ludic schema: a components section and a natives list (R4)

Each UI component: module, place, doc, xml and lss paths, props and state
(type, default as written, place, doc), states_read (the header's states),
derived fields with their types, functions and events as the template calls
them (states and instance stripped), and the native tags its template uses.
natives: every ui_native / ui_native_input call with a literal tag - tag, via,
handler, place. schema_version stays 1; the lists are additions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 19:36:04 +03:00
parent 28f7b4666b
commit 281ebc23e1
11 changed files with 80436 additions and 71227 deletions

View file

@ -90,6 +90,7 @@ function selfhost_frags() -> []pointer {
push(f, "selfhost/backend/emit_fnval.ludic")
push(f, "selfhost/backend/emit_vis.ludic")
push(f, "selfhost/backend/emit_schema.ludic")
push(f, "selfhost/backend/emit_schema_ui.ludic")
push(f, "selfhost/backend/emit_schema_hash.ludic")
push(f, "selfhost/check/check_state.ludic")
push(f, "selfhost/check/check_index.ludic")

View file

@ -1240,6 +1240,12 @@ function cmd_dev_test() -> int {
schema_case("lang/attributes", "\"fn_type\": \"fn(Tool,int)->float\", \"params\": [\"Tool\", \"int\"]", "--emit-schema: a function with arguments, its fn_type spelled as a field's")
schema_case("lang/attributes", "{\"name\": \"Node\", \"args\": [\"tool\"]}", "--emit-schema: @Node and the field it reads its model from")
schema_case("lang/attributes", "{\"name\": \"Ref\", \"args\": [\"Items\"], \"unresolved\": true}", "--emit-schema: an attribute whose target the program lacks is marked unresolved, not refused")
schema_case("library/ui_component", "{\"name\": \"step\", \"type\": \"int\", \"default\": \"1\", \"file\": \"examples/library/ui_component_parts/Counter.ludic\", \"line\": 4, \"col\": 3, \"attributes\": [], \"doc\": \"how much one press adds\"}", "--emit-schema: a component's prop, with its default, place and doc")
schema_case("library/ui_component", "\"xml\": \"examples/library/ui_component_parts/Counter.xml\", \"lss\": \"examples/library/ui_component_parts/Counter.lss\"", "--emit-schema: a component's template and stylesheet")
schema_case("state/component", "\"states_read\": [\"Score\", \"Look\"]", "--emit-schema: the states a component's header names, apart from its model")
schema_case("state/component", "{\"name\": \"add\", \"params\": [[\"n\", \"int\"]], \"line\": 8}", "--emit-schema: a component's event as the template calls it, its states and instance stripped")
schema_case("library/ui_pointer", "{\"tag\": \"chartmap\", \"via\": \"ui_native_input\", \"handler\": \"map_input\", \"module\": null, \"file\": \"examples/library/ui_pointer.ludic\", \"line\": 35, \"col\": 5}", "--emit-schema: a native tag registered by a literal, and its handler")
schema_case("library/ui_pointer", "\"natives\": [\"chartmap\"]}", "--emit-schema: the native tags a component's template uses")
reject_case("rejected/registry_twice", "def Furnishings crate is declared twice", "a registry's key is declared once")
reject_case("rejected/registry_field", "Furnishing has no field colour", "a def's fields are the record's")
feat_case("modules/open_registry", "", "clock animals weather / 2 2 3", "open_registry.ludic (L8+L3: an open registry takes other modules' defs; its own entries first, then by module name)")