From 584e7224a72cc4159cf8305a098e3c0c4e5e42e2 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Fri, 27 Mar 2026 11:59:59 -0500 Subject: [PATCH] Compile pipeline WIP and various refactoring. --- dmc-lib/src/ast/call.rs | 2 +- dmc-lib/src/ast/compilation_unit.rs | 26 +++++++++- dmc-lib/src/ast/field.rs | 2 +- dmc-lib/src/ast/helpers.rs | 27 ---------- dmc-lib/src/ast/identifier.rs | 8 +-- dmc-lib/src/ast/let_statement.rs | 2 +- dmc-lib/src/ast/mod.rs | 2 - dmc-lib/src/ast/type_use.rs | 2 +- dmc-lib/src/compile_pipeline.rs | 51 +++++++++++++++++++ dmc-lib/src/{ast => }/diagnostic_factories.rs | 0 dmc-lib/src/lib.rs | 3 ++ dmc-lib/src/symbol_table/mod.rs | 1 + dmc-lib/src/symbol_table/util.rs | 30 +++++++++++ dmc-lib/src/{ast => }/util.rs | 0 14 files changed, 118 insertions(+), 38 deletions(-) create mode 100644 dmc-lib/src/compile_pipeline.rs rename dmc-lib/src/{ast => }/diagnostic_factories.rs (100%) create mode 100644 dmc-lib/src/symbol_table/util.rs rename dmc-lib/src/{ast => }/util.rs (100%) diff --git a/dmc-lib/src/ast/call.rs b/dmc-lib/src/ast/call.rs index 7aafa64..ba2d88d 100644 --- a/dmc-lib/src/ast/call.rs +++ b/dmc-lib/src/ast/call.rs @@ -1,8 +1,8 @@ -use crate::ast::diagnostic_factories::class_has_no_constructor; use crate::ast::expression::Expression; use crate::ast::fqn_util::fqn_parts_to_string; use crate::ast::ir_builder::IrBuilder; use crate::diagnostic::Diagnostic; +use crate::diagnostic_factories::class_has_no_constructor; use crate::ir::ir_call::IrCall; use crate::ir::ir_expression::IrExpression; use crate::source_range::SourceRange; diff --git a/dmc-lib/src/ast/compilation_unit.rs b/dmc-lib/src/ast/compilation_unit.rs index ea79887..ee9d658 100644 --- a/dmc-lib/src/ast/compilation_unit.rs +++ b/dmc-lib/src/ast/compilation_unit.rs @@ -2,11 +2,13 @@ use crate::ast::class::Class; use crate::ast::extern_function::ExternFunction; use crate::ast::fqn_context::FqnContext; use crate::ast::function::Function; -use crate::ast::helpers::{collect_diagnostics_into_mut, try_insert_symbols_into}; +use crate::ast::helpers::collect_diagnostics_into_mut; use crate::diagnostic::Diagnostic; use crate::ir::ir_class::IrClass; use crate::ir::ir_function::IrFunction; +use crate::symbol::Symbol; use crate::symbol_table::SymbolTable; +use crate::symbol_table::util::try_insert_symbols_into; use crate::types_table::TypesTable; use crate::{diagnostics_result, handle_diagnostics}; @@ -55,6 +57,28 @@ impl CompilationUnit { symbol_table.pop_scope(); } + pub fn gather_symbols(&self) -> Vec { + let fqn_context = FqnContext::new(); + [ + self.classes + .iter() + .flat_map(|class| class.make_symbols(&fqn_context)) + .collect::>(), + self.extern_functions + .iter() + .flat_map(|function| function.make_symbols(&fqn_context).1) + .collect(), + self.functions + .iter() + .flat_map(|function| function.make_symbols(&fqn_context, false).1) + .collect(), + ] + .into_iter() + .flatten() + .collect() + } + + #[deprecated] pub fn gather_symbols_into( &self, symbol_table: &mut SymbolTable, diff --git a/dmc-lib/src/ast/field.rs b/dmc-lib/src/ast/field.rs index a9a9581..456d893 100644 --- a/dmc-lib/src/ast/field.rs +++ b/dmc-lib/src/ast/field.rs @@ -1,7 +1,7 @@ -use crate::ast::diagnostic_factories::field_has_no_type_or_init; use crate::ast::expression::Expression; use crate::ast::type_use::TypeUse; use crate::diagnostic::Diagnostic; +use crate::diagnostic_factories::field_has_no_type_or_init; use crate::source_range::SourceRange; use crate::symbol::class_symbol::ClassSymbol; use crate::symbol::field_symbol::FieldSymbol; diff --git a/dmc-lib/src/ast/helpers.rs b/dmc-lib/src/ast/helpers.rs index 661062e..c4bfcef 100644 --- a/dmc-lib/src/ast/helpers.rs +++ b/dmc-lib/src/ast/helpers.rs @@ -1,11 +1,9 @@ -use crate::ast::diagnostic_factories::symbol_already_declared; use crate::ast::fqn_context::FqnContext; use crate::ast::parameter::Parameter; use crate::diagnostic::Diagnostic; use crate::diagnostics_result; use crate::symbol::Symbol; use crate::symbol::parameter_symbol::ParameterSymbol; -use crate::symbol_table::SymbolTable; use std::rc::Rc; /// Iterates through all `ts`, running the `f` function, and pushing returned `Diagnostic`s @@ -95,31 +93,6 @@ pub fn resolve_ctor_name(fqn_context: &FqnContext) -> Vec> { fqn_context.resolve("ctor") // ctor is a keyword at the language level, should not be callable via normal means } -pub fn try_insert_symbol_into( - symbol: Symbol, - symbol_table: &mut SymbolTable, -) -> Result<(), Diagnostic> { - let maybe_already_inserted = symbol_table.get_symbol(symbol.scope_id(), symbol.declared_name()); - if let Some(already_inserted) = maybe_already_inserted { - Err(symbol_already_declared(&already_inserted, &symbol)) - } else { - symbol_table.insert_symbol(symbol); - Ok(()) - } -} - -pub fn try_insert_symbols_into( - symbols: Vec, - symbol_table: &mut SymbolTable, -) -> Result<(), Vec> { - let diagnostics: Vec = symbols - .into_iter() - .map(|symbol| try_insert_symbol_into(symbol, symbol_table)) - .filter_map(Result::err) - .collect(); - diagnostics_result!(diagnostics) -} - pub fn collect_parameter_symbols_into( parameters: &[Parameter], all_symbols: &mut Vec, diff --git a/dmc-lib/src/ast/identifier.rs b/dmc-lib/src/ast/identifier.rs index 610ca25..d347dda 100644 --- a/dmc-lib/src/ast/identifier.rs +++ b/dmc-lib/src/ast/identifier.rs @@ -1,10 +1,10 @@ -use crate::ast::diagnostic_factories::{ - outer_class_field_usage, outer_class_method_usage, self_constructor_used_in_init, - self_field_used_in_init, self_method_used_in_init, symbol_not_found, -}; use crate::ast::ir_builder::IrBuilder; use crate::ast::ir_util::get_or_init_field_pointer_variable; use crate::diagnostic::Diagnostic; +use crate::diagnostic_factories::{ + outer_class_field_usage, outer_class_method_usage, self_constructor_used_in_init, + self_field_used_in_init, self_method_used_in_init, symbol_not_found, +}; use crate::ir::ir_assign::IrAssign; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_operation::IrOperation; diff --git a/dmc-lib/src/ast/let_statement.rs b/dmc-lib/src/ast/let_statement.rs index feea21a..6cde991 100644 --- a/dmc-lib/src/ast/let_statement.rs +++ b/dmc-lib/src/ast/let_statement.rs @@ -1,5 +1,4 @@ use crate::ast::expression::Expression; -use crate::ast::helpers::try_insert_symbol_into; use crate::ast::ir_builder::IrBuilder; use crate::diagnostic::Diagnostic; use crate::ir::ir_assign::IrAssign; @@ -10,6 +9,7 @@ use crate::symbol::Symbol; use crate::symbol::class_symbol::ClassSymbol; use crate::symbol::variable_symbol::VariableSymbol; use crate::symbol_table::SymbolTable; +use crate::symbol_table::util::try_insert_symbol_into; use crate::type_info::TypeInfo; use crate::types_table::TypesTable; use std::cell::RefCell; diff --git a/dmc-lib/src/ast/mod.rs b/dmc-lib/src/ast/mod.rs index 6f2a304..44722a6 100644 --- a/dmc-lib/src/ast/mod.rs +++ b/dmc-lib/src/ast/mod.rs @@ -4,7 +4,6 @@ pub mod call; pub mod class; pub mod compilation_unit; pub mod constructor; -mod diagnostic_factories; pub mod double_literal; pub mod expression; pub mod expression_statement; @@ -26,4 +25,3 @@ pub mod parameter; pub mod statement; pub mod string_literal; pub mod type_use; -mod util; diff --git a/dmc-lib/src/ast/type_use.rs b/dmc-lib/src/ast/type_use.rs index 373b711..9ca5940 100644 --- a/dmc-lib/src/ast/type_use.rs +++ b/dmc-lib/src/ast/type_use.rs @@ -1,5 +1,5 @@ -use crate::ast::diagnostic_factories::symbol_not_found; use crate::diagnostic::Diagnostic; +use crate::diagnostic_factories::symbol_not_found; use crate::error_codes::INCORRECT_GENERIC_ARGUMENTS; use crate::source_range::SourceRange; use crate::symbol::type_symbol::TypeSymbol; diff --git a/dmc-lib/src/compile_pipeline.rs b/dmc-lib/src/compile_pipeline.rs new file mode 100644 index 0000000..075636b --- /dev/null +++ b/dmc-lib/src/compile_pipeline.rs @@ -0,0 +1,51 @@ +use crate::ast::compilation_unit::CompilationUnit; +use crate::diagnostic::Diagnostics; +use crate::parser::parse_compilation_unit; +use crate::symbol_table::SymbolTable; +use crate::symbol_table::util::try_insert_symbols_into; +use std::collections::HashMap; +use std::rc::Rc; + +pub type Filename = Rc; + +fn parse_compilation_units( + inputs: &HashMap, +) -> Result, Diagnostics> { + let mut parse_diagnostics = Vec::new(); + let mut compilation_units = HashMap::new(); + for (file_name, source) in inputs { + match parse_compilation_unit(source) { + Ok(compilation_unit) => { + compilation_units.insert(file_name.clone(), compilation_unit); + } + Err(mut ds) => { + parse_diagnostics.append(&mut ds); + } + } + } + if parse_diagnostics.is_empty() { + Ok(compilation_units) + } else { + Err(parse_diagnostics) + } +} + +pub fn compile_compilation_units(inputs: &HashMap) -> Result<(), Diagnostics> { + let mut compilation_units = parse_compilation_units(inputs)?; + + let mut symbol_table = SymbolTable::new(); + + // init scopes + for compilation_unit in compilation_units.values_mut() { + compilation_unit.init_scopes(&mut symbol_table); + } + + // gather symbols + let all_symbols = compilation_units + .values() + .flat_map(|compilation_unit| compilation_unit.gather_symbols()) + .collect::>(); + try_insert_symbols_into(all_symbols, &mut symbol_table)?; + + Ok(()) +} diff --git a/dmc-lib/src/ast/diagnostic_factories.rs b/dmc-lib/src/diagnostic_factories.rs similarity index 100% rename from dmc-lib/src/ast/diagnostic_factories.rs rename to dmc-lib/src/diagnostic_factories.rs diff --git a/dmc-lib/src/lib.rs b/dmc-lib/src/lib.rs index af00528..e3f8012 100644 --- a/dmc-lib/src/lib.rs +++ b/dmc-lib/src/lib.rs @@ -1,6 +1,8 @@ pub mod ast; +pub mod compile_pipeline; pub mod constants_table; pub mod diagnostic; +mod diagnostic_factories; pub mod error_codes; pub mod intrinsics; pub mod ir; @@ -14,3 +16,4 @@ pub mod symbol_table; pub mod token; pub mod type_info; pub mod types_table; +mod util; diff --git a/dmc-lib/src/symbol_table/mod.rs b/dmc-lib/src/symbol_table/mod.rs index e2fdfaf..47e0e7a 100644 --- a/dmc-lib/src/symbol_table/mod.rs +++ b/dmc-lib/src/symbol_table/mod.rs @@ -1,4 +1,5 @@ mod helpers; +pub mod util; use crate::scope::Scope; use crate::scope::block_scope::BlockScope; diff --git a/dmc-lib/src/symbol_table/util.rs b/dmc-lib/src/symbol_table/util.rs new file mode 100644 index 0000000..fcc1c95 --- /dev/null +++ b/dmc-lib/src/symbol_table/util.rs @@ -0,0 +1,30 @@ +use crate::diagnostic::Diagnostic; +use crate::diagnostic_factories::symbol_already_declared; +use crate::diagnostics_result; +use crate::symbol::Symbol; +use crate::symbol_table::SymbolTable; + +pub fn try_insert_symbol_into( + symbol: Symbol, + symbol_table: &mut SymbolTable, +) -> Result<(), Diagnostic> { + let maybe_already_inserted = symbol_table.get_symbol(symbol.scope_id(), symbol.declared_name()); + if let Some(already_inserted) = maybe_already_inserted { + Err(symbol_already_declared(&already_inserted, &symbol)) + } else { + symbol_table.insert_symbol(symbol); + Ok(()) + } +} + +pub fn try_insert_symbols_into( + symbols: Vec, + symbol_table: &mut SymbolTable, +) -> Result<(), Vec> { + let diagnostics: Vec = symbols + .into_iter() + .map(|symbol| try_insert_symbol_into(symbol, symbol_table)) + .filter_map(Result::err) + .collect(); + diagnostics_result!(diagnostics) +} diff --git a/dmc-lib/src/ast/util.rs b/dmc-lib/src/util.rs similarity index 100% rename from dmc-lib/src/ast/util.rs rename to dmc-lib/src/util.rs