haskell: classic program fib.hs + source-order top-level binding (+2 tests, 388/388)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
This commit is contained in:
@@ -677,16 +677,22 @@ plus a b = a + b
|
||||
hk-bind-decls!
|
||||
(fn
|
||||
(env decls)
|
||||
(let ((groups (dict)) (pat-binds (list)))
|
||||
;; Pass 1: collect fun-clause groups by name; collect pat-binds
|
||||
;; in source order. Pre-seed env so any name can already be
|
||||
;; looked up by closures built in pass 2.
|
||||
(let
|
||||
((groups (dict))
|
||||
(group-order (list))
|
||||
(pat-binds (list)))
|
||||
;; Pass 1: collect fun-clause groups by name; track first-seen
|
||||
;; order so pass 3 can evaluate 0-arity bodies in source order
|
||||
;; (forward references to other 0-arity definitions still need
|
||||
;; the earlier name to be bound first).
|
||||
(for-each
|
||||
(fn (d)
|
||||
(cond
|
||||
((= (first d) "fun-clause")
|
||||
(let
|
||||
((name (nth d 1)))
|
||||
(when (not (has-key? groups name))
|
||||
(append! group-order name))
|
||||
(dict-set!
|
||||
groups
|
||||
name
|
||||
@@ -703,8 +709,9 @@ plus a b = a + b
|
||||
(append! pat-binds d))
|
||||
(:else nil)))
|
||||
decls)
|
||||
;; Pass 2: install multifuns for arity > 0; mark 0-arity for
|
||||
;; pass 3. The mutable env means recursive references work.
|
||||
;; Pass 2: install multifuns (arity > 0) — order doesn't matter
|
||||
;; because they're closures; collect 0-arity names in source
|
||||
;; order for pass 3.
|
||||
(let ((zero-arity (list)))
|
||||
(for-each
|
||||
(fn (name)
|
||||
@@ -717,8 +724,11 @@ plus a b = a + b
|
||||
name
|
||||
(hk-mk-multifun arity clauses env)))
|
||||
(:else (append! zero-arity name))))))
|
||||
(keys groups))
|
||||
;; Pass 3: evaluate 0-arity bodies and pat-binds.
|
||||
group-order)
|
||||
;; Pass 3: evaluate 0-arity bodies and pat-binds in source
|
||||
;; order — forward references to a later 0-arity name will
|
||||
;; still see its placeholder (nil) and fail noisily, but the
|
||||
;; common case of a top-down program works.
|
||||
(for-each
|
||||
(fn (name)
|
||||
(let ((clauses (get groups name)))
|
||||
|
||||
Reference in New Issue
Block a user