@PerMap and @Chunked(n) registries: rows read per map, a state and verbs written, every map checked

- @PerMap registry R of T from "file.lres" reads <maps root>/<map>/file.lres at run time
  (package.ludic's new `maps` line, default assets/maps); @Chunked(n) one file per chunk,
  {cx}/{cz} in its name. No as PREFIX, no constants, no def, never open.
- permap_gen: state R, r_load/_clear/_find/_path; chunked: RChunk, r_in/_out/_slot/_find/
  _clear/_path; a typed reset and fill per record over lres.ludic, rows, lists and list
  records pooled per table / chunk slot, @alloc_ok on what grows at high water.
- permap_consts: lres_consts__(), the program's int and float constants by name.
- permap_check: ludicc --check reads every map directory (fields, types, constants, fn,
  @OneOf/@Range/@Ref, cross-row @Ref keys in the same map, a key twice); --no-maps skips.
- @Ref(PerMapTable) is refused on a non-string field; the schema says scope/chunk per
  registry and scope map on such a Ref, and lists the canonical @Unit spellings; any other
  @Unit spelling is a warning naming the canonical one.
- reseeded (mac + win seeds; bootstrap-cfree out.ll == seed.ll).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 21:03:02 +03:00
parent 7170c31304
commit 2f4860ae71
14 changed files with 137400 additions and 100393 deletions

View file

@ -1007,6 +1007,11 @@ function parse_one_decl() -> void {
else if a == "Namespace" { eat_op("("); ns_name = eat_id(); eat_op(")") } # @Namespace(Name) package Foo.* namespace (#62)
else if a == "deterministic" { is_det = true }
else if (a == "AppendOnly") or (a == "ByKey") { at_decl(a) } # a registry's, for editors (attrs.ludic)
else if a == "PerMap" { # a map-scoped registry (permap.ludic)
at_decl(a)
g_pm_pending = true
}
else if a == "Chunked" { pm_parse_chunked() } # @Chunked(64): read a chunk at a time
else if a == "alloc_ok" { # 25.2: @alloc_ok("why") - this allocates in a frame on purpose
eat_op("(")
let why = expr()
@ -1046,12 +1051,18 @@ function parse_one_decl() -> void {
g_at_keep = true
let p0 = len(prog)
let e0 = len(g_events)
let r0 = len(g_rg_var)
parse_one_decl()
var k = p0
while k < len(prog) {
prog[k].vis = 1
k += 1
}
k = r0
while k < len(g_rg_var) { # a @PerMap registry's own node is not in prog
g_rg_var[k].vis = 1
k += 1
}
k = e0
while k < len(g_events) {
g_events[k].vis = 1
@ -1530,6 +1541,12 @@ function maybe_splice_runtime() -> void {
do_import("runtime/native/udp.ludic")
cur_dir = saved
}
# a @PerMap registry: the .lres reader its generated fill calls (permap.ludic)
if g_pm_any {
cur_dir = ""
do_import("runtime/native/lres.ludic")
cur_dir = saved
}
# Process.*: splice the child-process library. Spawning is native (process.ll /
# process_win.ll); the argv array and the Windows command line are built in Ludic.
if g_uses_process {