diff --git a/schala-lang/language/src/symbol_table/mod.rs b/schala-lang/language/src/symbol_table/mod.rs index c8d52e0..8bf2558 100644 --- a/schala-lang/language/src/symbol_table/mod.rs +++ b/schala-lang/language/src/symbol_table/mod.rs @@ -22,7 +22,7 @@ pub struct FQSN { } impl FQSN { - fn from_scope_stack(scopes: &[Scope], new_name: String) -> Self { + fn from_scope_stack(scopes: &[Scope], new_name: Rc) -> Self { let mut v = Vec::new(); for s in scopes { v.push(s.clone()); @@ -30,13 +30,26 @@ impl FQSN { v.push(Scope::Name(new_name)); FQSN { scopes: v } } + + #[cfg(test)] + fn from_strs(strs: &[&str]) -> FQSN { + let mut scopes = vec![]; + for s in strs { + scopes.push(Scope::Name(Rc::new(s.to_string()))); + } + FQSN { + scopes + } + } } + + //TODO eventually this should use ItemId's to avoid String-cloning /// One segment within a scope. #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] enum Scope { - Name(String) + Name(Rc) } #[allow(dead_code)] @@ -208,13 +221,11 @@ impl SymbolTable { //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> { for statement in statements { - //TODO I'm not sure if I need to do anything with this ID - let Statement { id: _, kind, location } = statement; + let Statement { id: _, kind, location } = statement; //TODO I'm not sure if I need to do anything with this ID let location = *location; match kind { 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); + let fq_function = FQSN::from_scope_stack(scope_stack.as_ref(), signature.name.clone()); self.fq_names.register(fq_function.clone(), NameSpec { location, kind: NameKind::Function })?; self.types.register(fq_function.clone(), NameSpec { location, kind: TypeKind } )?; @@ -224,9 +235,9 @@ impl SymbolTable { }); } StatementKind::Declaration(Declaration::FuncDecl(signature, body)) => { - let fn_name: String = signature.name.as_str().to_owned(); + 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); + 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 } )?; @@ -241,14 +252,14 @@ impl SymbolTable { output? }, 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.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.as_str().to_owned()); + let fq_binding = FQSN::from_scope_stack(scope_stack.as_ref(), name.clone()); self.fq_names.register(fq_binding.clone(), NameSpec { location, kind: NameKind::Binding })?; self.add_symbol(fq_binding, Symbol { local_name: name.clone(), @@ -256,9 +267,8 @@ impl SymbolTable { }); } 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); + 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); @@ -289,13 +299,13 @@ impl SymbolTable { }; let TypeBody(variants) = type_body; - let new_scope = Scope::Name(type_name.name.as_ref().to_owned()); + let new_scope = Scope::Name(type_name.name.clone()); scope_stack.push(new_scope); for (index, variant) in variants.iter().enumerate() { match variant { Variant::UnitStruct(name) => { - let fq_name = FQSN::from_scope_stack(scope_stack.as_ref(), name.as_ref().to_owned()); + let fq_name = FQSN::from_scope_stack(scope_stack.as_ref(), name.clone()); let spec = SymbolSpec::DataConstructor { index, arity: 0, @@ -304,7 +314,7 @@ impl SymbolTable { register(fq_name, spec); }, Variant::TupleStruct(name, items) => { - let fq_name = FQSN::from_scope_stack(scope_stack.as_ref(), name.as_ref().to_owned()); + let fq_name = FQSN::from_scope_stack(scope_stack.as_ref(), name.clone()); let spec = SymbolSpec::DataConstructor { index, arity: items.len(), @@ -313,7 +323,7 @@ impl SymbolTable { register(fq_name, spec); }, Variant::Record { name, members } => { - let fq_name = FQSN::from_scope_stack(scope_stack.as_ref(), name.as_ref().to_owned()); + let fq_name = FQSN::from_scope_stack(scope_stack.as_ref(), name.clone()); let spec = SymbolSpec::RecordConstructor { index, type_name: name.clone(), diff --git a/schala-lang/language/src/symbol_table/resolver.rs b/schala-lang/language/src/symbol_table/resolver.rs index bbdcc80..1b784da 100644 --- a/schala-lang/language/src/symbol_table/resolver.rs +++ b/schala-lang/language/src/symbol_table/resolver.rs @@ -28,13 +28,13 @@ impl<'a> Resolver<'a> { None => { FQSN { scopes: components.iter() - .map(|name| Scope::Name(name.as_ref().to_owned())) + .map(|name| Scope::Name(name.clone())) .collect() } }, Some(fqsn_prefix) => { let mut full_name = fqsn_prefix.clone(); - let rest_of_name: FQSNPrefix = components[1..].iter().map(|name| Scope::Name(name.as_ref().to_owned())).collect(); + let rest_of_name: FQSNPrefix = components[1..].iter().map(|name| Scope::Name(name.clone())).collect(); full_name.extend_from_slice(&rest_of_name); FQSN { @@ -61,25 +61,25 @@ impl<'a> ASTVisitor for Resolver<'a> { match imported_names { ImportedNames::All => { let prefix = FQSN { - scopes: path_components.iter().map(|c| Scope::Name(c.as_ref().to_owned())).collect() + scopes: path_components.iter().map(|c| Scope::Name(c.clone())).collect() }; let members = self.symbol_table.symbol_trie.get_children(&prefix); for member in members.into_iter() { let Scope::Name(n) = member.scopes.last().unwrap(); - let local_name = Rc::new(n.clone()); + let local_name = n.clone(); self.name_scope_stack.insert(local_name, member.scopes); } }, ImportedNames::LastOfPath => { let name = path_components.last().unwrap(); //TODO handle better let fqsn_prefix = path_components.iter() - .map(|c| Scope::Name(c.as_ref().to_owned())) + .map(|c| Scope::Name(c.clone())) .collect(); self.name_scope_stack.insert(name.clone(), fqsn_prefix); } ImportedNames::List(ref names) => { let fqsn_prefix: FQSNPrefix = path_components.iter() - .map(|c| Scope::Name(c.as_ref().to_owned())) + .map(|c| Scope::Name(c.clone())) .collect(); for name in names.iter() { self.name_scope_stack.insert(name.clone(), fqsn_prefix.clone()); diff --git a/schala-lang/language/src/symbol_table/symbol_trie.rs b/schala-lang/language/src/symbol_table/symbol_trie.rs index 68af1a0..9bcae64 100644 --- a/schala-lang/language/src/symbol_table/symbol_trie.rs +++ b/schala-lang/language/src/symbol_table/symbol_trie.rs @@ -41,16 +41,10 @@ impl SymbolTrie { #[cfg(test)] mod test { use super::*; - use crate::symbol_table::{Scope, FQSN}; + use crate::symbol_table::FQSN; fn make_fqsn(strs: &[&str]) -> FQSN { - let mut scopes = vec![]; - for s in strs { - scopes.push(Scope::Name(s.to_string())); - } - FQSN { - scopes - } + FQSN::from_strs(strs) } #[test] diff --git a/schala-lang/language/src/symbol_table/test.rs b/schala-lang/language/src/symbol_table/test.rs index 62e73a0..963812a 100644 --- a/schala-lang/language/src/symbol_table/test.rs +++ b/schala-lang/language/src/symbol_table/test.rs @@ -10,13 +10,7 @@ fn add_symbols(src: &str) -> (SymbolTable, Result<(), String>) { } fn make_fqsn(strs: &[&str]) -> FQSN { - let mut scopes = vec![]; - for s in strs { - scopes.push(Scope::Name(s.to_string())); - } - FQSN { - scopes - } + FQSN::from_strs(strs) } @@ -25,6 +19,10 @@ fn basic_symbol_table() { let src = "let a = 10; fn b() { 20 }"; let (symbols, _) = add_symbols(src); + fn make_fqsn(strs: &[&str]) -> FQSN { + FQSN::from_strs(strs) + } + symbols.fq_names.table.get(&make_fqsn(&["b"])).unwrap(); let src = "type Option = Some(T) | None";