From d65233240a86ce5e841a4ae05af5bce83073deca Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Mon, 25 Oct 2021 17:13:34 -0700 Subject: [PATCH] Unify u32-based identifiers into common code Create a new type Id paramaterized by whatever specific class of IDs is relevant to a domain; create stores and macros to support this; and repace the existing Id types. --- rustfmt.toml | 3 +- schala-lang/language/src/ast/mod.rs | 43 +++--------- schala-lang/language/src/identifier.rs | 74 ++++++++++++++++++++ schala-lang/language/src/lib.rs | 4 +- schala-lang/language/src/parsing/mod.rs | 5 +- schala-lang/language/src/symbol_table/mod.rs | 42 ++--------- 6 files changed, 96 insertions(+), 75 deletions(-) create mode 100644 schala-lang/language/src/identifier.rs diff --git a/rustfmt.toml b/rustfmt.toml index 36327c7..6774194 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -4,4 +4,5 @@ use_small_heuristics = "max" imports_indent = "block" imports_granularity = "crate" group_imports = "stdexternalcrate" - +match_arm_blocks = false +where_single_line = true diff --git a/schala-lang/language/src/ast/mod.rs b/schala-lang/language/src/ast/mod.rs index a1db480..c48c9a6 100644 --- a/schala-lang/language/src/ast/mod.rs +++ b/schala-lang/language/src/ast/mod.rs @@ -2,7 +2,6 @@ #![allow(clippy::enum_variant_names)] use std::rc::Rc; -use std::fmt; use std::convert::{AsRef, From}; mod visitor; @@ -13,41 +12,19 @@ pub use visitor::*; use crate::derivative::Derivative; use crate::tokenizing::Location; +use crate::identifier::{Id, define_id_kind}; -/// An abstract identifier for an AST node. Note that -/// the u32 index limits the size of an AST to 2^32 nodes. -#[derive(Debug, PartialEq, Eq, Hash, Clone, Default)] -pub struct ItemId { - pub idx: u32, +define_id_kind!(ASTItem); + +/* +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)] +pub struct ASTItem; +impl IdKind for ASTItem { + fn tag() -> &'static str { "ASTItem" } } +*/ -impl ItemId { - fn new(n: u32) -> ItemId { - ItemId { idx: n } - } -} - -impl fmt::Display for ItemId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ItemId:{}", self.idx) - } -} - -pub struct ItemIdStore { - last_idx: u32 -} - -impl ItemIdStore { - pub fn new() -> ItemIdStore { - ItemIdStore { last_idx: 0 } - } - - pub fn fresh(&mut self) -> ItemId { - let idx = self.last_idx; - self.last_idx += 1; - ItemId::new(idx) - } -} +pub type ItemId = Id; #[derive(Derivative, Debug)] #[derivative(PartialEq)] diff --git a/schala-lang/language/src/identifier.rs b/schala-lang/language/src/identifier.rs new file mode 100644 index 0000000..22299fa --- /dev/null +++ b/schala-lang/language/src/identifier.rs @@ -0,0 +1,74 @@ +use std::{ + fmt::{self, Debug}, + hash::Hash, + marker::PhantomData, +}; + +pub trait IdKind: Debug + Copy + Clone + Hash + PartialEq + Eq + Default { + fn tag() -> &'static str; +} + +/// A generalized abstract identifier type of up to 2^32-1 entries. +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] +pub struct Id +where T: IdKind +{ + idx: u32, + t: PhantomData, +} + +impl Id +where T: IdKind +{ + fn new(n: u32) -> Self { + Self { idx: n, t: PhantomData } + } + + #[allow(dead_code)] + pub fn as_u32(&self) -> u32 { + self.idx + } +} + +impl fmt::Display for Id +where T: IdKind +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}:{}", self.idx, T::tag()) + } +} + +pub struct IdStore +where T: IdKind +{ + last_idx: u32, + t: PhantomData, +} + +impl IdStore +where T: IdKind +{ + pub fn new() -> Self { + Self { last_idx: 0, t: PhantomData } + } + + pub fn fresh(&mut self) -> Id { + let idx = self.last_idx; + self.last_idx += 1; + Id::new(idx) + } +} + +macro_rules! define_id_kind { + ($name:ident) => { + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] + pub struct $name; + impl crate::identifier::IdKind for $name { + fn tag() -> &'static str { + stringify!($name) + } + } + }; +} + +pub(crate) use define_id_kind; diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index 1d0e21b..dcd4fa1 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -23,10 +23,10 @@ mod tokenizing; mod symbol_table; mod builtin; mod error; -//mod eval; -//mod reduced_ast; mod reduced_ir; mod tree_walk_eval; +#[macro_use] +mod identifier; mod schala; diff --git a/schala-lang/language/src/parsing/mod.rs b/schala-lang/language/src/parsing/mod.rs index 6b1ae1d..5be7ce0 100644 --- a/schala-lang/language/src/parsing/mod.rs +++ b/schala-lang/language/src/parsing/mod.rs @@ -170,6 +170,7 @@ use crate::tokenizing::TokenKind::*; use crate::tokenizing::Location; use crate::ast::*; +use crate::identifier::IdStore; /// Represents a parsing error #[derive(Debug)] @@ -201,7 +202,7 @@ pub struct Parser { parse_record: Vec, parse_level: u32, restrictions: ParserRestrictions, - id_store: ItemIdStore, + id_store: IdStore, } @@ -252,7 +253,7 @@ impl Parser { parse_record: vec![], parse_level: 0, restrictions: ParserRestrictions { no_struct_literal: false }, - id_store: ItemIdStore::new(), + id_store: IdStore::new(), } } diff --git a/schala-lang/language/src/symbol_table/mod.rs b/schala-lang/language/src/symbol_table/mod.rs index db0178a..0ff2089 100644 --- a/schala-lang/language/src/symbol_table/mod.rs +++ b/schala-lang/language/src/symbol_table/mod.rs @@ -14,42 +14,10 @@ mod resolver; mod symbol_trie; use symbol_trie::SymbolTrie; mod test; +use crate::identifier::{Id, IdStore, define_id_kind}; - -//TODO parameterize different types of ID -/// ID used for definitions -#[derive(Debug, PartialEq, Eq, Hash, Clone, Default)] -pub struct DefId { - idx: u32, -} - -impl DefId { - pub fn as_u32(&self) -> u32 { - self.idx - } -} - -impl fmt::Display for DefId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "DefId:{}", self.idx) - } -} - -pub struct DefIdStore { - last_idx: u32 -} - -impl DefIdStore { - pub fn new() -> Self { - Self { last_idx: 0 } - } - - pub fn fresh(&mut self) -> DefId { - let idx = self.last_idx; - self.last_idx += 1; - DefId { idx } - } -} +define_id_kind!(DefItem); +pub type DefId = Id; /// Fully-qualified symbol name #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] @@ -170,7 +138,7 @@ impl NameTable { //cf. p. 150 or so of Language Implementation Patterns pub struct SymbolTable { - def_id_store: DefIdStore, + def_id_store: IdStore, /// Used for import resolution. symbol_trie: SymbolTrie, @@ -190,7 +158,7 @@ pub struct SymbolTable { impl SymbolTable { pub fn new() -> SymbolTable { SymbolTable { - def_id_store: DefIdStore::new(), + def_id_store: IdStore::new(), symbol_trie: SymbolTrie::new(), fq_names: NameTable::new(), types: NameTable::new(),