feat(reflect): generic value tree + Reflect.serialize/apply + JSON bridge (#44)
A self-describing Value node (null/int/fixed/bool/str/list/object) with constructors, builders (Value.add/put) and accessors (get/at/count/kind/ as_int/as_str/…). Reflect.serialize(entity) walks an entity's whole component set into a value tree — one member per component, each a sub-object of its fields — and Reflect.apply(entity, value) writes one back; a fixed field becomes a fixed node, everything else an int node, so the round-trip is bit-exact, with the model id under "@kind". Json.encode/parse bridge the tree to and from compact, stable, diffable text, with fixed written as an exact terminating decimal that parses back bit-for-bit (verified across the raw Q16.16 range). Together: a one-call, bit-exact save/load for entities. Written in Ludic and spliced on demand (runtime/native/value.ludic + reflect_io.ludic, like Query/Light), so a program that doesn't touch Value.*/Json.*/Reflect.serialize compiles byte-identically and the C-free bootstrap fixpoint holds (verified). The general tagged-union/any language type stays tracked in #1; this ships the concrete value tree the serializer needs. Adds 21 namespace-method docs pages + Value/Json sections, examples/library/serialize.ludic, and a regression case. Whole CI set green: x test 72/72, x test-tools 30/30, check-impl/vocabulary/docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0d1b09e4f0
commit
9452557f3c
31 changed files with 16753 additions and 14898 deletions
|
|
@ -295,6 +295,36 @@ function emit_ns_call(ns: pointer, meth: pointer, e: Node) -> Val {
|
|||
if (meth == "has") { bare = "world_has"; push(labels, "entity"); push(labels, "prop") }
|
||||
if (meth == "kind") { bare = "world_kind"; push(labels, "entity") }
|
||||
if (meth == "model") { bare = "world_model_id"; push(labels, "name") }
|
||||
# #44 — serialize an entity to a value tree and apply one back (reflect_io.ludic)
|
||||
if (meth == "serialize") { bare = "reflect_serialize"; push(labels, "entity") }
|
||||
if (meth == "apply") { bare = "reflect_apply"; push(labels, "entity"); push(labels, "value") }
|
||||
}
|
||||
# Value.* — the generic value tree (runtime/native/value.ludic, spliced on
|
||||
# demand). Nodes are int/fixed/bool/str/list/object; the methods map straight
|
||||
# to the spliced value_* functions, whose signatures carry the return types.
|
||||
if (ns == "Value") {
|
||||
if (meth == "null") { bare = "value_null" }
|
||||
if (meth == "int") { bare = "value_int"; push(labels, "n") }
|
||||
if (meth == "fixed") { bare = "value_fixed"; push(labels, "f") }
|
||||
if (meth == "bool") { bare = "value_bool"; push(labels, "b") }
|
||||
if (meth == "str") { bare = "value_str"; push(labels, "s") }
|
||||
if (meth == "list") { bare = "value_list" }
|
||||
if (meth == "object") { bare = "value_object" }
|
||||
if (meth == "add") { bare = "value_add"; push(labels, "list"); push(labels, "item") }
|
||||
if (meth == "put") { bare = "value_put"; push(labels, "obj"); push(labels, "key"); push(labels, "item") }
|
||||
if (meth == "get") { bare = "value_get"; push(labels, "obj"); push(labels, "key") }
|
||||
if (meth == "has") { bare = "value_has"; push(labels, "obj"); push(labels, "key") }
|
||||
if (meth == "at") { bare = "value_at"; push(labels, "list"); push(labels, "index") }
|
||||
if (meth == "key_at") { bare = "value_key_at"; push(labels, "obj"); push(labels, "index") }
|
||||
if (meth == "count") { bare = "value_count"; push(labels, "value") }
|
||||
if (meth == "kind") { bare = "value_kind"; push(labels, "value") }
|
||||
if (meth == "as_int") { bare = "value_as_int"; push(labels, "value") }
|
||||
if (meth == "as_str") { bare = "value_as_str"; push(labels, "value") }
|
||||
}
|
||||
# Json.* — the text bridge over the value tree (runtime/native/value.ludic).
|
||||
if (ns == "Json") {
|
||||
if (meth == "encode") { bare = "json_encode"; push(labels, "value") }
|
||||
if (meth == "parse") { bare = "json_parse"; push(labels, "text") }
|
||||
}
|
||||
if (bare == null) { perr(`unknown builtin {ns}.{meth}`) }
|
||||
reorder_named(e, labels)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue