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 {
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();
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<String>)
}
#[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<Scope>) -> 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(),

View File

@ -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());

View File

@ -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]

View File

@ -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<T> = Some(T) | None";