mirror of
https://github.com/imjasonh/nescript
synced 2026-07-08 08:55:38 +00:00
IR codegen: allocate storage for function-local variables
Function bodies can declare local variables with \`var NAME: u8 = …\`. Previously the lowering created a VarId for them but didn't track it on the \`IrFunction.locals\` list, so the IR codegen had no address to map it to and \`LoadVar\` / \`StoreVar\` silently did nothing. The generated function body read and wrote random temp slots. Fixes: - Lowering: replaced the per-function \`locals\` local with a long-lived \`current_locals\` field; \`lower_function\` resets it on entry and moves it into the \`IrFunction\` at exit. Each \`Statement::VarDecl\` inside a function body appends to \`current_locals\`. - IR codegen: iterate every function's \`locals\` list. Params 0..4 still map to \$04-\$07, and the remaining locals get addresses in main RAM starting at \$0300. Each function's locals are disjoint, so nested calls don't corrupt each other's state. - Integration test \`program_with_function_local_variables\` exercises nested calls with function-local state to guard against regression. https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
parent
240da57b54
commit
34b312537d
3 changed files with 69 additions and 11 deletions
|
|
@ -178,6 +178,37 @@ fn program_with_on_scanline_per_state() {
|
|||
rom::validate_ines(&rom_data).expect("should be valid iNES");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn program_with_function_local_variables() {
|
||||
// Functions with locally-declared variables should allocate
|
||||
// their own backing storage and not corrupt caller state when
|
||||
// nested.
|
||||
let source = r#"
|
||||
game "Locals" { mapper: NROM }
|
||||
var out: u8 = 0
|
||||
|
||||
fun double(x: u8) -> u8 {
|
||||
var t: u8 = x
|
||||
t = t + t
|
||||
return t
|
||||
}
|
||||
|
||||
fun double_sum(a: u8, b: u8) -> u8 {
|
||||
var s1: u8 = double(a)
|
||||
var s2: u8 = double(b)
|
||||
return s1 + s2
|
||||
}
|
||||
|
||||
on frame {
|
||||
out = double_sum(10, 20)
|
||||
wait_frame
|
||||
}
|
||||
start Main
|
||||
"#;
|
||||
let rom_data = compile(source);
|
||||
rom::validate_ines(&rom_data).expect("should be valid iNES");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn program_with_for_loop() {
|
||||
let source = r#"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue