Switch scope to Rc<String>
This commit is contained in:
parent
3c4d31c963
commit
7a0134014b
@ -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(),
|
||||
|
@ -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());
|
||||
|
@ -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]
|
||||
|
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user