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