Use Vec of symbol errors
This commit is contained in:
parent
7a0134014b
commit
d3378c3210
@ -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,19 +295,13 @@ 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(())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_type_members(&mut self, type_name: &TypeSingletonName, type_body: &TypeBody, _mutable: &bool, location: Location, scope_stack: &mut Vec<Scope>) -> Result<(), Vec<DuplicateName>> {
|
||||
|
Loading…
Reference in New Issue
Block a user