C-c C-m over a provider, and what it has to show

The live loop's two halves, asserted where they live. The path first: a macro
reading a data file resolves it against the directory of the source file the
form is written in, and here that file is an origin the editor sent rather than
anything on a command line — assets/edn/tuning.edn sits beside
programs/edn-provide.flan and nowhere near the process's own directory, so an
expansion that answered at all read the right file. Nothing is cached but the
macro module, which holds the macro's code and not the data, so editing the
.edn and expanding again is the loop.

Then that the answer is readable, which is the point of generating code a
person can look at rather than the smallest code there is: the struct with a
type per field, the nested struct named for the path that reaches it, and the
reader's dispatch on a key onto a field. Substrings and not a golden copy — the
expansion is some hundreds of characters and a full one would fail on every
comment reflowed in the derivation.

@x86 matches on the generated reader and @sanitize is clean over it. The x86
run is the one worth naming: the set became a (Map [2 i64] bool), and a
fixed-array key is a hash and equality pair the backend emits, which nothing
generated had asked it for before.
This commit is contained in:
Joseph Ferano 2026-09-19 06:26:33 +07:00
parent a5a77867f9
commit 76f23fc68b

View File

@ -723,6 +723,55 @@ let () =
| exception Loc.Error { Loc.dmsg = m; _ } ->
fail "a session that refused an expansion could not expand afterwards: %s" m);
(* ── A type provider, expanded ─────────────────────────────────────
Two claims, and they are the two halves of the live-tuning loop.
The first is the path. A macro that reads a data file resolves it the way
(embed "...") does against the directory of the source file the *form*
is written in and a macro cannot know where that is, because a Form
carries no location. The compiler pokes the call site's directory in
before every expansion, and the call site here is an origin the editor
sent, not a file on a command line. "assets/edn/tuning.edn" is beside
programs/edn-provide.flan and nowhere near this process's directory, so an
expansion that answered anything at all read the right file.
The second is that the answer is readable. `C-c C-m` over a provider is
the only way to see what it decided, and a provider whose output nobody
can look at is a plugin. So this asserts on text a person would recognise:
the struct with its fields and derived types, the nested struct named for
its path, and the reader's dispatch on a key. Asserted as substrings
rather than in full the expansion is some hundreds of characters and a
golden copy of it would fail on every comment reflowed in the derivation.
It also re-reads on every expansion, which is what makes editing the .edn
and hitting C-c C-m a loop: nothing is cached but the macro module, and
that holds the macro's code, not the data. *)
(let pt, _ = Session.create ~file:"programs/edn-provide.flan" () in
match
Session.macroexpand ~origin:"programs/edn-provide.flan" ~all:false pt
"(edn/defedn Tuning \"assets/edn/tuning.edn\")"
with
| x ->
let got = Form.to_source x.Session.xafter in
List.iter
(fun want ->
if not (has got want) then
fail "expanding a defedn: %S is not in\n%s" want got)
[ (* The struct, with a type per field derived from the value. *)
"(defstruct Tuning [name string hp i64 speed f64 boss? bool";
(* The vector, and the constructor that states its type so that
(vec-new) has something to take it from. *)
"drops (Vec i64)";
(* The nested map, named for the path that reaches it, and the one
nested inside that. *)
"(defstruct Tuning-hitbox-offset [x i64 y i64])";
"hitbox Tuning-hitbox";
(* And the reader, dispatching on a key onto a field. *)
"(edn/keyword=? k \"speed\")";
"(set (.speed out) (edn/need-float c))" ]
| exception Loc.Error { Loc.dmsg = m; _ } ->
fail "expanding a defedn through a session: %s" m);
(* A form typed into a file that is *imported as a package* has to be
qualified the way the import qualified it, or it splices as a brand-new
unrelated name: the evaluation reports success and the running program