feat(semantic): add basic symbol table

This commit is contained in:
Boshen 2023-03-07 21:16:34 +08:00
parent be6fa2e7a0
commit 1c24875067
5 changed files with 154 additions and 1 deletions

View file

@ -10,6 +10,7 @@ use oxc_ast::{ast::*, visit::Visit, AstKind, SourceType, Trivias};
use crate::{
node::{AstNodeId, AstNodes, NodeFlags, SemanticNode},
scope::ScopeBuilder,
symbol::SymbolTable,
Semantic,
};
@ -23,6 +24,8 @@ pub struct SemanticBuilder<'a> {
// builders
nodes: AstNodes<'a>,
scope: ScopeBuilder,
#[allow(unused)]
symbols: SymbolTable,
}
impl<'a> SemanticBuilder<'a> {
@ -33,7 +36,14 @@ impl<'a> SemanticBuilder<'a> {
let semantic_node =
SemanticNode::new(AstKind::Root, scope.current_scope_id, NodeFlags::empty());
let current_node_id = nodes.new_node(semantic_node).into();
Self { source_type, current_node_id, nodes, scope, current_node_flags: NodeFlags::empty() }
Self {
source_type,
current_node_id,
current_node_flags: NodeFlags::empty(),
nodes,
scope,
symbols: SymbolTable::default(),
}
}
#[must_use]

View file

@ -1,6 +1,7 @@
mod builder;
mod node;
mod scope;
mod symbol;
use std::rc::Rc;

View file

@ -0,0 +1,40 @@
use std::{
hash::Hash,
num::NonZeroUsize,
ops::{Index, IndexMut},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SymbolId(NonZeroUsize);
impl Default for SymbolId {
fn default() -> Self {
Self::new(1)
}
}
impl<T> Index<SymbolId> for Vec<T> {
type Output = T;
fn index(&self, id: SymbolId) -> &Self::Output {
&self[id.index0()]
}
}
impl<T> IndexMut<SymbolId> for Vec<T> {
fn index_mut(&mut self, id: SymbolId) -> &mut T {
&mut self[id.index0()]
}
}
impl SymbolId {
#[must_use]
pub fn new(n: usize) -> Self {
unsafe { Self(NonZeroUsize::new_unchecked(n)) }
}
#[must_use]
pub(crate) fn index0(self) -> usize {
self.0.get() - 1
}
}

View file

@ -0,0 +1,47 @@
//! Symbol and Symbol Table for tracking of semantics of variables
pub mod id;
pub mod table;
use oxc_ast::{Atom, Span};
pub use self::{id::SymbolId, table::SymbolTable};
#[derive(Debug)]
pub struct Symbol {
id: SymbolId,
name: Atom,
span: Span,
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
#[test]
fn symbol_size() {
use std::mem::size_of;
assert_eq!(size_of::<Symbol>(), 40);
}
impl Symbol {
#[must_use]
pub fn new(id: SymbolId, name: Atom, span: Span) -> Self {
Self { id, name, span }
}
#[must_use]
#[allow(unused)]
pub fn id(&self) -> SymbolId {
self.id
}
#[must_use]
#[allow(unused)]
pub fn name(&self) -> &Atom {
&self.name
}
#[must_use]
#[allow(unused)]
pub fn span(&self) -> &Span {
&self.span
}
}

View file

@ -0,0 +1,55 @@
use std::ops::{Deref, Index, IndexMut};
use oxc_ast::{Atom, Span};
use super::{Symbol, SymbolId};
#[derive(Debug, Default)]
pub struct SymbolTable {
symbols: Vec<Symbol>,
}
impl Index<SymbolId> for SymbolTable {
type Output = Symbol;
fn index(&self, index: SymbolId) -> &Self::Output {
&self.symbols[index.index0()]
}
}
impl IndexMut<SymbolId> for SymbolTable {
fn index_mut(&mut self, index: SymbolId) -> &mut Self::Output {
&mut self.symbols[index.index0()]
}
}
impl Deref for SymbolTable {
type Target = Vec<Symbol>;
fn deref(&self) -> &Self::Target {
&self.symbols
}
}
impl SymbolTable {
#[must_use]
#[allow(unused)]
pub fn symbols(&self) -> &Vec<Symbol> {
&self.symbols
}
#[must_use]
#[allow(unused)]
pub fn get(&self, id: SymbolId) -> Option<&Symbol> {
self.symbols.get(id.index0())
}
#[must_use]
#[allow(unused)]
pub fn create(&mut self, name: Atom, span: Span) -> SymbolId {
let symbol_id = SymbolId::new(self.symbols.len() + 1);
let symbol = Symbol::new(symbol_id, name, span);
self.symbols.push(symbol);
symbol_id
}
}