1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-09 09:18:01 +00:00

Implement codegen for state dispatch, functions, arrays, math, scroll

State machine dispatch:
- Assign each state a numeric index, store in ZP $03
- Main loop dispatch table: CMP + BNE + JMP trampoline pattern
  (avoids branch range limits for large programs)
- on_enter/on_exit handlers generated as JSR targets
- Transition statement writes state index + JSR enter/exit handlers

Function calls:
- Function bodies emitted as labeled subroutines with RTS
- Statement::Call generates parameter passing via ZP + JSR
- Statement::Return generates RTS (with value in A if present)
- Parameter slots at ZP $04-$07

Break/continue:
- Loop stack tracks continue/break label pairs
- Break generates JMP to break_label
- Continue generates JMP to continue_label
- While and Loop push/pop the stack

Array indexing:
- LValue::ArrayIndex generates TAX + STA absolute,X
- Expr::ArrayIndex generates TAX + LDA absolute,X / ZP,X
- Compound array assignments (+=, -=, &=, |=, ^=) load-modify-store

Scroll:
- scroll(x, y) writes to PPU $2005 twice (X then Y)

Math:
- Multiply generates JSR __multiply (shift-and-add routine)
- Divide generates JSR __divide (restoring division)
- Modulo loads remainder from $03 after divide
- ShiftLeft generates ASL A, ShiftRight generates LSR A
- Math routines wired into linker

Error validations:
- E0203 for assignment to const variables
- Break/continue outside loop detection (in_loop tracking)

233 tests (8 new codegen + 2 analyzer + 2 integration), all passing.

https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
Claude 2026-04-12 02:04:49 +00:00
parent 3b1a03981b
commit 40632f192c
No known key found for this signature in database
6 changed files with 466 additions and 31 deletions

View file

@ -84,6 +84,10 @@ impl Linker {
// User code (var init + main loop)
all_instructions.extend(user_code.iter().cloned());
// Math runtime routines (included always for simplicity)
all_instructions.extend(runtime::gen_multiply());
all_instructions.extend(runtime::gen_divide());
// NMI handler
all_instructions.push(Instruction::new(NOP, AM::Label("__nmi".into())));
all_instructions.extend(runtime::gen_nmi());