feat(control_tree): Phase 136/137 - return literal and add expression (dev-only)

Phase 136 P0: Return literal (Integer) support
- Extend loop(true) break-once to support `return 7`
- Fixtures: phase136_loop_true_break_once_return_literal_min.hako (exit code 7)
- VM/LLVM EXE parity achieved

Phase 137 P0: Return add expression support
- Extend to support `return x + 2` and `return 5 + 3`
- LHS: Variable or Integer literal
- RHS: Integer literal only
- Fixtures:
  - phase137_loop_true_break_once_return_add_min.hako (exit code 3)
  - phase137_loop_true_break_once_return_add_const_min.hako (exit code 8)
  - phase137_loop_true_break_once_post_return_add_min.hako (exit code 13)
- VM/LLVM EXE parity achieved

Implementation:
- Added lower_return_value_to_vid() method in loop_true_break_once.rs
- Replaced extract_variable_name() with unified return value lowering
- Supported patterns: Variable, Integer literal, BinaryOp Add
- Out-of-scope patterns return Ok(None) for fallback
- SSOT documentation added (lines 29-46)

Tests: 5 fixtures + 10 smoke tests (5 VM + 5 LLVM EXE), all PASS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-19 00:15:32 +09:00
parent 91c7dfbf0b
commit ff09adebe0
16 changed files with 703 additions and 23 deletions

View File

@ -0,0 +1,26 @@
// Phase 136 P0: loop(true) break-once + post assign + return literal fixture
//
// Purpose: Test loop(true) { <assign>* ; break }; <assign>; return <int_literal>
// Expected exit code: 7
//
// Structure:
// x = 0 // pre-loop init
// loop(true) { // condition is Bool literal true
// x = 1 // body assignment
// break // break at end
// }
// x = x + 2 // post-loop computation (this IS executed)
// return 7 // return integer literal (not x, so result is 7 not 3)
static box Main {
main() {
local x
x = 0
loop(true) {
x = 1
break
}
x = x + 2
return 7
}
}

View File

@ -0,0 +1,24 @@
// Phase 136 P0: loop(true) break-once + return literal minimal fixture
//
// Purpose: Test loop(true) { <assign>* ; break }; return <int_literal>
// Expected exit code: 7
//
// Structure:
// x = 0 // pre-loop init
// loop(true) { // condition is Bool literal true
// x = 1 // body assignment
// break // break at end
// }
// return 7 // return integer literal (not variable)
static box Main {
main() {
local x
x = 0
loop(true) {
x = 1
break
}
return 7
}
}

View File

@ -0,0 +1,26 @@
// Phase 137 P0: loop(true) break-once with post-loop assigns + return add minimal fixture
//
// Purpose: Test post-loop assigns + return add expression
// Expected output: 13 (0 → 1 → 11 → 13)
//
// Structure:
// x = 0 // pre-loop init
// loop(true) { // condition is Bool literal true
// x = 1 // body assignment
// break // break at end
// }
// x = x + 10 // post-loop assignment
// return x + 2 // return add expression
static box Main {
main() {
local x
x = 0
loop(true) {
x = 1
break
}
x = x + 10
return x + 2
}
}

View File

@ -0,0 +1,19 @@
// Phase 137 P0: loop(true) break-once with return add (const + const) minimal fixture
//
// Purpose: Test return 5 + 3 (constant + constant)
// Expected output: 8
//
// Structure:
// loop(true) { // condition is Bool literal true
// break // break at end
// }
// return 5 + 3 // return add expression (const + const)
static box Main {
main() {
loop(true) {
break
}
return 5 + 3
}
}

View File

@ -0,0 +1,24 @@
// Phase 137 P0: loop(true) break-once with return add minimal fixture
//
// Purpose: Test return x + 2 (where x is env variable)
// Expected output: 3 (x=0, x=1 in loop, return 1+2)
//
// Structure:
// x = 0 // pre-loop init
// loop(true) { // condition is Bool literal true
// x = 1 // body assignment (to make x part of env)
// break // break at end
// }
// return x + 2 // return add expression
static box Main {
main() {
local x
x = 0
loop(true) {
x = 1
break
}
return x + 2
}
}