Rename FQSN -> Fqsn

This commit is contained in:
Greg Shuflin 2021-10-19 21:14:15 -07:00
parent c0a3a03045
commit 355ed3c749
4 changed files with 52 additions and 52 deletions

View File

@ -15,28 +15,28 @@ mod test;
/// Fully-qualified symbol name /// Fully-qualified symbol name
#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub struct FQSN { pub struct Fqsn {
//TODO FQSN's need to be cheaply cloneable //TODO Fqsn's need to be cheaply cloneable
scopes: Vec<Scope>, //TODO rename to ScopeSegment scopes: Vec<Scope>, //TODO rename to ScopeSegment
} }
impl FQSN { impl Fqsn {
fn from_scope_stack(scopes: &[Scope], new_name: Rc<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());
} }
v.push(Scope::Name(new_name)); v.push(Scope::Name(new_name));
FQSN { scopes: v } Fqsn { scopes: v }
} }
#[cfg(test)] #[cfg(test)]
fn from_strs(strs: &[&str]) -> FQSN { fn from_strs(strs: &[&str]) -> Fqsn {
let mut scopes = vec![]; let mut scopes = vec![];
for s in strs { for s in strs {
scopes.push(Scope::Name(Rc::new(s.to_string()))); scopes.push(Scope::Name(Rc::new(s.to_string())));
} }
FQSN { Fqsn {
scopes scopes
} }
} }
@ -55,11 +55,11 @@ enum Scope {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum SymbolError { pub enum SymbolError {
DuplicateName { DuplicateName {
prev_name: FQSN, prev_name: Fqsn,
location: Location location: Location
}, },
DuplicateRecord { DuplicateRecord {
type_name: FQSN, type_name: Fqsn,
location: Location, location: Location,
member: String, member: String,
} }
@ -84,7 +84,7 @@ struct TypeKind;
/// Keeps track of what names were used in a given namespace. /// Keeps track of what names were used in a given namespace.
struct NameTable<K> { struct NameTable<K> {
table: HashMap<FQSN, NameSpec<K>> table: HashMap<Fqsn, NameSpec<K>>
} }
impl<K> NameTable<K> { impl<K> NameTable<K> {
@ -92,7 +92,7 @@ impl<K> NameTable<K> {
Self { table: HashMap::new() } Self { table: HashMap::new() }
} }
fn register(&mut self, name: FQSN, spec: NameSpec<K>) -> Result<(), SymbolError> { fn register(&mut self, name: Fqsn, spec: NameSpec<K>) -> Result<(), SymbolError> {
match self.table.entry(name.clone()) { match self.table.entry(name.clone()) {
Entry::Occupied(o) => { Entry::Occupied(o) => {
Err(SymbolError::DuplicateName { prev_name: name, location: o.get().location }) Err(SymbolError::DuplicateName { prev_name: name, location: o.get().location })
@ -114,14 +114,14 @@ pub struct SymbolTable {
fq_names: NameTable<NameKind>, //Note that presence of two tables implies that a type and other binding with the same name can co-exist fq_names: NameTable<NameKind>, //Note that presence of two tables implies that a type and other binding with the same name can co-exist
types: NameTable<TypeKind>, types: NameTable<TypeKind>,
/// A map of the `ItemId`s of instances of use of names to their fully-canonicalized FQSN form. /// A map of the `ItemId`s of instances of use of names to their fully-canonicalized Fqsn form.
/// Updated by the item id resolver. /// Updated by the item id resolver.
id_to_fqsn: HashMap<ItemId, FQSN>, id_to_fqsn: HashMap<ItemId, Fqsn>,
/// A map of the FQSN of an AST definition to a Symbol data structure, which contains /// A map of the Fqsn of an AST definition to a Symbol data structure, which contains
/// some basic information about what that symbol is and (ideally) references to other tables /// some basic information about what that symbol is and (ideally) references to other tables
/// (e.g. typechecking tables) with more information about that symbol. /// (e.g. typechecking tables) with more information about that symbol.
fqsn_to_symbol: HashMap<FQSN, Symbol>, fqsn_to_symbol: HashMap<Fqsn, Symbol>,
} }
impl SymbolTable { impl SymbolTable {
@ -203,7 +203,7 @@ impl SymbolTable {
/// Register a new mapping of a fully-qualified symbol name (e.g. `Option::Some`) /// Register a new mapping of a fully-qualified symbol name (e.g. `Option::Some`)
/// to a Symbol, a descriptor of what that name refers to. /// to a Symbol, a descriptor of what that name refers to.
fn add_symbol(&mut self, fqsn: FQSN, symbol: Symbol) { fn add_symbol(&mut self, fqsn: Fqsn, symbol: Symbol) {
self.symbol_trie.insert(&fqsn); self.symbol_trie.insert(&fqsn);
self.fqsn_to_symbol.insert(fqsn, symbol); self.fqsn_to_symbol.insert(fqsn, symbol);
} }
@ -263,7 +263,7 @@ impl SymbolTable {
fn add_single_statement(&mut self, kind: &StatementKind, location: Location, scope_stack: &Vec<Scope>) -> Result<(), SymbolError> { fn add_single_statement(&mut self, kind: &StatementKind, location: Location, scope_stack: &Vec<Scope>) -> Result<(), SymbolError> {
match kind { match kind {
StatementKind::Declaration(Declaration::FuncSig(signature)) => { StatementKind::Declaration(Declaration::FuncSig(signature)) => {
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(), signature.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 } )?;
@ -274,7 +274,7 @@ impl SymbolTable {
} }
StatementKind::Declaration(Declaration::FuncDecl(signature, ..)) => { StatementKind::Declaration(Declaration::FuncDecl(signature, ..)) => {
let fn_name = &signature.name; let fn_name = &signature.name;
let fq_function = FQSN::from_scope_stack(scope_stack.as_ref(), fn_name.clone()); 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 } )?;
@ -284,11 +284,11 @@ impl SymbolTable {
}); });
}, },
StatementKind::Declaration(Declaration::TypeDecl { name, .. }) => { StatementKind::Declaration(Declaration::TypeDecl { name, .. }) => {
let fq_type = FQSN::from_scope_stack(scope_stack.as_ref(), name.name.clone()); 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 } )?;
}, },
StatementKind::Declaration(Declaration::Binding { name, .. }) => { StatementKind::Declaration(Declaration::Binding { name, .. }) => {
let fq_binding = FQSN::from_scope_stack(scope_stack.as_ref(), name.clone()); 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(),
@ -296,7 +296,7 @@ impl SymbolTable {
}); });
} }
StatementKind::Module(ModuleSpecifier { name, .. }) => { StatementKind::Module(ModuleSpecifier { name, .. }) => {
let fq_module = FQSN::from_scope_stack(scope_stack.as_ref(), name.clone()); let fq_module = Fqsn::from_scope_stack(scope_stack.as_ref(), name.clone());
self.fq_names.register(fq_module, NameSpec { location, kind: NameKind::Module })?; self.fq_names.register(fq_module, NameSpec { location, kind: NameKind::Module })?;
}, },
_ => (), _ => (),
@ -308,7 +308,7 @@ impl SymbolTable {
let mut member_errors = vec![]; let mut member_errors = vec![];
let mut errors = vec![]; let mut errors = vec![];
let mut register = |fqsn: FQSN, spec: SymbolSpec| { let mut register = |fqsn: Fqsn, spec: SymbolSpec| {
let name_spec = NameSpec { location, kind: TypeKind }; let name_spec = NameSpec { location, kind: TypeKind };
if let Err(err) = self.types.register(fqsn.clone(), name_spec) { if let Err(err) = self.types.register(fqsn.clone(), name_spec) {
errors.push(err); errors.push(err);
@ -329,7 +329,7 @@ impl SymbolTable {
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.clone()); 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,
@ -338,7 +338,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.clone()); 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(),
@ -347,7 +347,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.clone()); let fq_name = Fqsn::from_scope_stack(scope_stack.as_ref(), name.clone());
let mut seen_members = HashMap::new(); let mut seen_members = HashMap::new();
for (member_name, _) in members.iter() { for (member_name, _) in members.iter() {

View File

@ -1,31 +1,31 @@
use std::rc::Rc; use std::rc::Rc;
use crate::symbol_table::{SymbolTable, FQSN, Scope}; use crate::symbol_table::{SymbolTable, Fqsn, Scope};
use crate::ast::*; use crate::ast::*;
use crate::util::ScopeStack; use crate::util::ScopeStack;
type FQSNPrefix = Vec<Scope>; type FqsnPrefix = Vec<Scope>;
pub struct Resolver<'a> { pub struct Resolver<'a> {
symbol_table: &'a mut super::SymbolTable, symbol_table: &'a mut super::SymbolTable,
name_scope_stack: ScopeStack<'a, Rc<String>, FQSNPrefix>, name_scope_stack: ScopeStack<'a, Rc<String>, FqsnPrefix>,
} }
impl<'a> Resolver<'a> { impl<'a> Resolver<'a> {
pub fn new(symbol_table: &'a mut SymbolTable) -> Self { pub fn new(symbol_table: &'a mut SymbolTable) -> Self {
let name_scope_stack: ScopeStack<'a, Rc<String>, FQSNPrefix> = ScopeStack::new(None); let name_scope_stack: ScopeStack<'a, Rc<String>, FqsnPrefix> = ScopeStack::new(None);
Self { symbol_table, name_scope_stack } Self { symbol_table, name_scope_stack }
} }
pub fn resolve(&mut self, ast: &AST) { pub fn resolve(&mut self, ast: &AST) {
walk_ast(self, ast); walk_ast(self, ast);
} }
fn lookup_name_in_scope(&self, sym_name: &QualifiedName) -> FQSN { fn lookup_name_in_scope(&self, sym_name: &QualifiedName) -> Fqsn {
let QualifiedName { components, .. } = sym_name; let QualifiedName { components, .. } = sym_name;
let first_component = &components[0]; let first_component = &components[0];
match self.name_scope_stack.lookup(first_component) { match self.name_scope_stack.lookup(first_component) {
None => { None => {
FQSN { Fqsn {
scopes: components.iter() scopes: components.iter()
.map(|name| Scope::Name(name.clone())) .map(|name| Scope::Name(name.clone()))
.collect() .collect()
@ -33,10 +33,10 @@ impl<'a> Resolver<'a> {
}, },
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.clone())).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 {
scopes: full_name scopes: full_name
} }
} }
@ -59,7 +59,7 @@ impl<'a> ASTVisitor for Resolver<'a> {
let ImportSpecifier { ref path_components, ref imported_names, .. } = &import_spec; let ImportSpecifier { ref path_components, ref imported_names, .. } = &import_spec;
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.clone())).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);
@ -77,7 +77,7 @@ impl<'a> ASTVisitor for Resolver<'a> {
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.clone())) .map(|c| Scope::Name(c.clone()))
.collect(); .collect();
for name in names.iter() { for name in names.iter() {

View File

@ -1,12 +1,12 @@
use radix_trie::{Trie, TrieCommon, TrieKey}; use radix_trie::{Trie, TrieCommon, TrieKey};
use super::{Scope, FQSN}; use super::{Scope, Fqsn};
use std::hash::{Hasher, Hash}; use std::hash::{Hasher, Hash};
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
#[derive(Debug)] #[derive(Debug)]
pub struct SymbolTrie(Trie<FQSN, ()>); pub struct SymbolTrie(Trie<Fqsn, ()>);
impl TrieKey for FQSN { impl TrieKey for Fqsn {
fn encode_bytes(&self) -> Vec<u8> { fn encode_bytes(&self) -> Vec<u8> {
let mut hasher = DefaultHasher::new(); let mut hasher = DefaultHasher::new();
let mut output = vec![]; let mut output = vec![];
@ -24,16 +24,16 @@ impl SymbolTrie {
SymbolTrie(Trie::new()) SymbolTrie(Trie::new())
} }
pub fn insert(&mut self, fqsn: &FQSN) { pub fn insert(&mut self, fqsn: &Fqsn) {
self.0.insert(fqsn.clone(), ()); self.0.insert(fqsn.clone(), ());
} }
pub fn get_children(&self, fqsn: &FQSN) -> Vec<FQSN> { pub fn get_children(&self, fqsn: &Fqsn) -> Vec<Fqsn> {
let subtrie = match self.0.subtrie(fqsn) { let subtrie = match self.0.subtrie(fqsn) {
Some(s) => s, Some(s) => s,
None => return vec![] None => return vec![]
}; };
let output: Vec<FQSN> = subtrie.keys().filter(|cur_key| **cur_key != *fqsn).map(|fqsn| fqsn.clone()).collect(); let output: Vec<Fqsn> = subtrie.keys().filter(|cur_key| **cur_key != *fqsn).map(|fqsn| fqsn.clone()).collect();
output output
} }
} }
@ -41,10 +41,10 @@ impl SymbolTrie {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use crate::symbol_table::FQSN; use crate::symbol_table::Fqsn;
fn make_fqsn(strs: &[&str]) -> FQSN { fn make_fqsn(strs: &[&str]) -> Fqsn {
FQSN::from_strs(strs) Fqsn::from_strs(strs)
} }
#[test] #[test]

View File

@ -10,8 +10,8 @@ fn add_symbols(src: &str) -> (SymbolTable, Result<(), Vec<SymbolError>>) {
(symbol_table, result) (symbol_table, result)
} }
fn make_fqsn(strs: &[&str]) -> FQSN { fn make_fqsn(strs: &[&str]) -> Fqsn {
FQSN::from_strs(strs) Fqsn::from_strs(strs)
} }
@ -20,8 +20,8 @@ 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 { fn make_fqsn(strs: &[&str]) -> Fqsn {
FQSN::from_strs(strs) Fqsn::from_strs(strs)
} }
symbols.fq_names.table.get(&make_fqsn(&["b"])).unwrap(); symbols.fq_names.table.get(&make_fqsn(&["b"])).unwrap();
@ -45,7 +45,7 @@ fn no_function_definition_duplicates() {
let errs = output.unwrap_err(); let errs = output.unwrap_err();
assert_matches!(&errs[..], [ assert_matches!(&errs[..], [
SymbolError::DuplicateName { prev_name, ..} SymbolError::DuplicateName { prev_name, ..}
] if prev_name == &FQSN::from_strs(&["a"]) ] if prev_name == &Fqsn::from_strs(&["a"])
); );
} }
@ -64,7 +64,7 @@ fn no_variable_definition_duplicates() {
assert_matches!(&errs[..], [ assert_matches!(&errs[..], [
SymbolError::DuplicateName { prev_name: pn1, ..}, SymbolError::DuplicateName { prev_name: pn1, ..},
SymbolError::DuplicateName { prev_name: pn2, ..} SymbolError::DuplicateName { prev_name: pn2, ..}
] if pn1 == &FQSN::from_strs(&["a"]) && pn2 == &FQSN::from_strs(&["x"]) ] if pn1 == &Fqsn::from_strs(&["a"]) && pn2 == &Fqsn::from_strs(&["x"])
); );
} }
@ -87,7 +87,7 @@ fn no_variable_definition_duplicates_in_function() {
let errs = output.unwrap_err(); let errs = output.unwrap_err();
assert_matches!(&errs[..], [ assert_matches!(&errs[..], [
SymbolError::DuplicateName { prev_name: pn1, ..}, SymbolError::DuplicateName { prev_name: pn1, ..},
] if pn1 == &FQSN::from_strs(&["q", "x"]) ] if pn1 == &Fqsn::from_strs(&["q", "x"])
); );
} }
@ -202,7 +202,7 @@ fn duplicate_modules() {
assert_matches!(&errs[..], [ assert_matches!(&errs[..], [
SymbolError::DuplicateName { prev_name: pn1, ..}, SymbolError::DuplicateName { prev_name: pn1, ..},
] if pn1 == &FQSN::from_strs(&["a"]) ] if pn1 == &Fqsn::from_strs(&["a"])
); );
} }
@ -227,7 +227,7 @@ fn duplicate_struct_members() {
assert_matches!(&errs[..], [ assert_matches!(&errs[..], [
SymbolError::DuplicateRecord { SymbolError::DuplicateRecord {
type_name, member, ..}, type_name, member, ..},
] if type_name == &FQSN::from_strs(&["Tarak", "Tarak"]) && member == "mets" ] if type_name == &Fqsn::from_strs(&["Tarak", "Tarak"]) && member == "mets"
); );
} }