diff --git a/schala-lang/language/src/symbol_table/mod.rs b/schala-lang/language/src/symbol_table/mod.rs index 8bf2558..65ea33a 100644 --- a/schala-lang/language/src/symbol_table/mod.rs +++ b/schala-lang/language/src/symbol_table/mod.rs @@ -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) -> Result<(), DuplicateName> { + fn add_from_scope<'a>(&'a mut self, statements: &[Statement], scope_stack: &mut Vec) -> Result<(), Vec> { + 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) -> 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) -> Result<(), Vec> {