diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 914e103..e201033 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -14,6 +14,8 @@ use internment::Intern; use lexer::{Radix, Token, TokenItemIterator, TokenIterator}; use thiserror::Error; +use crate::symbols::{Span, Symbol, SymbolKind}; + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum IntSize { Bits(u16), @@ -210,7 +212,7 @@ impl Index { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum AstNode { Root { files: Vec, diff --git a/crates/parser/src/symbols.rs b/crates/parser/src/symbols.rs index 427e874..887eec0 100644 --- a/crates/parser/src/symbols.rs +++ b/crates/parser/src/symbols.rs @@ -19,14 +19,14 @@ //! Exception: `Key::ScopeByIndex` -> `InternIndex` use core::fmt::Debug; -use std::collections::BTreeMap; +use std::{collections::BTreeMap, ops::Index as IndexOp}; use internment::Intern; -use crate::Index; +use crate::{Ast, Index}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Span(u32); +pub struct Span(pub u32); #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Spanned(pub T, Span); @@ -54,20 +54,22 @@ pub enum Key { ScopeByIndex { ast: Index, }, + Parent(Index), Symbol { scope: Index, - name: Intern, - kind: SymbolKind, + sym: Symbol, }, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct Symbol { + pub name: Intern, + pub kind: SymbolKind, +} + impl Key { pub fn parent(scope: Index) -> Key { - Key::Symbol { - scope, - name: Intern::from(""), - kind: SymbolKind::ParentScope, - } + Key::Parent(scope) } } @@ -77,6 +79,7 @@ pub enum Payload { Name(Intern), } +#[derive(Clone, Default)] pub struct Symbols { inner: BTreeMap, } @@ -109,11 +112,21 @@ impl Symbols { inner: BTreeMap::new(), } } - pub fn insert_scope(&mut self, name: Intern, ast: Index) { + pub fn insert_scope(&mut self, ast: Index, name: Option>, parent: Option) { + if let Some(name) = name { + self.inner + .insert(Key::ScopeByIndex { ast }, Payload::Name(name)); + self.inner + .insert(Key::ScopeByName { name }, Payload::Ast(ast)); + } + if let Some(parent) = parent { + self.inner.insert(Key::parent(ast), Payload::Ast(parent)); + } + } + + pub fn insert_symbol(&mut self, sym: Symbol, scope: Index, ast: Index) { self.inner - .insert(Key::ScopeByIndex { ast }, Payload::Name(name)); - self.inner - .insert(Key::ScopeByName { name }, Payload::Ast(ast)); + .insert(Key::Symbol { scope, sym }, Payload::Ast(ast)); } pub fn find_symbol(&self, scope: Index, name: Intern, loc: Span) -> Option<(Key, Index)> { @@ -121,12 +134,16 @@ impl Symbols { let range = self.inner.range( Key::Symbol { scope, - name, - kind: __First, + sym: Symbol { + name, + kind: __First, + }, }..=Key::Symbol { scope, - name, - kind: Local(loc), + sym: Symbol { + name, + kind: Local(loc), + }, }, ); @@ -151,12 +168,16 @@ impl Symbols { let range = self.inner.range( Key::Symbol { scope, - name, - kind: __First, + sym: Symbol { + name, + kind: __First, + }, }..=Key::Symbol { scope, - name, - kind: __TypeScope, + sym: Symbol { + name, + kind: __TypeScope, + }, }, ); @@ -170,9 +191,94 @@ impl Symbols { } } } - - pub fn insert_symbol(&mut self, scope: Index, name: Intern, kind: SymbolKind, ast: Index) { - self.inner - .insert(Key::Symbol { scope, name, kind }, Payload::Ast(ast)); - } +} + +pub fn pre_symbol_pass(ast: &mut Ast) { + struct Ctx<'a> { + symbols: Symbols, + scopes: Vec, + ast: &'a mut Ast, + } + + let mut ctx = Ctx { + ast, + symbols: Symbols::new(), + scopes: Vec::new(), + }; + + fn process_node(ctx: &mut Ctx<'_>, index: Index) { + match ctx.ast.index(index).clone() { + crate::AstNode::Root { files } => { + for file in files { + process_node(ctx, file); + } + } + crate::AstNode::File { decls } => todo!(), + crate::AstNode::ParameterList(parameter_list) => todo!(), + crate::AstNode::Parameter(parameter) => todo!(), + crate::AstNode::FunctionDecl(function_decl) => todo!(), + crate::AstNode::Block { statements, expr } => todo!(), + crate::AstNode::Constant { ty, value } => todo!(), + crate::AstNode::NoopExpr => todo!(), + crate::AstNode::Stmt { expr } => todo!(), + crate::AstNode::ControlFlow { kind, expr } => todo!(), + crate::AstNode::VarDecl { + mutable, + name, + var_type, + } => todo!(), + crate::AstNode::Assignment { dest, expr } => todo!(), + crate::AstNode::GlobalDecl { + name, + var_type, + expr, + } => todo!(), + crate::AstNode::StructDecl { name, fields } => todo!(), + crate::AstNode::FieldDecl { name, field_type } => todo!(), + crate::AstNode::FieldAccess { expr, field } => todo!(), + crate::AstNode::UnresolvedDeclRef { name } => todo!(), + crate::AstNode::DeclRef { decl } => todo!(), + crate::AstNode::TypeDeclRef { ty } => todo!(), + crate::AstNode::ExplicitCast { expr, ty } => todo!(), + crate::AstNode::Deref { expr } => todo!(), + crate::AstNode::AddressOf { expr } => todo!(), + crate::AstNode::PlaceToValue { expr } => todo!(), + crate::AstNode::ValueToPlace { expr } => todo!(), + crate::AstNode::CallExpr { callee, arguments } => todo!(), + crate::AstNode::Argument { expr } => todo!(), + crate::AstNode::Not(index) => todo!(), + crate::AstNode::Negate(index) => todo!(), + crate::AstNode::Multiply { left, right } => todo!(), + crate::AstNode::Divide { left, right } => todo!(), + crate::AstNode::Modulus { left, right } => todo!(), + crate::AstNode::Add { left, right } => todo!(), + crate::AstNode::Subtract { left, right } => todo!(), + crate::AstNode::BitOr { left, right } => todo!(), + crate::AstNode::BitAnd { left, right } => todo!(), + crate::AstNode::BitXor { left, right } => todo!(), + crate::AstNode::LogicalOr { left, right } => todo!(), + crate::AstNode::LogicalAnd { left, right } => todo!(), + crate::AstNode::Eq { left, right } => todo!(), + crate::AstNode::NotEq { left, right } => todo!(), + crate::AstNode::Less { left, right } => todo!(), + crate::AstNode::LessEq { left, right } => todo!(), + crate::AstNode::Greater { left, right } => todo!(), + crate::AstNode::GreaterEq { left, right } => todo!(), + crate::AstNode::ShiftLeft { left, right } => todo!(), + crate::AstNode::ShiftRight { left, right } => todo!(), + crate::AstNode::Subscript { expr, index } => todo!(), + crate::AstNode::If { + condition, + then, + r#else, + } => todo!(), + crate::AstNode::Else { expr } => todo!(), + crate::AstNode::Comment { text } => todo!(), + crate::AstNode::Attributes { attrs } => todo!(), + crate::AstNode::Doc { text } => todo!(), + crate::AstNode::Error { err } => todo!(), + } + } + + let mut node = Index(ast.nodes.len().checked_sub(1).map(|n| n as u32)); }