✓
Passing This code compiles and runs correctly.
Code
// Test: the cell state surface — shape-derived field manifest.
//
// `std/cell:open` bakes the proto block into a "name:type;..." manifest at
// transform time (the proto's own field grammar already ran upstream; the
// transform only splits lines). `get`/`set` validate field names against the
// manifest — a typo'd field names the shape (`unknown-field`), a value that
// won't coerce names the expected type (`type-mismatch`), and a declared-
// but-never-written field is `unset`, distinct from absent.
//
// The state is in-memory: hibernate loses it. That is the honest seam —
// a materializer (SQLite/DuckDB per the [X] field annotations still being
// designed) plugs in where `state` lives.
import std/io
import std/cell
import std/proto
import std/runtime
std/proto(room_state) {
visits: u32
name: string
awake: bool
}
pub tor greet { name: string } -> string
greet -> "hello {{ name:s }}"
std/runtime:register(scope: "cell") {
greet(5)
}
std/cell:open(room_state, id: "assistant")
| cell c |> std/cell:fields(c): fl |> std/io:print.ln("shape: {{ fl:s }}")
|> std/cell:get(c, field: "visits")
| value v |> std/io:print.ln("visits = {{ v.int:d }}")
| unknown-field e |> std/io:print.ln("no field {{ e.field:s }}")
| unset u |> std/io:print.ln("visits unset")
|> std/cell:set(c, field: "visits", value: "41")
| set |> std/io:print.ln("visits set")
| unknown-field e |> std/io:print.ln("no field")
| type-mismatch t |> std/io:print.ln("mismatch")
|> std/cell:get(c, field: "visits")
| value v |> std/io:print.ln("visits = {{ v.int:d }}")
| unknown-field e |> std/io:print.ln("no field")
| unset u |> std/io:print.ln("unset")
|> std/cell:set(c, field: "vists", value: "1")
| set |> std/io:print.ln("vists set")
| unknown-field e |> std/io:print.ln("unknown: {{ e.field:s }} (shape: {{ e.shape:s }})")
| type-mismatch t |> std/io:print.ln("mismatch")
|> std/cell:set(c, field: "visits", value: "abc")
| set |> std/io:print.ln("set")
| unknown-field e |> std/io:print.ln("no field")
| type-mismatch t |> std/io:print.ln("{{ t.field:s }} wanted {{ t.expected:s }}")
|> std/cell:set(c, field: "name", value: "assistant-01")
| set |> std/io:print.ln("name set")
| unknown-field e |> std/io:print.ln("no field")
| type-mismatch t |> std/io:print.ln("mismatch")
|> std/cell:set(c, field: "name", value: "assistant-02")
| set |> std/io:print.ln("name reset")
| unknown-field e |> std/io:print.ln("no field")
| type-mismatch t |> std/io:print.ln("mismatch")
|> std/cell:get(c, field: "name")
| value v |> std/io:print.ln("name = {{ v.text:s }}")
| unknown-field e |> std/io:print.ln("no field")
| unset u |> std/io:print.ln("unset")
|> std/cell:set(c, field: "awake", value: "true")
| set |> std/io:print.ln("awake set")
| unknown-field e |> std/io:print.ln("no field")
| type-mismatch t |> std/io:print.ln("mismatch")
|> std/cell:get(c, field: "awake")
| value v |> std/io:print.ln("awake = {{ v.flag:any }}")
| unknown-field e |> std/io:print.ln("no field")
| unset u |> std/io:print.ln("unset")
|> std/cell:run(c, source: "greet(name: \"assistant\")")
| result r |> std/io:print.ln("cell said: {{ r.bound:s }}")
| error e |> std/io:print.ln("turn failed: {{ e.kind:s }}")
|> std/cell:hibernate(c) |> std/io:print.ln("assistant hibernated")
Actual
shape: visits:u32;name:string;awake:bool
visits unset
visits set
visits = 41
unknown: vists (shape: room_state)
visits wanted u32
name set
name reset
name = assistant-02
awake set
awake = true
cell said: r1
assistant hibernated
Expected output
shape: visits:u32;name:string;awake:bool
visits unset
visits set
visits = 41
unknown: vists (shape: room_state)
visits wanted u32
name set
name reset
name = assistant-02
awake set
awake = true
cell said: r1
assistant hibernated
Flows
flow ~std/proto click a branch to expand · @labels scroll to their anchor
std/proto (room_state, source: visits: u32
name: string
awake: bool)
flow ~register click a branch to expand · @labels scroll to their anchor
register (scope: "cell", source: greet(5))
flow ~open click a branch to expand · @labels scroll to their anchor
open (expr: room_state, id: "assistant")
Test Configuration
MUST_RUN