@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

@ -64,6 +64,8 @@ function reg_lower(s: pointer) -> pointer {
}
# registry NAME of TYPE [as PREFIX]
function parse_registry() -> void {
let pm = g_pm_pending # @PerMap / @Chunked(n) (permap.ludic)
let chunk = g_pm_chunk_pending
pi += 1
let v = node(N_VAR)
v.s = eat_id()
@ -72,6 +74,7 @@ function parse_registry() -> void {
let t = ptype()
var prefix = reg_upper(v.s)
if is_id("as") {
if pm { perr(`registry {v.s}: a @PerMap registry has no 'as PREFIX' - its keys are not known when the game compiles, so it has no constants; find a row by its key with {pm_snake(v.s)}_find`) }
pi += 1
prefix = eat_id()
}
@ -82,7 +85,7 @@ function parse_registry() -> void {
pi += 1
}
v.ty = "[]" + t
push(prog, v)
if not pm { push(prog, v) } # a map-scoped table is a state, written when the program is read
push(g_rg_name, v.s)
push(g_rg_type, t)
push(g_rg_prefix, prefix)
@ -90,7 +93,8 @@ function parse_registry() -> void {
push(g_rg_open, 0)
push(g_rg_from, from)
push(g_rg_at, at_registry_take()) # attrs.ludic
if from != null { res_read(v, from) }
pm_declared(pm, chunk, v.s)
if from != null and not pm { res_read(v, from) }
}
# def REGISTRY key { field: value, ... }
# def REGISTRY from "file.lres" - every entry of a resource file, as defs of this file's module