ocaml: phase 2 let..and.. mutual recursion (+3 tests, 251 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 51s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 51s
Parser collects multiple bindings via 'and', emitting (:def-rec-mut BINDINGS) for let-rec chains and (:def-mut BINDINGS) for non-rec. Single bindings keep the existing (:def …) / (:def-rec …) shapes. Eval (def-rec-mut): allocate placeholder cell per binding, build joint env where each name forwards through its cell, then evaluate each rhs against the joint env and fill the cells. Even/odd mutual-rec works.
This commit is contained in:
@@ -647,6 +647,60 @@
|
||||
(begin
|
||||
(set! env (ocaml-env-extend env name v))
|
||||
(set! last v))))))))
|
||||
((= tag "def-mut")
|
||||
;; let x = ... and y = ... — non-recursive; each rhs is
|
||||
;; evaluated in the parent env, then all names bind in
|
||||
;; sequence.
|
||||
(let ((bs (nth decl 1)))
|
||||
(begin
|
||||
(define run-one
|
||||
(fn (b)
|
||||
(let ((nm (nth b 0)) (ps (nth b 1)) (rh (nth b 2)))
|
||||
(let ((v (if (= (len ps) 0)
|
||||
(ocaml-eval rh env)
|
||||
(ocaml-make-curried ps rh env))))
|
||||
(begin
|
||||
(set! env (ocaml-env-extend env nm v))
|
||||
(set! last v))))))
|
||||
(define loop
|
||||
(fn (xs)
|
||||
(when (not (= xs (list)))
|
||||
(begin (run-one (first xs)) (loop (rest xs))))))
|
||||
(loop bs))))
|
||||
((= tag "def-rec-mut")
|
||||
;; let rec f = ... and g = ... — mutually recursive;
|
||||
;; bind all names with placeholder cells first, then
|
||||
;; evaluate each rhs in the joint env, finally fill cells.
|
||||
(let ((bs (nth decl 1)) (cells (list)) (env2 env))
|
||||
(begin
|
||||
(define alloc
|
||||
(fn (xs)
|
||||
(when (not (= xs (list)))
|
||||
(let ((b (first xs)))
|
||||
(let ((c (list nil)) (nm (nth b 0)))
|
||||
(begin
|
||||
(append! cells c)
|
||||
(set! env2 (ocaml-env-extend env2 nm
|
||||
(fn (a) ((nth c 0) a))))
|
||||
(alloc (rest xs))))))))
|
||||
(alloc bs)
|
||||
(let ((idx 0))
|
||||
(begin
|
||||
(define fill
|
||||
(fn (xs)
|
||||
(when (not (= xs (list)))
|
||||
(let ((b (first xs)))
|
||||
(let ((nm (nth b 0)) (ps (nth b 1)) (rh (nth b 2)))
|
||||
(let ((v (if (= (len ps) 0)
|
||||
(ocaml-eval rh env2)
|
||||
(ocaml-make-curried ps rh env2))))
|
||||
(begin
|
||||
(set-nth! (nth cells idx) 0 v)
|
||||
(set! idx (+ idx 1))
|
||||
(set! last v)
|
||||
(fill (rest xs)))))))))
|
||||
(fill bs)
|
||||
(set! env env2))))))
|
||||
((= tag "expr")
|
||||
(set! last (ocaml-eval (nth decl 1) env)))
|
||||
((= tag "module-def")
|
||||
|
||||
Reference in New Issue
Block a user