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