Commit 1c7c884
Phase H.5.2: Op::SafeArrSetNamed — close the last
The host-level `safe` keyword shipped yesterday (commit 6e1b5f4)
worked correctly through tree-walk but `safe arr_set(VAR, ...)`
compiled to bytecode lost the mutation when run through the Rust
VM — same shape gap V.7c originally closed for plain arr_set with
Op::ArrSetNamed.
The fix is structurally identical: take the variable name off the
value stack and put it on the opcode itself, bypassing
vm_call_builtin's synthetic-arg shim that copies array arguments.
bytecode.rs: New Op::SafeArrSetNamed(String) variant.
vm.rs: Dispatch handler — pop val, pop raw_idx, fold raw_idx
onto nearest Fibonacci attractor via the new
pub(crate) interpreter::fold_to_fibonacci_const,
Euclidean-mod by arr_len, mutate, write back.
Empty arrays silently drop the write (total semantics).
compiler.rs: Safe(Call("arr_set", [Variable, idx, val])) emits
SafeArrSetNamed; non-Variable first arg falls through
to Op::Call("safe_arr_set", 3) which still loses
mutation (same semantics as plain arr_set on non-VAR).
disasm.rs: Disassembly format for the new op.
interpreter.rs: fold_to_fibonacci_const promoted to pub(crate)
so vm.rs can call it.
Verified end-to-end: examples/safe_keyword_host.omc produces
identical output under tree-walk and OMC_VM=1. The Rust VM
disassembly shows `0027: SAFE_ARR_SET_NAMED xs` for the
`safe arr_set(xs, 999, 99)` call — the mutation lands at
xs[fold(999) % 3] = xs[1], propagating through VM scope correctly.
Phase H is now end-to-end clean on BOTH interpretation paths.
Self-healing semantics work the same way whether you're tree-
walking or compiling-and-running, for every documented shape:
safe divide, safe arr_get, safe arr_set.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>safe keyword gap1 parent dc16b10 commit 1c7c884
5 files changed
Lines changed: 50 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
112 | 119 | | |
113 | 120 | | |
114 | 121 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
437 | 437 | | |
438 | 438 | | |
439 | 439 | | |
440 | | - | |
441 | | - | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
442 | 455 | | |
443 | | - | |
444 | 456 | | |
445 | 457 | | |
446 | 458 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
| 78 | + | |
78 | 79 | | |
79 | 80 | | |
80 | 81 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1843 | 1843 | | |
1844 | 1844 | | |
1845 | 1845 | | |
1846 | | - | |
| 1846 | + | |
1847 | 1847 | | |
1848 | 1848 | | |
1849 | 1849 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
289 | 289 | | |
290 | 290 | | |
291 | 291 | | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
292 | 318 | | |
293 | 319 | | |
294 | 320 | | |
| |||
0 commit comments