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:
parent
57b66bdf47
commit
6a24b14f0e
26 changed files with 61796 additions and 51949 deletions
|
|
@ -48,6 +48,7 @@ function ck_args(e: Node, name: pointer, labels: []pointer, tys: []pointer) -> v
|
|||
if n != len(tys) { ck_err("arity", e, `{name} takes {itoa(len(tys))} argument(s) and this call gives {itoa(n)}`) }
|
||||
var i = 0
|
||||
while i < n {
|
||||
if i < len(tys) { ck_expect = tys[i] }
|
||||
let at = ck_expr(e.kids[i])
|
||||
if i < len(tys) { ck_give(tys[i], at, e.kids[i], `argument {itoa(i + 1)} of {name}`) }
|
||||
i += 1
|
||||
|
|
@ -126,6 +127,8 @@ function ck_call_named(e: Node, name: pointer) -> pointer {
|
|||
if bt != null { return bt }
|
||||
let f = ck_fn(name)
|
||||
if f != null { return ck_call_fn(e, name, f) }
|
||||
let gt = gen_template(g_gen_fns, name)
|
||||
if gt != null { return gen_call(e, name, gt) }
|
||||
let x = ck_extern(name)
|
||||
if x != null { return ck_call_fn(e, name, x) }
|
||||
let g = ck_global(name)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue