apl: named function definitions f ← {…} (+7 tests, 467/467)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s

Parser: apl-collect-fn-bindings pre-scans stmt-groups for
`name ← { ... }` patterns and populates apl-known-fn-names.
is-fn-tok? consults this list; collect-segments-loop emits
(:fn-name nm) for known names so they parse as functions.

Resolver: apl-resolve-{monadic,dyadic} handle :fn-name by
looking up env, asserting the binding is a dfn, returning
a closure that dispatches to apl-call-dfn{-m,}.

Recursion still works: `fact ← {0=⍵:1 ⋄ ⍵×∇⍵-1} ⋄ fact 5` → 120.
This commit is contained in:
2026-05-07 17:33:41 +00:00
parent d9cf00f287
commit b13819c50c
4 changed files with 175 additions and 76 deletions

View File

@@ -429,6 +429,18 @@
((f (apl-resolve-dyadic inner env)))
(fn (arr) (apl-commute f arr))))
(else (error "apl-resolve-monadic: unsupported op")))))
((= tag :fn-name)
(let
((nm (nth fn-node 1)))
(let
((bound (get env nm)))
(if
(and
(list? bound)
(> (len bound) 0)
(= (first bound) :dfn))
(fn (arg) (apl-call-dfn-m bound arg))
(error "apl-resolve-monadic: name not bound to dfn")))))
(else (error "apl-resolve-monadic: unknown fn-node tag"))))))
(define
@@ -452,6 +464,18 @@
((f (apl-resolve-dyadic inner env)))
(fn (a b) (apl-commute-dyadic f a b))))
(else (error "apl-resolve-dyadic: unsupported op")))))
((= tag :fn-name)
(let
((nm (nth fn-node 1)))
(let
((bound (get env nm)))
(if
(and
(list? bound)
(> (len bound) 0)
(= (first bound) :dfn))
(fn (a b) (apl-call-dfn bound a b))
(error "apl-resolve-dyadic: name not bound to dfn")))))
((= tag :outer)
(let
((inner (nth fn-node 2)))