diff --git a/schala-lang/language/src/symbol_table/fqsn.rs b/schala-lang/language/src/symbol_table/fqsn.rs new file mode 100644 index 0000000..5c3c784 --- /dev/null +++ b/schala-lang/language/src/symbol_table/fqsn.rs @@ -0,0 +1,59 @@ +use std::{fmt, rc::Rc}; + +/// Fully-qualified symbol name +#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] +pub struct Fqsn { + //TODO Fqsn's need to be cheaply cloneable + pub scopes: Vec, +} + +impl Fqsn { + pub fn from_scope_stack(scopes: &[ScopeSegment], new_name: Rc) -> Self { + let mut v = Vec::new(); + for s in scopes { + v.push(s.clone()); + } + v.push(ScopeSegment::Name(new_name)); + Fqsn { scopes: v } + } + + #[allow(dead_code)] + pub fn from_strs(strs: &[&str]) -> Fqsn { + let mut scopes = vec![]; + for s in strs { + scopes.push(ScopeSegment::Name(Rc::new(s.to_string()))); + } + Fqsn { scopes } + } + + pub fn last_elem(&self) -> Rc { + let ScopeSegment::Name(name) = self.scopes.last().unwrap(); + name.clone() + } +} + +impl fmt::Display for Fqsn { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let delim = "::"; + let Fqsn { scopes } = self; + write!(f, "FQSN<{}", scopes[0])?; + for item in scopes[1..].iter() { + write!(f, "{}{}", delim, item)?; + } + write!(f, ">") + } +} + +//TODO eventually this should use ItemId's to avoid String-cloning +/// One segment within a scope. +#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] +pub enum ScopeSegment { + Name(Rc), +} + +impl fmt::Display for ScopeSegment { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let ScopeSegment::Name(name) = self; + write!(f, "{}", name) + } +} diff --git a/schala-lang/language/src/symbol_table/mod.rs b/schala-lang/language/src/symbol_table/mod.rs index f177c53..7d7aaf5 100644 --- a/schala-lang/language/src/symbol_table/mod.rs +++ b/schala-lang/language/src/symbol_table/mod.rs @@ -18,6 +18,8 @@ use crate::{ type_inference::{self, PendingType, TypeBuilder, TypeContext, TypeId, VariantBuilder}, }; +mod fqsn; +pub use fqsn::{Fqsn, ScopeSegment}; mod resolver; mod symbol_trie; use symbol_trie::SymbolTrie; @@ -27,64 +29,6 @@ use crate::identifier::{define_id_kind, Id, IdStore}; define_id_kind!(DefItem); pub type DefId = Id; -/// Fully-qualified symbol name -#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] -pub struct Fqsn { - //TODO Fqsn's need to be cheaply cloneable - scopes: Vec, -} - -impl Fqsn { - fn from_scope_stack(scopes: &[ScopeSegment], new_name: Rc) -> Self { - let mut v = Vec::new(); - for s in scopes { - v.push(s.clone()); - } - v.push(ScopeSegment::Name(new_name)); - Fqsn { scopes: v } - } - - #[allow(dead_code)] - fn from_strs(strs: &[&str]) -> Fqsn { - let mut scopes = vec![]; - for s in strs { - scopes.push(ScopeSegment::Name(Rc::new(s.to_string()))); - } - Fqsn { scopes } - } - - fn last_elem(&self) -> Rc { - let ScopeSegment::Name(name) = self.scopes.last().unwrap(); - name.clone() - } -} - -impl fmt::Display for Fqsn { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let delim = "::"; - let Fqsn { scopes } = self; - write!(f, "FQSN<{}", scopes[0])?; - for item in scopes[1..].iter() { - write!(f, "{}{}", delim, item)?; - } - write!(f, ">") - } -} - -//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 ScopeSegment { - Name(Rc), -} - -impl fmt::Display for ScopeSegment { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let ScopeSegment::Name(name) = self; - write!(f, "{}", name) - } -} - #[allow(dead_code)] #[derive(Debug, Clone)] pub enum SymbolError {