diff --git a/crates/lean_compiler/src/a_simplify_lang.rs b/crates/lean_compiler/src/a_simplify_lang.rs index 558ff452..5ea1e3be 100644 --- a/crates/lean_compiler/src/a_simplify_lang.rs +++ b/crates/lean_compiler/src/a_simplify_lang.rs @@ -96,6 +96,7 @@ pub enum SimpleLine { condition: SimpleExpr, then_branch: Vec, else_branch: Vec, + line_number: SourceLineNumber, }, TestZero { // Test that the result of the given operation is zero @@ -107,6 +108,7 @@ pub enum SimpleLine { function_name: String, args: Vec, return_data: Vec, + line_number: SourceLineNumber, }, FunctionRet { return_data: Vec, @@ -316,7 +318,7 @@ fn simplify_lines( const_malloc, ); } - Line::Assert(boolean) => match boolean { + Line::Assert(boolean, line_number) => match boolean { Boolean::Different { left, right } => { let left = simplify_expr(left, &mut res, counters, array_manager, const_malloc); let right = @@ -333,6 +335,7 @@ fn simplify_lines( condition: diff_var.into(), then_branch: vec![], else_branch: vec![SimpleLine::Panic], + line_number: *line_number, }); } Boolean::Equal { left, right } => { @@ -358,6 +361,7 @@ fn simplify_lines( condition, then_branch, else_branch, + line_number, } => { let (condition_simplified, then_branch, else_branch) = match condition { Condition::Comparison(condition) => { @@ -468,6 +472,7 @@ fn simplify_lines( condition: condition_simplified, then_branch: then_branch_simplified, else_branch: else_branch_simplified, + line_number: *line_number, }); } Line::ForLoop { @@ -477,6 +482,7 @@ fn simplify_lines( body, rev, unroll, + line_number, } => { if *unroll { let (internal_variables, _) = find_variable_usage(body); @@ -534,7 +540,7 @@ fn simplify_lines( const_malloc.counter = loop_const_malloc.counter; array_manager.valid = valid_aux_vars_in_array_manager_before; // restore the valid aux vars - let func_name = format!("@loop_{}", counters.loops); + let func_name = format!("@loop_{}_line_{}", counters.loops, line_number); counters.loops += 1; // Find variables used inside loop but defined outside @@ -574,6 +580,7 @@ fn simplify_lines( // Create recursive function body let recursive_func = create_recursive_function( func_name.clone(), + *line_number, func_args, iterator.clone(), end_simplified, @@ -590,12 +597,14 @@ fn simplify_lines( function_name: func_name, args: call_args, return_data: vec![], + line_number: *line_number, }); } Line::FunctionCall { function_name, args, return_data, + line_number, } => { let simplified_args = args .iter() @@ -605,6 +614,7 @@ fn simplify_lines( function_name: function_name.clone(), args: simplified_args, return_data: return_data.clone(), + line_number: *line_number, }); } Line::FunctionRet { return_data } => { @@ -872,6 +882,7 @@ pub fn find_variable_usage(lines: &[Line]) -> (BTreeSet, BTreeSet) { condition, then_branch, else_branch, + line_number: _, } => { on_new_condition(condition, &internal_vars, &mut external_vars); @@ -894,7 +905,7 @@ pub fn find_variable_usage(lines: &[Line]) -> (BTreeSet, BTreeSet) { } internal_vars.extend(return_data.iter().cloned()); } - Line::Assert(condition) => { + Line::Assert(condition, _line_number) => { on_new_condition( &Condition::Comparison(condition.clone()), &internal_vars, @@ -941,6 +952,7 @@ pub fn find_variable_usage(lines: &[Line]) -> (BTreeSet, BTreeSet) { body, rev: _, unroll: _, + line_number: _, } => { let (body_internal, body_external) = find_variable_usage(body); internal_vars.extend(body_internal); @@ -1040,6 +1052,7 @@ pub fn inline_lines( condition, then_branch, else_branch, + line_number: _, } => { inline_condition(condition); @@ -1058,7 +1071,7 @@ pub fn inline_lines( inline_internal_var(return_var); } } - Line::Assert(condition) => { + Line::Assert(condition, _line_number) => { inline_comparison(condition); } Line::FunctionRet { return_data } => { @@ -1112,6 +1125,7 @@ pub fn inline_lines( body, rev: _, unroll: _, + line_number: _, } => { inline_lines(body, args, res, inlining_count); inline_internal_var(iterator); @@ -1234,6 +1248,7 @@ fn handle_array_assignment( fn create_recursive_function( name: String, + line_number: SourceLineNumber, args: Vec, iterator: Var, end: SimpleExpr, @@ -1257,6 +1272,7 @@ fn create_recursive_function( function_name: name.clone(), args: recursive_args, return_data: vec![], + line_number, }); body.push(SimpleLine::FunctionRet { return_data: vec![], @@ -1277,6 +1293,7 @@ fn create_recursive_function( else_branch: vec![SimpleLine::FunctionRet { return_data: vec![], }], + line_number, }, ]; @@ -1416,7 +1433,10 @@ fn replace_vars_for_unroll( internal_vars, ); } - Line::Assert(Boolean::Equal { left, right } | Boolean::Different { left, right }) => { + Line::Assert( + Boolean::Equal { left, right } | Boolean::Different { left, right }, + _line_number, + ) => { replace_vars_for_unroll_in_expr( left, iterator, @@ -1436,6 +1456,7 @@ fn replace_vars_for_unroll( condition, then_branch, else_branch, + line_number: _, } => { match condition { Condition::Comparison( @@ -1489,6 +1510,7 @@ fn replace_vars_for_unroll( body, rev: _, unroll: _, + line_number: _, } => { assert!(other_iterator != iterator); *other_iterator = @@ -1519,6 +1541,7 @@ fn replace_vars_for_unroll( function_name: _, args, return_data, + line_number: _, } => { // Function calls are not unrolled, so we don't need to change them for arg in args { @@ -1709,6 +1732,7 @@ fn handle_inlined_functions_helper( function_name, args, return_data, + line_number: _, } => { if let Some(func) = inlined_functions.get(&*function_name) { let mut inlined_lines = vec![]; @@ -1860,6 +1884,7 @@ fn handle_const_arguments_helper( function_name, args, return_data: _, + line_number: _, } => { if let Some(func) = constant_functions.get(function_name) { // If the function has constant arguments, we need to handle them @@ -2051,6 +2076,7 @@ fn replace_vars_by_const_in_lines(lines: &mut [Line], map: &BTreeMap) { condition, then_branch, else_branch, + line_number: _, } => { match condition { Condition::Comparison(Boolean::Equal { left, right }) @@ -2072,7 +2098,7 @@ fn replace_vars_by_const_in_lines(lines: &mut [Line], map: &BTreeMap) { replace_vars_by_const_in_expr(end, map); replace_vars_by_const_in_lines(body, map); } - Line::Assert(condition) => match condition { + Line::Assert(condition, _line_number) => match condition { Boolean::Equal { left, right } | Boolean::Different { left, right } => { replace_vars_by_const_in_expr(left, map); replace_vars_by_const_in_expr(right, map); @@ -2212,6 +2238,7 @@ impl SimpleLine { condition, then_branch, else_branch, + line_number: _, } => { let then_str = then_branch .iter() @@ -2237,6 +2264,7 @@ impl SimpleLine { function_name, args, return_data, + line_number: _, } => { let args_str = args .iter() diff --git a/crates/lean_compiler/src/b_compile_intermediate.rs b/crates/lean_compiler/src/b_compile_intermediate.rs index cffa8f45..1b26315f 100644 --- a/crates/lean_compiler/src/b_compile_intermediate.rs +++ b/crates/lean_compiler/src/b_compile_intermediate.rs @@ -288,6 +288,7 @@ fn compile_lines( condition, then_branch, else_branch, + line_number, } => { validate_vars_declared(&[condition], declared_vars)?; @@ -295,9 +296,9 @@ fn compile_lines( compiler.if_counter += 1; let (if_label, else_label, end_label) = ( - Label::if_label(if_id), - Label::else_label(if_id), - Label::if_else_end(if_id), + Label::if_label(if_id, *line_number), + Label::else_label(if_id, *line_number), + Label::if_else_end(if_id, *line_number), ); // c: condition @@ -425,10 +426,11 @@ fn compile_lines( function_name: callee_function_name, args, return_data, + line_number, } => { let call_id = compiler.call_counter; compiler.call_counter += 1; - let return_label = Label::return_from_call(call_id); + let return_label = Label::return_from_call(call_id, *line_number); let new_fp_pos = compiler.stack_size; compiler.stack_size += 1; diff --git a/crates/lean_compiler/src/lang.rs b/crates/lean_compiler/src/lang.rs index 7eea1ea0..3514c509 100644 --- a/crates/lean_compiler/src/lang.rs +++ b/crates/lean_compiler/src/lang.rs @@ -332,11 +332,12 @@ pub enum Line { index: Expression, value: Expression, }, - Assert(Boolean), + Assert(Boolean, SourceLineNumber), IfCondition { condition: Condition, then_branch: Vec, else_branch: Vec, + line_number: SourceLineNumber, }, ForLoop { iterator: Var, @@ -345,11 +346,13 @@ pub enum Line { body: Vec, rev: bool, unroll: bool, + line_number: SourceLineNumber, }, FunctionCall { function_name: String, args: Vec, return_data: Vec, + line_number: SourceLineNumber, }, FunctionRet { return_data: Vec, @@ -445,11 +448,12 @@ impl Line { } => { format!("{array}[{index}] = {value}") } - Self::Assert(condition) => format!("assert {condition}"), + Self::Assert(condition, _line_number) => format!("assert {condition}"), Self::IfCondition { condition, then_branch, else_branch, + line_number: _, } => { let then_str = then_branch .iter() @@ -481,6 +485,7 @@ impl Line { body, rev, unroll, + line_number: _, } => { let body_str = body .iter() @@ -502,6 +507,7 @@ impl Line { function_name, args, return_data, + line_number: _, } => { let args_str = args .iter() diff --git a/crates/lean_compiler/src/parser/parsers/function.rs b/crates/lean_compiler/src/parser/parsers/function.rs index c7ad9e03..2abb209f 100644 --- a/crates/lean_compiler/src/parser/parsers/function.rs +++ b/crates/lean_compiler/src/parser/parsers/function.rs @@ -3,6 +3,7 @@ use super::literal::VarListParser; use super::statement::StatementParser; use super::{Parse, ParseContext, next_inner_pair}; use crate::{ + SourceLineNumber, lang::{Expression, Function, Line, SimpleExpr}, parser::{ error::{ParseResult, SemanticError}, @@ -113,6 +114,7 @@ impl Parse for FunctionCallParser { let mut return_data = Vec::new(); let mut function_name = String::new(); let mut args = Vec::new(); + let line_number = pair.line_col().0; for item in pair.into_inner() { match item.as_rule() { @@ -148,12 +150,13 @@ impl Parse for FunctionCallParser { } // Handle built-in functions - Self::handle_builtin_function(function_name, args, return_data) + Self::handle_builtin_function(line_number, function_name, args, return_data) } } impl FunctionCallParser { fn handle_builtin_function( + line_number: SourceLineNumber, function_name: String, args: Vec, return_data: Vec, @@ -249,6 +252,7 @@ impl FunctionCallParser { function_name, args, return_data, + line_number, }) } } diff --git a/crates/lean_compiler/src/parser/parsers/statement.rs b/crates/lean_compiler/src/parser/parsers/statement.rs index 2d4e0fa9..de055693 100644 --- a/crates/lean_compiler/src/parser/parsers/statement.rs +++ b/crates/lean_compiler/src/parser/parsers/statement.rs @@ -78,6 +78,7 @@ pub struct IfStatementParser; impl Parse for IfStatementParser { fn parse(pair: ParsePair<'_>, ctx: &mut ParseContext) -> ParseResult { + let line_number = pair.line_col().0; let mut inner = pair.into_inner(); let condition = ConditionParser::parse(next_inner_pair(&mut inner, "if condition")?, ctx)?; @@ -104,6 +105,7 @@ impl Parse for IfStatementParser { condition, then_branch, else_branch, + line_number, }) } } @@ -170,6 +172,7 @@ pub struct ForStatementParser; impl Parse for ForStatementParser { fn parse(pair: ParsePair<'_>, ctx: &mut ParseContext) -> ParseResult { + let line_number = pair.line_col().0; let mut inner = pair.into_inner(); let iterator = next_inner_pair(&mut inner, "loop iterator")? .as_str() @@ -209,6 +212,7 @@ impl Parse for ForStatementParser { body, rev, unroll, + line_number, }) } } @@ -298,11 +302,12 @@ pub struct AssertEqParser; impl Parse for AssertEqParser { fn parse(pair: ParsePair<'_>, ctx: &mut ParseContext) -> ParseResult { + let line_number = pair.line_col().0; let mut inner = pair.into_inner(); let left = ExpressionParser::parse(next_inner_pair(&mut inner, "left assertion")?, ctx)?; let right = ExpressionParser::parse(next_inner_pair(&mut inner, "right assertion")?, ctx)?; - Ok(Line::Assert(Boolean::Equal { left, right })) + Ok(Line::Assert(Boolean::Equal { left, right }, line_number)) } } @@ -311,10 +316,14 @@ pub struct AssertNotEqParser; impl Parse for AssertNotEqParser { fn parse(pair: ParsePair<'_>, ctx: &mut ParseContext) -> ParseResult { + let line_number = pair.line_col().0; let mut inner = pair.into_inner(); let left = ExpressionParser::parse(next_inner_pair(&mut inner, "left assertion")?, ctx)?; let right = ExpressionParser::parse(next_inner_pair(&mut inner, "right assertion")?, ctx)?; - Ok(Line::Assert(Boolean::Different { left, right })) + Ok(Line::Assert( + Boolean::Different { left, right }, + line_number, + )) } } diff --git a/crates/lean_vm/src/core/label.rs b/crates/lean_vm/src/core/label.rs index 77e005ae..e4224299 100644 --- a/crates/lean_vm/src/core/label.rs +++ b/crates/lean_vm/src/core/label.rs @@ -1,3 +1,5 @@ +use crate::core::SourceLineNumber; + /// Structured label for bytecode locations #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum Label { @@ -5,14 +7,19 @@ pub enum Label { Function(String), /// Program termination: @end_program EndProgram, - /// Conditional flow: @if_{id}, @else_{id}, @if_else_end_{id} - If { id: usize, kind: IfKind }, + /// Conditional flow: @if_{id}_line_{line_number}, @else_{id}_line_{line_number}, + /// @if_else_end_{id}_line_{line_number} + If { + id: usize, + kind: IfKind, + line_number: SourceLineNumber, + }, /// Match statement end: @match_end_{id} MatchEnd(usize), /// Return from function call: @return_from_call_{id} - ReturnFromCall(usize), - /// Loop definition: @loop_{id} - Loop(usize), + ReturnFromCall(usize, SourceLineNumber), + /// Loop definition: @loop_{id}_line_{line_number} + Loop(usize, SourceLineNumber), /// Built-in memory symbols BuiltinSymbol(BuiltinSymbol), /// Auxiliary variables during compilation @@ -68,14 +75,20 @@ impl std::fmt::Display for Label { match self { Self::Function(name) => write!(f, "@function_{name}"), Self::EndProgram => write!(f, "@end_program"), - Self::If { id, kind } => match kind { - IfKind::If => write!(f, "@if_{id}"), - IfKind::Else => write!(f, "@else_{id}"), - IfKind::End => write!(f, "@if_else_end_{id}"), + Self::If { + id, + kind, + line_number, + } => match kind { + IfKind::If => write!(f, "@if_{id}_line_{line_number}"), + IfKind::Else => write!(f, "@else_{id}_line_{line_number}"), + IfKind::End => write!(f, "@if_else_end_{id}_line_{line_number}"), }, Self::MatchEnd(id) => write!(f, "@match_end_{id}"), - Self::ReturnFromCall(id) => write!(f, "@return_from_call_{id}"), - Self::Loop(id) => write!(f, "@loop_{id}"), + Self::ReturnFromCall(id, line_number) => { + write!(f, "@return_from_call_{id}_line_{line_number}") + } + Self::Loop(id, line_number) => write!(f, "@loop_{id}_line_{line_number}"), Self::BuiltinSymbol(symbol) => write!(f, "{symbol}"), Self::AuxVar { kind, id } => match kind { AuxKind::AuxVar => write!(f, "@aux_var_{id}"), @@ -108,24 +121,27 @@ impl Label { Self::Function(name.into()) } - pub fn if_label(id: usize) -> Self { + pub fn if_label(id: usize, line_number: SourceLineNumber) -> Self { Self::If { id, kind: IfKind::If, + line_number, } } - pub fn else_label(id: usize) -> Self { + pub fn else_label(id: usize, line_number: SourceLineNumber) -> Self { Self::If { id, kind: IfKind::Else, + line_number, } } - pub fn if_else_end(id: usize) -> Self { + pub fn if_else_end(id: usize, line_number: SourceLineNumber) -> Self { Self::If { id, kind: IfKind::End, + line_number, } } @@ -133,12 +149,12 @@ impl Label { Self::MatchEnd(id) } - pub fn return_from_call(id: usize) -> Self { - Self::ReturnFromCall(id) + pub fn return_from_call(id: usize, line_number: SourceLineNumber) -> Self { + Self::ReturnFromCall(id, line_number) } - pub fn loop_label(id: usize) -> Self { - Self::Loop(id) + pub fn loop_label(id: usize, line_number: SourceLineNumber) -> Self { + Self::Loop(id, line_number) } pub fn aux_var(id: usize) -> Self {