Reduce number of tables in symbol table
This commit is contained in:
parent
db6c9bb162
commit
9d89440a6d
@ -68,25 +68,39 @@ struct DuplicateName {
|
||||
location: Location
|
||||
}
|
||||
|
||||
//TODO should map to a Spec* type that has Location and Kind of namespace entry
|
||||
//tht way I don't need as many tables
|
||||
/// Keeps track of what names were used in a given namespace.
|
||||
struct NameTable {
|
||||
table: HashMap<FQSN, Location>
|
||||
#[derive(Debug)]
|
||||
struct NameSpec<K> {
|
||||
location: Location,
|
||||
kind: K
|
||||
}
|
||||
|
||||
impl NameTable {
|
||||
#[derive(Debug)]
|
||||
enum NameKind {
|
||||
Module,
|
||||
Function,
|
||||
Binding,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TypeKind;
|
||||
|
||||
/// Keeps track of what names were used in a given namespace.
|
||||
struct NameTable<K> {
|
||||
table: HashMap<FQSN, NameSpec<K>>
|
||||
}
|
||||
|
||||
impl<K> NameTable<K> {
|
||||
fn new() -> Self {
|
||||
Self { table: HashMap::new() }
|
||||
}
|
||||
|
||||
fn register(&mut self, name: FQSN, location: Location) -> Result<(), DuplicateName> {
|
||||
fn register(&mut self, name: FQSN, spec: NameSpec<K>) -> Result<(), DuplicateName> {
|
||||
match self.table.entry(name.clone()) {
|
||||
Entry::Occupied(o) => {
|
||||
Err(DuplicateName { prev_name: name, location: *o.get() })
|
||||
Err(DuplicateName { prev_name: name, location: o.get().location })
|
||||
},
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(location);
|
||||
v.insert(spec);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -162,9 +176,8 @@ pub struct SymbolTable {
|
||||
symbol_path_to_symbol: HashMap<FullyQualifiedSymbolName, Symbol>,
|
||||
id_to_fqsn: HashMap<ItemId, FullyQualifiedSymbolName>,
|
||||
symbol_trie: SymbolTrie,
|
||||
functions: NameTable, //TODO maybe bindings and functions should be the same table?
|
||||
types: NameTable,
|
||||
bindings: NameTable, //TODO NameTable should be a trie to facilitate quick lookups
|
||||
fq_names: NameTable<NameKind>,
|
||||
types: NameTable<TypeKind>,
|
||||
}
|
||||
|
||||
impl SymbolTable {
|
||||
@ -174,9 +187,8 @@ impl SymbolTable {
|
||||
symbol_path_to_symbol: HashMap::new(),
|
||||
id_to_fqsn: HashMap::new(),
|
||||
symbol_trie: SymbolTrie::new(),
|
||||
functions: NameTable::new(),
|
||||
fq_names: NameTable::new(),
|
||||
types: NameTable::new(),
|
||||
bindings: NameTable::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +275,6 @@ impl SymbolTable {
|
||||
/// checks for dupicate definitions (and returns errors if discovered), and sets
|
||||
/// up name tables that will be used by further parts of the compiler
|
||||
pub fn process_ast(&mut self, ast: &ast::AST) -> Result<(), String> {
|
||||
|
||||
let mut scope_stack = vec![Scope::Top];
|
||||
self.add_from_scope(ast.statements.as_ref(), &mut scope_stack)
|
||||
.map_err(|err| format!("{:?}", err))?;
|
||||
@ -279,15 +290,15 @@ impl SymbolTable {
|
||||
StatementKind::Declaration(Declaration::FuncSig(signature)) => {
|
||||
let fn_name: String = signature.name.as_str().to_owned();
|
||||
let fq_function = FQSN::from_scope_stack(scope_stack.as_ref(), fn_name);
|
||||
self.functions.register(fq_function.clone(), location)?;
|
||||
self.types.register(fq_function, location)?;
|
||||
self.fq_names.register(fq_function.clone(), NameSpec { location, kind: NameKind::Function })?;
|
||||
self.types.register(fq_function, NameSpec { location, kind: TypeKind } )?;
|
||||
}
|
||||
StatementKind::Declaration(Declaration::FuncDecl(signature, body)) => {
|
||||
let fn_name: String = signature.name.as_str().to_owned();
|
||||
let new_scope = Scope::Name(fn_name.clone());
|
||||
let fq_function = FQSN::from_scope_stack(scope_stack.as_ref(), fn_name);
|
||||
self.functions.register(fq_function.clone(), location)?;
|
||||
self.types.register(fq_function, location)?;
|
||||
self.fq_names.register(fq_function.clone(), NameSpec { location, kind: NameKind::Function })?;
|
||||
self.types.register(fq_function, NameSpec { location, kind: TypeKind } )?;
|
||||
scope_stack.push(new_scope);
|
||||
let output = self.add_from_scope(body.as_ref(), scope_stack);
|
||||
scope_stack.pop();
|
||||
@ -295,20 +306,20 @@ impl SymbolTable {
|
||||
},
|
||||
StatementKind::Declaration(Declaration::TypeDecl { name, body, mutable }) => {
|
||||
let fq_type = FQSN::from_scope_stack(scope_stack.as_ref(), name.name.as_ref().to_owned());
|
||||
self.types.register(fq_type, location)?;
|
||||
self.types.register(fq_type, NameSpec { location, kind: TypeKind } )?;
|
||||
if let Err(errors) = self.add_type_members(name, body, mutable, location, scope_stack) {
|
||||
return Err(errors[0].clone());
|
||||
}
|
||||
},
|
||||
StatementKind::Declaration(Declaration::Binding { name, .. }) => {
|
||||
let fq_binding = FQSN::from_scope_stack(scope_stack.as_ref(), name.as_str().to_owned());
|
||||
self.bindings.register(fq_binding, location)?;
|
||||
self.fq_names.register(fq_binding, NameSpec { location, kind: NameKind::Binding })?;
|
||||
}
|
||||
StatementKind::Module(ModuleSpecifier { name, contents }) => {
|
||||
let mod_name = name.as_str().to_owned();
|
||||
let fq_module = FQSN::from_scope_stack(scope_stack.as_ref(), mod_name.clone());
|
||||
let new_scope = Scope::Name(mod_name);
|
||||
self.bindings.register(fq_module, location)?;
|
||||
self.fq_names.register(fq_module, NameSpec { location, kind: NameKind::Module })?;
|
||||
scope_stack.push(new_scope);
|
||||
let output = self.add_from_scope(contents.as_ref(), scope_stack);
|
||||
scope_stack.pop();
|
||||
@ -324,7 +335,8 @@ impl SymbolTable {
|
||||
let mut errors = vec![];
|
||||
|
||||
let mut register = |fqsn: FQSN| {
|
||||
if let Err(err) = self.types.register(fqsn, location) {
|
||||
let spec = NameSpec { location, kind: TypeKind };
|
||||
if let Err(err) = self.types.register(fqsn, spec) {
|
||||
errors.push(err);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user