Compile pipeline WIP and various refactoring.

This commit is contained in:
Jesse Brault 2026-03-27 11:59:59 -05:00
parent 178ce5d1a6
commit 584e7224a7
14 changed files with 118 additions and 38 deletions

View File

@ -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;

View File

@ -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<Symbol> {
let fqn_context = FqnContext::new();
[
self.classes
.iter()
.flat_map(|class| class.make_symbols(&fqn_context))
.collect::<Vec<_>>(),
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,

View File

@ -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;

View File

@ -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<Rc<str>> {
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>,
symbol_table: &mut SymbolTable,
) -> Result<(), Vec<Diagnostic>> {
let diagnostics: Vec<Diagnostic> = 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<Symbol>,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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<str>;
fn parse_compilation_units(
inputs: &HashMap<Filename, &str>,
) -> Result<HashMap<Filename, CompilationUnit>, 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<Filename, &str>) -> 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::<Vec<_>>();
try_insert_symbols_into(all_symbols, &mut symbol_table)?;
Ok(())
}

View File

@ -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;

View File

@ -1,4 +1,5 @@
mod helpers;
pub mod util;
use crate::scope::Scope;
use crate::scope::block_scope::BlockScope;

View File

@ -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>,
symbol_table: &mut SymbolTable,
) -> Result<(), Vec<Diagnostic>> {
let diagnostics: Vec<Diagnostic> = symbols
.into_iter()
.map(|symbol| try_insert_symbol_into(symbol, symbol_table))
.filter_map(Result::err)
.collect();
diagnostics_result!(diagnostics)
}