Use Vec of symbol errors

This commit is contained in:
Greg Shuflin 2021-10-19 18:00:34 -07:00
parent 7a0134014b
commit d3378c3210

View File

@ -218,11 +218,49 @@ impl SymbolTable {
Ok(())
}
//TODO this should probably return a vector of duplicate name errors
fn add_from_scope<'a>(&'a mut self, statements: &[Statement], scope_stack: &mut Vec<Scope>) -> Result<(), DuplicateName> {
fn add_from_scope<'a>(&'a mut self, statements: &[Statement], scope_stack: &mut Vec<Scope>) -> Result<(), Vec<DuplicateName>> {
let mut errors = vec![];
for statement in statements {
let Statement { id: _, kind, location } = statement; //TODO I'm not sure if I need to do anything with this ID
let location = *location;
if let Err(err) = self.add_single_statement(kind, location, &scope_stack) {
errors.push(err);
}
let recursive_errs = match kind {
StatementKind::Declaration(Declaration::FuncDecl(signature, body)) => {
let new_scope = Scope::Name(signature.name.clone());
scope_stack.push(new_scope);
let output = self.add_from_scope(body.as_ref(), scope_stack);
scope_stack.pop();
output
}
StatementKind::Module(ModuleSpecifier { name, contents }) => {
let new_scope = Scope::Name(name.clone());
scope_stack.push(new_scope);
let output = self.add_from_scope(contents.as_ref(), scope_stack);
scope_stack.pop();
output
}
StatementKind::Declaration(Declaration::TypeDecl { name, body, mutable }) => {
self.add_type_members(name, body, mutable, location, scope_stack)
}
_ => Ok(())
};
if let Err(errs) = recursive_errs {
errors.extend(errs.into_iter());
}
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
fn add_single_statement(&mut self, kind: &StatementKind, location: Location, scope_stack: &Vec<Scope>) -> Result<(), DuplicateName> {
match kind {
StatementKind::Declaration(Declaration::FuncSig(signature)) => {
let fq_function = FQSN::from_scope_stack(scope_stack.as_ref(), signature.name.clone());
@ -234,9 +272,8 @@ impl SymbolTable {
spec: SymbolSpec::Func(vec![]), //TODO does this inner vec need to exist at all?
});
}
StatementKind::Declaration(Declaration::FuncDecl(signature, body)) => {
StatementKind::Declaration(Declaration::FuncDecl(signature, ..)) => {
let fn_name = &signature.name;
let new_scope = Scope::Name(fn_name.clone());
let fq_function = FQSN::from_scope_stack(scope_stack.as_ref(), fn_name.clone());
self.fq_names.register(fq_function.clone(), NameSpec { location, kind: NameKind::Function })?;
self.types.register(fq_function.clone(), NameSpec { location, kind: TypeKind } )?;
@ -245,18 +282,10 @@ impl SymbolTable {
local_name: signature.name.clone(),
spec: SymbolSpec::Func(vec![]), //TODO does this inner vec need to exist at all?
});
scope_stack.push(new_scope);
let output = self.add_from_scope(body.as_ref(), scope_stack);
scope_stack.pop();
output?
},
StatementKind::Declaration(Declaration::TypeDecl { name, body, mutable }) => {
StatementKind::Declaration(Declaration::TypeDecl { name, .. }) => {
let fq_type = FQSN::from_scope_stack(scope_stack.as_ref(), name.name.clone());
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.clone());
@ -266,18 +295,12 @@ impl SymbolTable {
spec: SymbolSpec::Binding,
});
}
StatementKind::Module(ModuleSpecifier { name, contents }) => {
StatementKind::Module(ModuleSpecifier { name, .. }) => {
let fq_module = FQSN::from_scope_stack(scope_stack.as_ref(), name.clone());
let new_scope = Scope::Name(name.clone());
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();
output?
},
_ => (),
}
}
Ok(())
}