mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(semantic): add basic symbol table
This commit is contained in:
parent
be6fa2e7a0
commit
1c24875067
5 changed files with 154 additions and 1 deletions
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
mod builder;
|
||||
mod node;
|
||||
mod scope;
|
||||
mod symbol;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
|
|
|
|||
40
crates/oxc_semantic/src/symbol/id.rs
Normal file
40
crates/oxc_semantic/src/symbol/id.rs
Normal 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
|
||||
}
|
||||
}
|
||||
47
crates/oxc_semantic/src/symbol/mod.rs
Normal file
47
crates/oxc_semantic/src/symbol/mod.rs
Normal 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
|
||||
}
|
||||
}
|
||||
55
crates/oxc_semantic/src/symbol/table.rs
Normal file
55
crates/oxc_semantic/src/symbol/table.rs
Normal 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
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue