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
|
|
@ -21,8 +21,18 @@ function vis_allowed(d: Node, from: pointer) -> bool {
|
|||
return module_is_friend(from)
|
||||
}
|
||||
# `what` is the name as written at the reference
|
||||
function vis_check(d: Node, what: pointer) -> void {
|
||||
# a generic function's instance is named for its type arguments (grow$int); a message names grow
|
||||
function vis_plain(what: pointer) -> pointer {
|
||||
var i = 0
|
||||
while i < len(what) {
|
||||
if what[i] == '$' { return what[0 .. i] }
|
||||
i += 1
|
||||
}
|
||||
return what
|
||||
}
|
||||
function vis_check(d: Node, what0: pointer) -> void {
|
||||
if d == null { return }
|
||||
let what = vis_plain(what0)
|
||||
var here = g_err_file
|
||||
if here == null { return }
|
||||
let from = module_of(here)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue