feat(lang): L5 generic records and functions

property Pool<T> { ... }, function first<T>(xs: []T) -> T, map<T, U> over fn
types; a type writes an instance as Pool<Thing>, nested as deep as needed. The
parser names an instance Pool$Thing and remembers its generic and arguments; the
checker takes the generic declarations out, infers a call's type arguments from
its arguments or its result's declared slot, and makes each instance once as an
ordinary record or function, checked like any other. Errors print Pool<Thing>.
An instance keeps its generic's module and export (L3). ludic-fmt keeps type
arguments together while spacing comparisons and shifts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-24 02:21:09 +03:00
parent 57b66bdf47
commit 6a24b14f0e
26 changed files with 61796 additions and 51949 deletions

View file

@ -18,6 +18,7 @@ function selfhost_frags() -> []pointer {
push(f, "selfhost/frontend/lex.ludic")
push(f, "selfhost/frontend/parse.ludic")
push(f, "selfhost/frontend/parse_game.ludic")
push(f, "selfhost/frontend/generics.ludic")
push(f, "selfhost/backend/emit_core.ludic")
push(f, "selfhost/backend/emit_head.ludic")
push(f, "selfhost/backend/emit_addr.ludic")
@ -62,6 +63,8 @@ function selfhost_frags() -> []pointer {
push(f, "selfhost/check/check_ops.ludic")
push(f, "selfhost/check/check_call.ludic")
push(f, "selfhost/check/check_stmt.ludic")
push(f, "selfhost/check/check_gen.ludic")
push(f, "selfhost/check/check_gen_call.ludic")
push(f, "selfhost/backend/emit_stmt.ludic")
push(f, "selfhost/backend/game/emit_ecs.ludic")
push(f, "selfhost/backend/game/emit_query.ludic")