You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(stage3): TEA stdlib — counter + titlescreen running in interpreter
Stage 3 of the AffineScript TEA dogfood plan: The Elm Architecture
running in the AffineScript interpreter. Closes 3a–3d.
**Interpreter fixes (3b foundation):**
- `interp.ml` — `TopType TyEnum`: register enum constructors into the
runtime env. Nullary → VVariant value; N-ary → VBuiltin constructor
function. Previously all enum constructors were "Unbound variable" at
runtime.
- `interp.ml` — `tea_run` builtin: reads stdin line-by-line, dispatches
each line as a VVariant Msg to the user's `update` function, prints
the result of `view`. Clean EOF exit. Full REPL-style TEA loop.
- `value.ml` — `binop_string`: add `OpConcat` (the `++` operator) so
string concatenation works at runtime. Was falling through to "not
supported on strings".
- `resolve.ml` — `create_context`: register ALL interpreter builtins
(int_to_string, tea_run, float_to_string, read_line, etc.) so the
resolver doesn't reject them as UndefinedVariable.
- `typecheck.ml` — `register_builtins`: add `tea_run` with flexible
type `∀a. a → unit ! IO`.
- `bin/main.ml` — `eval_file` (both JSON and non-JSON paths): call
`register_builtins` before type-checking declarations (the eval path
was skipping this); auto-call `main()` after `eval_program` if main
is defined in the env.
**Examples (3c + 3d):**
- `examples/counter.afs` — canonical TEA counter: Increment/Decrement/
Reset messages, affine model, view renders "Count: N"
- `examples/titlescreen.afs` — IDApTIK title screen: TitleModel struct,
TitleMsg enum (NewGame/LoadGame/Settings/Credits), view renders screen
dimensions and selected option. Bridge target for Stage 4.
**Tests (5 new, 85 total):**
- counter compiles: frontend + eval_program succeeds
- counter init=0: apply_function counter_init [] returns VInt 0
- counter update transitions: Increment 0→1, Decrement 1→0
- titlescreen compiles: frontend + eval_program succeeds
- titlescreen NewGame→new_game: update sets selected field correctly
Stage 3 done when:
✓ counter.afs runs correctly (Increment/Decrement/Reset via stdin)
✓ ownership violations caught (Stage 1 QTT enforcement still live)
✓ titlescreen.afs compiles and interprets without errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
0 commit comments