Unify u32-based identifiers into common code
Create a new type Id<T> 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.
This commit is contained in:
parent
a3463f5519
commit
d65233240a
@ -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
|
||||
|
@ -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);
|
||||
|
||||
impl ItemId {
|
||||
fn new(n: u32) -> ItemId {
|
||||
ItemId { idx: n }
|
||||
}
|
||||
/*
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
|
||||
pub struct ASTItem;
|
||||
impl IdKind for ASTItem {
|
||||
fn tag() -> &'static str { "ASTItem" }
|
||||
}
|
||||
*/
|
||||
|
||||
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<ASTItem>;
|
||||
|
||||
#[derive(Derivative, Debug)]
|
||||
#[derivative(PartialEq)]
|
||||
|
74
schala-lang/language/src/identifier.rs
Normal file
74
schala-lang/language/src/identifier.rs
Normal file
@ -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<T>
|
||||
where T: IdKind
|
||||
{
|
||||
idx: u32,
|
||||
t: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> Id<T>
|
||||
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<T> fmt::Display for Id<T>
|
||||
where T: IdKind
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}:{}", self.idx, T::tag())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IdStore<T>
|
||||
where T: IdKind
|
||||
{
|
||||
last_idx: u32,
|
||||
t: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> IdStore<T>
|
||||
where T: IdKind
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Self { last_idx: 0, t: PhantomData }
|
||||
}
|
||||
|
||||
pub fn fresh(&mut self) -> Id<T> {
|
||||
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;
|
@ -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;
|
||||
|
||||
|
@ -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<ParseRecord>,
|
||||
parse_level: u32,
|
||||
restrictions: ParserRestrictions,
|
||||
id_store: ItemIdStore,
|
||||
id_store: IdStore<ASTItem>,
|
||||
}
|
||||
|
||||
|
||||
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<DefItem>;
|
||||
|
||||
/// Fully-qualified symbol name
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
||||
@ -170,7 +138,7 @@ impl<K> NameTable<K> {
|
||||
//cf. p. 150 or so of Language Implementation Patterns
|
||||
pub struct SymbolTable {
|
||||
|
||||
def_id_store: DefIdStore,
|
||||
def_id_store: IdStore<DefItem>,
|
||||
|
||||
/// 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(),
|
||||
|
Loading…
Reference in New Issue
Block a user