Another big parser refactor, collecting diagnostics better.

This commit is contained in:
Jesse Brault 2026-03-28 20:50:46 -05:00
parent 0df1252053
commit f95d504f88
8 changed files with 765 additions and 525 deletions

View File

@ -175,7 +175,10 @@ fn compile_expression(
constants_table: &mut ConstantsTable,
) -> Result<Function, Vec<Diagnostic>> {
// parse
let mut expression = parse_expression(input)?;
let (mut expression, parse_diagnostics) = parse_expression(input);
if !parse_diagnostics.is_empty() {
return Err(parse_diagnostics);
}
// init scopes, if necessary
let container_scope = prepare_scopes(symbol_table, fn_body_scope_id);
@ -240,7 +243,11 @@ fn compile_let_statement(
constants_table: &mut ConstantsTable,
) -> Result<Function, Vec<Diagnostic>> {
// parse
let mut let_statement = parse_let_statement(input)?;
let (maybe_let_statement, parse_diagnostics) = parse_let_statement(input);
if !parse_diagnostics.is_empty() {
return Err(parse_diagnostics);
}
let mut let_statement = maybe_let_statement.unwrap();
// names
let container_scope_id = prepare_scopes(symbol_table, body_scope_id);

View File

@ -7,7 +7,7 @@ use dmc_lib::constants_table::ConstantsTable;
use dmc_lib::diagnostic::Diagnostic;
use dmc_lib::intrinsics::{insert_intrinsic_symbols, insert_intrinsic_types};
use dmc_lib::offset_counter::OffsetCounter;
use dmc_lib::parser::parse_compilation_unit;
use dmc_lib::parser::get_compilation_unit;
use dmc_lib::symbol_table::SymbolTable;
use dmc_lib::types_table::TypesTable;
use dvm_lib::vm::constant::{Constant, StringConstant};
@ -41,7 +41,7 @@ fn run(
show_asm: bool,
register_count: usize,
) -> Result<(), Vec<Diagnostic>> {
let mut compilation_unit = parse_compilation_unit(&input)?;
let mut compilation_unit = get_compilation_unit(&input)?;
let mut symbol_table = SymbolTable::new();
symbol_table.push_module_scope("global scope");

View File

@ -255,7 +255,7 @@ mod tests {
use crate::ast::compilation_unit::CompilationUnit;
use crate::diagnostic::Diagnostic;
use crate::error_codes::{ASSIGN_LHS_IMMUTABLE, ASSIGN_MISMATCHED_TYPES, ASSIGN_NO_L_VALUE};
use crate::parser::parse_compilation_unit;
use crate::parser::get_compilation_unit;
use crate::symbol_table::SymbolTable;
use crate::types_table::TypesTable;
@ -272,15 +272,14 @@ mod tests {
#[test]
fn finds_mismatched_types() -> Result<(), Vec<Diagnostic>> {
let mut compilation_unit = parse_compilation_unit(
let mut compilation_unit = get_compilation_unit(
"
fn main()
let mut x = 4
x = \"Hello\"
end
",
)
.unwrap();
)?;
let mut symbol_table = SymbolTable::new();
let mut types_table = TypesTable::new();
compile_up_to_type_check(&mut compilation_unit, &mut symbol_table, &mut types_table)?;
@ -297,7 +296,7 @@ mod tests {
#[test]
fn finds_no_l_value() -> Result<(), Vec<Diagnostic>> {
let mut compilation_unit = parse_compilation_unit(
let mut compilation_unit = get_compilation_unit(
"
fn main()
42 = 42
@ -317,7 +316,7 @@ mod tests {
#[test]
fn finds_immutable_destination() -> Result<(), Vec<Diagnostic>> {
let mut compilation_unit = parse_compilation_unit(
let mut compilation_unit = get_compilation_unit(
"
fn main()
let x = 42

View File

@ -174,13 +174,13 @@ impl TypeUse {
#[cfg(test)]
mod tests {
use crate::diagnostic::Diagnostic;
use crate::parser::parse_compilation_unit;
use crate::parser::get_compilation_unit;
use crate::symbol_table::SymbolTable;
use crate::types_table::TypesTable;
#[test]
fn type_check_generics() -> Result<(), Vec<Diagnostic>> {
let mut compilation_unit = parse_compilation_unit(
let mut compilation_unit = get_compilation_unit(
"
class String end

View File

@ -14,14 +14,9 @@ fn parse_compilation_units(
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);
}
}
let (compilation_unit, mut ds) = parse_compilation_unit(source);
parse_diagnostics.append(&mut ds);
compilation_units.insert(file_name.clone(), compilation_unit);
}
if parse_diagnostics.is_empty() {
Ok(compilation_units)

View File

@ -124,13 +124,13 @@ impl Display for IrBlock {
mod tests {
use crate::diagnostic::Diagnostic;
use crate::offset_counter::OffsetCounter;
use crate::parser::parse_compilation_unit;
use crate::parser::get_compilation_unit;
use crate::symbol_table::SymbolTable;
use crate::types_table::TypesTable;
#[test]
fn overlapping_assignments_bug_when_k_2() -> Result<(), Vec<Diagnostic>> {
let mut compilation_unit = parse_compilation_unit(
let mut compilation_unit = get_compilation_unit(
"
fn main()
let a = 1

File diff suppressed because it is too large Load Diff

View File

@ -29,13 +29,10 @@ mod e2e_tests {
}
fn prepare_context(input: &str) -> Result<DvmContext, Vec<Diagnostic>> {
let parse_result = parse_compilation_unit(input);
let mut compilation_unit = match parse_result {
Ok(compilation_unit) => compilation_unit,
Err(diagnostics) => {
report_diagnostics(&diagnostics);
}
};
let (mut compilation_unit, diagnostics) = parse_compilation_unit(input);
if !diagnostics.is_empty() {
return Err(diagnostics);
}
let mut symbol_table = SymbolTable::new();
symbol_table.push_module_scope("global_scope");