feat(lang): L8 registries by declaration - registry and def

registry NAME of RECORD [as PREFIX] is a global table; def NAME key { ... } in
any file is one entry, collected in source order and filled before any code
runs. Each entry gets an index constant (PREFIX_KEY), the table PREFIX_COUNT,
and a record with a key field gets it filled and a NAME_find(key). A record
literal naming a field its record lacks is now an error everywhere; a global's
initializer is lowered as its own file's code (its errors, and what its module
may see, were whichever statement came last).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-24 13:34:51 +03:00
parent b0b0b62bce
commit 7e7f3ab297
15 changed files with 48231 additions and 44362 deletions

View file

@ -215,6 +215,37 @@ way in its own files. What is still built into the compiler is the namespaces th
`Math`, `Text`, `List`, `Vector`, `Color`, `Time`, `Date` - and the few methods that choose their
target by an argument's type (`Audio.play` of a handle or a name).
### Registries (`registry`, `def`)
A table of records that code used to fill with calls in an init function is declared instead:
```ludic
program Camp {
property Furnishing {
key: string = ""
name: string = ""
cost: int = 0
}
registry Furnishings of Furnishing as HF
def Furnishings chair { name: "Camp chair", cost: 60 }
def Furnishings crate { name: "Crate", cost: 30 }
entry { print(Furnishings[HF_CRATE].cost + HF_COUNT) }
}
```
`registry NAME of RECORD [as PREFIX]` is a global `[]RECORD`, and every `def NAME key { ... }` is one
entry of it - in any file, collected in source order, and in the table before any code runs. Each
entry gets an index constant, `PREFIX_KEY` (the prefix defaults to the registry's name in capitals),
in declaration order, and the registry a count, `PREFIX_COUNT`. When the record has a `key: string`
field it is filled with the entry's key, and `name_find(key)` (the registry's name in lower case)
returns its index or -1. A def's fields are checked against the record like any record literal, a
key is declared once, and `export registry` exports the table, its constants and its lookup.
Because the index is the order of the defs, a table stored by position - a save, a setting - keeps
the rule it always had: add an entry at the end, never between two. The order is the order the
compiler reads them in, and an `import` is read where it stands: a file's imported defs come before
the defs written after the import line.
### Memory is safe unless it says `unsafe`
The typed buffers are slices: `words(n)`, `floats(n)`, `fixeds(n)`, `doubles(n)` and