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
1.1 KiB
Plaintext
22 lines
1.1 KiB
Plaintext
(tests
|
|
(names test_flan test_acceptance test_reload test_agent test_session test_dev test_emacs test_repl)
|
|
(libraries flan unix)
|
|
; The acceptance programs are part of the test corpus: if the reader, the
|
|
; parser or the checker regresses on them we want to know here, not at the CLI.
|
|
(deps
|
|
(file %{workspace_root}/calc-me.flan)
|
|
(file %{workspace_root}/sand.flan)
|
|
; The sim package and the raylib bindings, because the headless sand case and
|
|
; the FFI case import them and an import reads the directory at build time.
|
|
(glob_files %{workspace_root}/sand-sim/*)
|
|
(glob_files %{workspace_root}/vendor/raylib/*)
|
|
; The dev agent package: its Flan declarations and the C that implements them.
|
|
(glob_files %{workspace_root}/vendor/agent/*)
|
|
(glob_files programs/*.flan)
|
|
; The reload primitive's host: a C main that dlopens what Build.shared made.
|
|
(file reload_host.c)
|
|
; test_dev runs the compiler itself: flan dev launches and owns a program.
|
|
(file %{workspace_root}/bin/main.exe)
|
|
; The Emacs client, which test_emacs drives against a real daemon.
|
|
(glob_files %{workspace_root}/emacs/*.el)))
|