Switch scope to Rc<String>

This commit is contained in:
Greg Shuflin 2021-10-19 17:22:35 -07:00
parent 3c4d31c963
commit 7a0134014b
4 changed files with 40 additions and 38 deletions

View File

@ -22,7 +22,7 @@ pub struct FQSN {
} }
impl FQSN { impl FQSN {
fn from_scope_stack(scopes: &[Scope], new_name: String) -> Self { fn from_scope_stack(scopes: &[Scope], new_name: Rc<String>) -> Self {
let mut v = Vec::new(); let mut v = Vec::new();
for s in scopes { for s in scopes {
v.push(s.clone()); v.push(s.clone());
@ -30,13 +30,26 @@ impl FQSN {
v.push(Scope::Name(new_name)); v.push(Scope::Name(new_name));
FQSN { scopes: v } 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 //TODO eventually this should use ItemId's to avoid String-cloning
/// One segment within a scope. /// One segment within a scope.
#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
enum Scope { enum Scope {
Name(String) Name(Rc<String>)
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -208,13 +221,11 @@ impl SymbolTable {
//TODO this should probably return a vector of duplicate name errors //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<(), DuplicateName> {
for statement in statements { for statement in statements {
//TODO I'm not sure if I need to do anything with this ID let Statement { id: _, kind, location } = statement; //TODO I'm not sure if I need to do anything with this ID
let Statement { id: _, kind, location } = statement;
let location = *location; let location = *location;
match kind { match kind {
StatementKind::Declaration(Declaration::FuncSig(signature)) => { 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(), signature.name.clone());
let fq_function = FQSN::from_scope_stack(scope_stack.as_ref(), fn_name);
self.fq_names.register(fq_function.clone(), NameSpec { location, kind: NameKind::Function })?; self.fq_names.register(fq_function.clone(), NameSpec { location, kind: NameKind::Function })?;
self.types.register(fq_function.clone(), NameSpec { location, kind: TypeKind } )?; self.types.register(fq_function.clone(), NameSpec { location, kind: TypeKind } )?;
@ -224,9 +235,9 @@ impl SymbolTable {
}); });
} }
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 = &signature.name;
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.clone());
self.fq_names.register(fq_function.clone(), NameSpec { location, kind: NameKind::Function })?; self.fq_names.register(fq_function.clone(), NameSpec { location, kind: NameKind::Function })?;
self.types.register(fq_function.clone(), NameSpec { location, kind: TypeKind } )?; self.types.register(fq_function.clone(), NameSpec { location, kind: TypeKind } )?;
@ -241,14 +252,14 @@ impl SymbolTable {
output? output?
}, },
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.clone());
self.types.register(fq_type, NameSpec { location, kind: TypeKind } )?; 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.clone());
self.fq_names.register(fq_binding.clone(), NameSpec { location, kind: NameKind::Binding })?; self.fq_names.register(fq_binding.clone(), NameSpec { location, kind: NameKind::Binding })?;
self.add_symbol(fq_binding, Symbol { self.add_symbol(fq_binding, Symbol {
local_name: name.clone(), local_name: name.clone(),
@ -256,9 +267,8 @@ impl SymbolTable {
}); });
} }
StatementKind::Module(ModuleSpecifier { name, contents }) => { StatementKind::Module(ModuleSpecifier { name, contents }) => {
let mod_name = name.as_str().to_owned(); let fq_module = FQSN::from_scope_stack(scope_stack.as_ref(), name.clone());
let fq_module = FQSN::from_scope_stack(scope_stack.as_ref(), mod_name.clone()); let new_scope = Scope::Name(name.clone());
let new_scope = Scope::Name(mod_name);
self.fq_names.register(fq_module, NameSpec { location, kind: NameKind::Module })?; 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);
@ -289,13 +299,13 @@ impl SymbolTable {
}; };
let TypeBody(variants) = type_body; 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); scope_stack.push(new_scope);
for (index, variant) in variants.iter().enumerate() { for (index, variant) in variants.iter().enumerate() {
match variant { match variant {
Variant::UnitStruct(name) => { 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 { let spec = SymbolSpec::DataConstructor {
index, index,
arity: 0, arity: 0,
@ -304,7 +314,7 @@ impl SymbolTable {
register(fq_name, spec); register(fq_name, spec);
}, },
Variant::TupleStruct(name, items) => { 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 { let spec = SymbolSpec::DataConstructor {
index, index,
arity: items.len(), arity: items.len(),
@ -313,7 +323,7 @@ impl SymbolTable {
register(fq_name, spec); register(fq_name, spec);
}, },
Variant::Record { name, members } => { 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 { let spec = SymbolSpec::RecordConstructor {
index, index,
type_name: name.clone(), type_name: name.clone(),

View File

@ -28,13 +28,13 @@ impl<'a> Resolver<'a> {
None => { None => {
FQSN { FQSN {
scopes: components.iter() scopes: components.iter()
.map(|name| Scope::Name(name.as_ref().to_owned())) .map(|name| Scope::Name(name.clone()))
.collect() .collect()
} }
}, },
Some(fqsn_prefix) => { Some(fqsn_prefix) => {
let mut full_name = fqsn_prefix.clone(); 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); full_name.extend_from_slice(&rest_of_name);
FQSN { FQSN {
@ -61,25 +61,25 @@ impl<'a> ASTVisitor for Resolver<'a> {
match imported_names { match imported_names {
ImportedNames::All => { ImportedNames::All => {
let prefix = FQSN { 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); let members = self.symbol_table.symbol_trie.get_children(&prefix);
for member in members.into_iter() { for member in members.into_iter() {
let Scope::Name(n) = member.scopes.last().unwrap(); 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); self.name_scope_stack.insert(local_name, member.scopes);
} }
}, },
ImportedNames::LastOfPath => { ImportedNames::LastOfPath => {
let name = path_components.last().unwrap(); //TODO handle better let name = path_components.last().unwrap(); //TODO handle better
let fqsn_prefix = path_components.iter() let fqsn_prefix = path_components.iter()
.map(|c| Scope::Name(c.as_ref().to_owned())) .map(|c| Scope::Name(c.clone()))
.collect(); .collect();
self.name_scope_stack.insert(name.clone(), fqsn_prefix); self.name_scope_stack.insert(name.clone(), fqsn_prefix);
} }
ImportedNames::List(ref names) => { ImportedNames::List(ref names) => {
let fqsn_prefix: FQSNPrefix = path_components.iter() let fqsn_prefix: FQSNPrefix = path_components.iter()
.map(|c| Scope::Name(c.as_ref().to_owned())) .map(|c| Scope::Name(c.clone()))
.collect(); .collect();
for name in names.iter() { for name in names.iter() {
self.name_scope_stack.insert(name.clone(), fqsn_prefix.clone()); self.name_scope_stack.insert(name.clone(), fqsn_prefix.clone());

View File

@ -41,16 +41,10 @@ impl SymbolTrie {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use crate::symbol_table::{Scope, FQSN}; use crate::symbol_table::FQSN;
fn make_fqsn(strs: &[&str]) -> FQSN { fn make_fqsn(strs: &[&str]) -> FQSN {
let mut scopes = vec![]; FQSN::from_strs(strs)
for s in strs {
scopes.push(Scope::Name(s.to_string()));
}
FQSN {
scopes
}
} }
#[test] #[test]

View File

@ -10,13 +10,7 @@ fn add_symbols(src: &str) -> (SymbolTable, Result<(), String>) {
} }
fn make_fqsn(strs: &[&str]) -> FQSN { fn make_fqsn(strs: &[&str]) -> FQSN {
let mut scopes = vec![]; FQSN::from_strs(strs)
for s in strs {
scopes.push(Scope::Name(s.to_string()));
}
FQSN {
scopes
}
} }
@ -25,6 +19,10 @@ fn basic_symbol_table() {
let src = "let a = 10; fn b() { 20 }"; let src = "let a = 10; fn b() { 20 }";
let (symbols, _) = add_symbols(src); let (symbols, _) = add_symbols(src);
fn make_fqsn(strs: &[&str]) -> FQSN {
FQSN::from_strs(strs)
}
symbols.fq_names.table.get(&make_fqsn(&["b"])).unwrap(); symbols.fq_names.table.get(&make_fqsn(&["b"])).unwrap();
let src = "type Option<T> = Some(T) | None"; let src = "type Option<T> = Some(T) | None";