feat(lang): packages count under uses; a port of defaults may go unbound

A module that says uses must name every package module it reaches; a
package with no module line is named for its directory (ludic_render3d)
for this rule, so a mechanic reaching into the renderer is caught. Only
the engine's runtime needs no naming. 'module x uses' with nothing after
it reaches no other module. A port whose every member has a default
answers with its defaults when unbound, and 'new' of a port says to bind
it. ludic-dev test runs 'ludic test packages'. Reseed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-25 05:36:11 +03:00
parent e8c1d54a96
commit f4062010e9
15 changed files with 47465 additions and 46516 deletions

View file

@ -131,8 +131,13 @@ fishing/land.ludic:4: error: fishing uses items.inv_add (items/index.ludic:3): a
- A module with no `uses` clause keeps the rule before it - anything exported - so the rule can be
switched on one module at a time. Two module lines for one module add their lists together.
- A file in no module (the program's root, the runtime) is unaffected either way, and a package's
module (found through `ludic_modules` or the toolchain, such as `ludic_ui`) is always usable.
- A package's module counts like any other: a mechanic that says `uses ludic_base` and calls
into `ludic_inventory`, `ludic_ui` or the renderer is refused. A package with no `module` line
of its own (`ludic.render3d`) is named for its directory - `ludic_render3d` - for this rule; its
names stay public to the export rule. Only the engine's own runtime - `Value`, `Json`,
`Random` and the rest, which is in no module and no package - needs no naming.
- A file in no module (the program's root) is unaffected either way.
- `module ludic_base uses` with nothing after it is a module that reaches no other module at all.
- A friend of a module (`friend module lab`, or `friend module lab of fishing`) is not held to its
`uses` for that module.
- The declared graph may not go round: `module a uses b` beside `module b uses a` is refused
@ -176,7 +181,9 @@ app.ludic:9: error: port Clock has no member later
```
and a member of the wrong type is a type error like any other (`field now of Clock_port wants a
fn()->int and this is a fn(int)->float`). A port nobody uses may stay unbound.
fn()->int and this is a fn(int)->float`). A port nobody uses may stay unbound, and so may a port
whose every member has a default: unbound, it answers with its defaults - which is how a
package's fallbacks ("unbound: this machine runs the world") are written.
### Types are checked before anything is emitted