feat(lang): open registry - other modules' defs, in an order imports cannot change

A def from another module into a registry that is not open is refused,
and defs go through visibility (the registry exported, its module in the
definer's uses). Index order: the declaring module's entries, then the
other modules' by module name, each in reading order. A registry entry
is emitted as its own file's code, so what it names is seen from its
own module. Reseed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-25 04:28:34 +03:00
parent 05b09b4c98
commit 6cfaaf0bf9
19 changed files with 49801 additions and 47689 deletions

View file

@ -0,0 +1,17 @@
# open_registry.ludic — L8 + L3: `export open registry Systems of System` takes defs from other
# modules. The index order is the declaring module's entries, then every other module's by module
# name - alpha before zeta, although zeta is imported first - so it never depends on import order.
#
# Running it prints: clock animals weather / 2 2 3
import "reg/core"
import "reg/zeta"
import "reg/alpha"
program OpenRegistry {
entry {
var out = ""
for i in 0 .. SY_COUNT { out = out + Systems[i].key + " " }
let s = Systems[SY_ANIMALS]
let w = Systems[SY_WEATHER]
print(`{out}/ {s.run()} {SY_WEATHER} {w.run()}`)
}
}

View file

@ -0,0 +1,6 @@
# alpha/index.ludic - another module's entry
module alpha uses core
def Systems animals { run: fn animals_run }
function animals_run() -> int {
return 2
}

View file

@ -0,0 +1,11 @@
# core/index.ludic - declares the registry other modules add to, and its own first entry
module core
export property System {
key: string = ""
run: fn() -> int = null
}
export open registry Systems of System as SY
def Systems clock { run: fn clock_run }
function clock_run() -> int {
return 1
}

View file

@ -0,0 +1,6 @@
# zeta/index.ludic - adds an entry to core's open registry; its function stays private to zeta
module zeta uses core
def Systems weather { run: fn weather_run }
function weather_run() -> int {
return 3
}

View file

@ -0,0 +1,7 @@
# closed_kit/index.ludic - a registry that is not open
module kit
export property Tool {
name: string = ""
}
export registry Tools of Tool
def Tools axe { name: "Axe" }

View file

@ -0,0 +1,10 @@
# hidden_kit/index.ludic - open, but not exported: nothing outside kit can name it
module kit
export property Tool {
name: string = ""
}
open registry Tools of Tool
def Tools axe { name: "Axe" }
export function tool_count() -> int {
return TOOLS_COUNT
}

View file

@ -0,0 +1,8 @@
# L8 + L3: only an `open registry` takes defs from another module
import "closed_kit"
program RegistryClosed {
def Tools saw { name: "Saw" }
entry {
print(TOOLS_COUNT)
}
}

View file

@ -0,0 +1,8 @@
# L8 + L3: a def goes through visibility like any reference - the registry must be exported
import "hidden_kit"
program RegistryHidden {
def Tools saw { name: "Saw" }
entry {
print(tool_count())
}
}