Phase 4a: machine states auto-number by declaration order

state KnightMenu = 0 { }  ->  state KnightMenu { }. Machine states now take their
value from declaration order (0,1,2,...); an explicit 'state Name = expr' still
works for the rare non-ordinal case. Removes the magic constants from state
machines (finding #13). Migrated combat.ludic's battle machine; chronorift golden
byte-identical (the ordinals match the old explicit 0-4). Reseeded, fixpoint
holds, test.sh 14/14.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-08-27 16:20:34 +03:00
parent 9a558d6b58
commit fd0b890acc
4 changed files with 427 additions and 394 deletions

View file

@ -379,15 +379,18 @@ state (no more `if phase == N` chains). See the co-op battle in
```ludic
# doc-check: skip — illustrative: elided bodies
machine R_PHASE {
state KnightMenu = 0 { … if is_confirm(k) { …attack… become KnightResolve } }
state KnightResolve = 1 { … become MageMenu }
state EnemyTurn = 4 { … become KnightMenu }
state KnightMenu { … if is_confirm(k) { …attack… become KnightResolve } }
state KnightResolve { … become MageMenu }
state EnemyTurn { … become KnightMenu }
}
```
A `machine <reg>` reads `reg(<reg>)` to pick the state; `become Name` compiles to
`setreg(<reg>, <Name's value>)`. Both lower to plain branches (and `match` runs
on the native LLVM backend too).
States **number themselves by declaration order** (`KnightMenu` is `0`,
`KnightResolve` is `1`, …) — no magic constants. (An explicit `state Name = expr`
is still accepted when a state needs a specific value.) A `machine <reg>` reads
`reg(<reg>)` to pick the state; `become Name` compiles to `setreg(<reg>, <Name's
value>)`. Both lower to plain branches (and `match` runs on the native LLVM
backend too).
## Expressions