A different primitive from redefining a name. There is no name to install a body into, so the expression is wrapped in a function with nowhere to be called from; the module exports flan_reload_call to say "run this once", and the agent calls it after the install - on the game thread, at a frame boundary, so an expression that reads the program's state sees a point the program agrees is consistent. Nothing is marshalled back because nothing could be. A Flan value carries no header, so no code at run time can say what it is; the compiler knows the type and renders it there, in the thunk. That is the layout decision's bill, and it is why the printer set is the scalars rather than everything. The rendering does not go through stdout. Stdout belongs to the program, it is in the hot path for anything that prints, and a dev-only feature must not put a branch in it - so flan_rt.c is untouched and the value goes to flan_dev_result, read back over the agent's socket. Safe without a handshake because the generation counter is bumped last: the daemon waits for it to move rather than assuming the program has reached a frame boundary. u64 refuses by name, because i64->bytes is signed and anything past 2^63 would come back negative. Everything without a derived printer refuses the same way. A number that is quietly wrong is the failure this whole thing exists to prevent. An evaluation is not a declaration: the thunk is built against the program and never spliced into it, so describe does not fill up with an eval/N for every expression ever typed. The test that matters is the same expression twice. The fixture increments ticks every frame, so two evaluations must disagree - a value computed in the compiler, or read from a copy of the program's state, would not.
22 lines
644 B
Plaintext
22 lines
644 B
Plaintext
;;;; A program that just runs, for evaluating expressions against.
|
|
;;;;
|
|
;;;; Unlike dev-loop.flan it does not count reloads and stop: C-x C-e is a
|
|
;;;; thunk the agent runs at a frame boundary, so a program under test has to
|
|
;;;; keep reaching them. (agent/wait 5) is both the poll and the pacing — 5ms
|
|
;;;; of nothing, which is what a frame is when there is no frame.
|
|
(import agent "vendor:agent")
|
|
|
|
(defvar ticks i64)
|
|
(defconst step-by i64 3)
|
|
|
|
(defn step [] i64
|
|
(set ticks (+ ticks step-by))
|
|
ticks)
|
|
|
|
(defn main [] i32
|
|
(agent/start "/tmp/flan-dev-repl-fallback.sock")
|
|
(dotimes [i 4000]
|
|
(agent/wait 5)
|
|
(set ticks (step)))
|
|
0)
|