Files
@ 1a42eb33aa76
Branch filter:
Location: CSY/reowolf/src/protocol/parser/symbol_table2.rs - annotation
1a42eb33aa76
5.7 KiB
application/rls-services+xml
WIP on compiler rearchitecting
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 1a42eb33aa76 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b 7f25ee16c39b 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 7f25ee16c39b | /// symbol_table.rs
///
/// The datastructure used to lookup symbols within particular scopes. Scopes
/// may be module-level or definition level, although imports and definitions
/// within definitions are currently not allowed.
///
/// TODO: Once the compiler has matured, find out ways to optimize to prevent
/// the repeated HashMap lookup.
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use crate::protocol::input_source2::*;
use crate::protocol::ast::*;
use crate::collections::*;
const RESERVED_SYMBOLS: usize = 32;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SymbolScope {
Module(RootId),
Definition(DefinitionId),
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum SymbolClass {
Module,
Struct,
Enum,
Union,
Function,
Component
}
struct ScopedSymbols {
scope: SymbolScope,
parent_scope: Option<SymbolScope>,
child_scopes: Vec<SymbolScope>,
symbols: Vec<Symbol>,
}
pub enum SymbolDefinition {
Module(RootId),
Struct(StructDefinitionId),
Enum(EnumDefinitionId),
Union(UnionDefinitionId),
Function(FunctionDefinitionId),
Component(ComponentDefinitionId),
}
impl SymbolDefinition {
pub fn symbol_class(&self) -> SymbolClass {
use SymbolDefinition as SD;
use SymbolClass as SC;
match self {
SD::Module(_) => SC::Module,
SD::Struct(_) => SC::Struct,
SD::Enum(_) => SC::Enum,
SD::Union(_) => SC::Union,
SD::Function(_) => SC::Function,
SD::Component(_) => SC::Component,
}
}
}
pub enum SymbolData {
}
pub struct Symbol {
// Definition location (may be different from the scope/module in which it
// is used if the symbol is imported)
pub defined_in_module: RootId,
pub defined_in_scope: SymbolScope,
pub definition_span: InputSpan, // full span of definition, not just the name
pub identifier_span: InputSpan, // span of just the identifier
// Introduction location (if imported instead of defined)
pub introduced_at: Option<ImportId>,
// Symbol properties
pub name: StringRef<'static>,
pub definition: SymbolDefinition,
}
pub struct SymbolTable {
module_lookup: HashMap<StringRef<'static>, RootId>,
scope_lookup: HashMap<SymbolScope, ScopedSymbols>,
}
impl SymbolTable {
/// Inserts a new module by its name. Upon module naming conflict the
/// previously associated `RootId` will be returned.
pub(crate) fn insert_module(&mut self, module_name: StringRef<'static>, root_id: RootId) -> Result<(), RootId> {
match self.module_lookup.entry(module_name) {
Entry::Occupied(v) => {
Err(*v.get())
},
Entry::Vacant(v) => {
v.insert(root_id);
Ok(())
}
}
}
/// Retrieves module `RootId` by name
pub(crate) fn get_module_by_name(&mut self, name: &[u8]) -> Option<RootId> {
let string_ref = StringRef::new(name);
self.module_lookup.get(&string_ref).map(|v| *v)
}
/// Inserts a new symbol scope. The parent must have been added to the
/// symbol table before.
pub(crate) fn insert_scope(&mut self, parent_scope: Option<SymbolScope>, new_scope: SymbolScope) {
debug_assert!(
parent_scope.is_none() || self.scope_lookup.contains_key(parent_scope.as_ref().unwrap()),
"inserting scope {:?} but parent {:?} does not exist", new_scope, parent_scope
);
debug_assert!(!self.scope_lookup.contains_key(&new_scope), "inserting scope {:?}, but it already exists", new_scope);
if let Some(parent_scope) = parent_scope {
let parent = self.scope_lookup.get_mut(&parent_scope).unwrap();
parent.child_scopes.push(new_scope);
}
let scope = ScopedSymbols {
scope: new_scope,
parent_scope,
child_scopes: Vec::with_capacity(RESERVED_SYMBOLS),
symbols: Vec::with_capacity(RESERVED_SYMBOLS)
};
self.scope_lookup.insert(new_scope, scope);
}
/// Inserts a symbol into a particular scope. The symbol's name may not
/// exist in the scope or any of its parents. If it does collide then the
/// symbol will be returned, together with the symbol that has the same
/// name.
pub(crate) fn insert_symbol(&mut self, in_scope: SymbolScope, symbol: Symbol) -> Result<(), (Symbol, &Symbol)> {
debug_assert!(self.scope_lookup.contains_key(&in_scope), "inserting symbol {}, but scope {:?} does not exist", symbol.name.as_str(), in_scope);
let mut seek_scope = in_scope;
loop {
let scoped_symbols = self.scope_lookup.get(&seek_scope).unwrap();
for existing_symbol in scoped_symbols.symbols.iter() {
if symbol.name == existing_symbol.name {
return Err((symbol, existing_symbol))
}
}
match scoped_symbols.parent_scope {
Some(parent_scope) => { seek_scope = parent_scope; },
None => { break; }
}
}
// If here, then there is no collision
let scoped_symbols = self.scope_lookup.get_mut(&in_scope).unwrap();
scoped_symbols.symbols.push(symbol);
Ok(())
}
/// Retrieves a particular scope. As this will be called by the compiler to
/// retrieve scopes that MUST exist, this function will panic if the
/// indicated scope does not exist.
pub(crate) fn get_scope_by_id(&mut self, scope: &SymbolScope) -> &mut ScopedSymbols {
debug_assert!(self.scope_lookup.contains_key(scope), "retrieving scope {:?}, but it doesn't exist", scope);
self.scope_lookup.get_mut(scope).unwrap()
}
}
|