From 87582956412b796ff932e7b9411a4d26cfbb483a Mon Sep 17 00:00:00 2001 From: Toni Date: Thu, 19 Mar 2026 13:18:24 +0100 Subject: [PATCH] Analyzer -> SymbolTable --- src/codegen_x86_64.rs | 30 ++++++++++++++++------------ src/main.rs | 10 +++++----- src/{analyzer.rs => symbol_table.rs} | 8 ++++---- src/typechecker.rs | 26 ++++++++++++------------ 4 files changed, 39 insertions(+), 35 deletions(-) rename src/{analyzer.rs => symbol_table.rs} (97%) diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index f0555a0..3442f02 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -1,8 +1,8 @@ use std::{collections::HashMap, fmt::Write}; use crate::{ - analyzer::Analyzer, parser::{Expr, Stmt}, + symbol_table::SymbolTable, tokenizer::{Token, TokenType, ZernError, error}, }; @@ -74,17 +74,17 @@ pub struct CodegenX86_64<'a> { data_section: String, label_counter: usize, data_counter: usize, - pub analyzer: &'a Analyzer, + pub symbol_table: &'a SymbolTable, } impl<'a> CodegenX86_64<'a> { - pub fn new(analyzer: &'a Analyzer) -> CodegenX86_64<'a> { + pub fn new(symbol_table: &'a SymbolTable) -> CodegenX86_64<'a> { CodegenX86_64 { output: String::new(), data_section: String::new(), label_counter: 0, data_counter: 1, - analyzer, + symbol_table, } } @@ -223,7 +223,7 @@ _builtin_environ: var_type, initializer, } => { - // TODO: move to analyzer + // TODO: move to typechecker? if env.get_var(&name.lexeme).is_some() { return error!( name.loc, @@ -250,7 +250,7 @@ _builtin_environ: emit!(&mut self.output, " mov QWORD [rbp-{}], rax", offset); } Stmt::Const { name: _, value: _ } => { - // handled in the analyzer + // handled in SymbolTable } Stmt::Block(statements) => { env.push_scope(); @@ -398,7 +398,7 @@ _builtin_environ: emit!(&mut self.output, "extern {}", name.lexeme); } Stmt::Struct { name: _, fields: _ } => { - // handled in the analyzer + // handled in SymbolTable } } Ok(()) @@ -555,11 +555,11 @@ _builtin_environ: } } Expr::Variable(name) => { - if self.analyzer.constants.contains_key(&name.lexeme) { + if self.symbol_table.constants.contains_key(&name.lexeme) { emit!( &mut self.output, " mov rax, {}", - self.analyzer.constants[&name.lexeme] + self.symbol_table.constants[&name.lexeme] ); } else { let var = match env.get_var(&name.lexeme) { @@ -655,7 +655,11 @@ _builtin_environ: } if let Expr::Variable(callee_name) = &**callee { - if self.analyzer.functions.contains_key(&callee_name.lexeme) { + if self + .symbol_table + .functions + .contains_key(&callee_name.lexeme) + { // its a function (defined/builtin/extern) emit!(&mut self.output, " call {}", callee_name.lexeme); } else { @@ -702,7 +706,7 @@ _builtin_environ: } Expr::AddrOf { op, expr } => match *expr.clone() { Expr::Variable(name) => { - if self.analyzer.functions.contains_key(&name.lexeme) { + if self.symbol_table.functions.contains_key(&name.lexeme) { emit!(&mut self.output, " mov rax, {}", name.lexeme); } else { let var = match env.get_var(&name.lexeme) { @@ -726,7 +730,7 @@ _builtin_environ: } }, Expr::New(struct_name) => { - let struct_fields = &self.analyzer.structs[&struct_name.lexeme]; + let struct_fields = &self.symbol_table.structs[&struct_name.lexeme]; // TODO: panic on mem.alloc error let memory_size = struct_fields.len() * 8; @@ -771,7 +775,7 @@ _builtin_environ: } }; - let fields = match self.analyzer.structs.get(&struct_name) { + let fields = match self.symbol_table.structs.get(&struct_name) { Some(f) => f, None => { return error!(&field.loc, format!("unknown struct type: {}", struct_name)); diff --git a/src/main.rs b/src/main.rs index 10585ef..69c7743 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ -mod analyzer; mod codegen_x86_64; mod parser; +mod symbol_table; mod tokenizer; mod typechecker; @@ -44,17 +44,17 @@ fn compile_file(args: Args) -> Result<(), ZernError> { let parser = parser::Parser::new(tokenizer.tokenize()?); statements.extend(parser.parse()?); - let mut analyzer = analyzer::Analyzer::new(); + let mut symbol_table = symbol_table::SymbolTable::new(); for stmt in &statements { - analyzer.register_declaration(stmt)?; + symbol_table.register_declaration(stmt)?; } - let mut typechecker = typechecker::TypeChecker::new(&analyzer); + let mut typechecker = typechecker::TypeChecker::new(&symbol_table); for stmt in &statements { typechecker.typecheck_stmt(&mut typechecker::Env::new(), stmt)?; } - let mut codegen = codegen_x86_64::CodegenX86_64::new(&analyzer); + let mut codegen = codegen_x86_64::CodegenX86_64::new(&symbol_table); codegen.emit_prologue(args.use_gcc)?; for stmt in statements { codegen.compile_stmt(&mut codegen_x86_64::Env::new(), &stmt)?; diff --git a/src/analyzer.rs b/src/symbol_table.rs similarity index 97% rename from src/analyzer.rs rename to src/symbol_table.rs index d65277f..8b0b9c7 100644 --- a/src/analyzer.rs +++ b/src/symbol_table.rs @@ -34,15 +34,15 @@ impl FnType { } } -pub struct Analyzer { +pub struct SymbolTable { pub functions: HashMap, pub constants: HashMap, pub structs: HashMap>, } -impl Analyzer { - pub fn new() -> Analyzer { - Analyzer { +impl SymbolTable { + pub fn new() -> SymbolTable { + SymbolTable { functions: HashMap::from([ ("_builtin_heap_head".into(), FnType::new("ptr", vec![])), ("_builtin_heap_tail".into(), FnType::new("ptr", vec![])), diff --git a/src/typechecker.rs b/src/typechecker.rs index 01c40fd..b7cfe7e 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use crate::{ - analyzer::{Analyzer, Type}, parser::{Expr, Stmt}, + symbol_table::{SymbolTable, Type}, tokenizer::{TokenType, ZernError, error}, }; @@ -70,14 +70,14 @@ impl Env { } pub struct TypeChecker<'a> { - analyzer: &'a Analyzer, + symbol_table: &'a SymbolTable, current_function_return_type: String, } impl<'a> TypeChecker<'a> { - pub fn new(analyzer: &'a Analyzer) -> TypeChecker<'a> { + pub fn new(symbol_table: &'a SymbolTable) -> TypeChecker<'a> { TypeChecker { - analyzer, + symbol_table, current_function_return_type: String::new(), } } @@ -110,7 +110,7 @@ impl<'a> TypeChecker<'a> { env.define_var(name.lexeme.clone(), actual_type); } Stmt::Const { name: _, value: _ } => { - // handled in the analyzer + // handled in SymbolTable } Stmt::Block(stmts) => { env.push_scope(); @@ -207,7 +207,7 @@ impl<'a> TypeChecker<'a> { Stmt::Break => {} Stmt::Continue => {} Stmt::Extern(_) => { - // handled in the analyzer + // handled in the SymbolTable } Stmt::Struct { name: _, fields } => { for field in fields { @@ -304,7 +304,7 @@ impl<'a> TypeChecker<'a> { } } Expr::Variable(name) => { - if self.analyzer.constants.contains_key(&name.lexeme) { + if self.symbol_table.constants.contains_key(&name.lexeme) { Ok("i64".into()) } else { match env.get_var_type(&name.lexeme) { @@ -341,7 +341,7 @@ impl<'a> TypeChecker<'a> { Expr::MemberAccess { left, field } => { let left_type = self.typecheck_expr(env, left)?; - let fields = match self.analyzer.structs.get(&left_type) { + let fields = match self.symbol_table.structs.get(&left_type) { Some(f) => f, None => { return error!( @@ -373,7 +373,7 @@ impl<'a> TypeChecker<'a> { args, } => { if let Expr::Variable(callee_name) = &**callee { - if let Some(fn_type) = self.analyzer.functions.get(&callee_name.lexeme) { + if let Some(fn_type) = self.symbol_table.functions.get(&callee_name.lexeme) { // its a function (defined/builtin/extern) if let Some(params) = fn_type.params.clone() { if params.len() != args.len() { @@ -432,7 +432,7 @@ impl<'a> TypeChecker<'a> { } Expr::AddrOf { op, expr } => match expr.as_ref() { Expr::Variable(name) => { - if self.analyzer.functions.contains_key(&name.lexeme) { + if self.symbol_table.functions.contains_key(&name.lexeme) { Ok("fnptr".into()) } else { Ok("ptr".into()) @@ -443,7 +443,7 @@ impl<'a> TypeChecker<'a> { } }, Expr::New(struct_name) => { - if !self.analyzer.structs.contains_key(&struct_name.lexeme) { + if !self.symbol_table.structs.contains_key(&struct_name.lexeme) { return error!( &struct_name.loc, format!("unknown struct name: {}", &struct_name.lexeme) @@ -454,7 +454,7 @@ impl<'a> TypeChecker<'a> { Expr::MemberAccess { left, field } => { let left_type = self.typecheck_expr(env, left)?; - let fields = match self.analyzer.structs.get(&left_type) { + let fields = match self.symbol_table.structs.get(&left_type) { Some(f) => f, None => { return error!(&field.loc, format!("unknown struct type: {}", left_type)); @@ -485,7 +485,7 @@ impl<'a> TypeChecker<'a> { if BUILTIN_TYPES.contains(&name) { return true; } - if self.analyzer.structs.contains_key(name) { + if self.symbol_table.structs.contains_key(name) { return true; } false