ocaml: phase 2 for/while loops (+5 tests, 194 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 52s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 52s
Parser: for i = lo to|downto hi do body done, while cond do body done. AST: (:for NAME LO HI :ascend|:descend BODY) and (:while COND BODY). Eval re-binds the loop var per iteration; both forms evaluate to unit.
This commit is contained in:
@@ -300,6 +300,51 @@
|
||||
(fn-val arg-val))))))
|
||||
((= tag "match")
|
||||
(ocaml-match-eval (nth ast 1) (nth ast 2) env))
|
||||
((= tag "for")
|
||||
;; (:for NAME LO HI DIR BODY) — DIR is "ascend" or "descend".
|
||||
(let ((name (nth ast 1))
|
||||
(lo (ocaml-eval (nth ast 2) env))
|
||||
(hi (ocaml-eval (nth ast 3) env))
|
||||
(dir (nth ast 4))
|
||||
(body (nth ast 5)))
|
||||
(begin
|
||||
(cond
|
||||
((= dir "ascend")
|
||||
(let ((i lo))
|
||||
(begin
|
||||
(define loop
|
||||
(fn ()
|
||||
(when (<= i hi)
|
||||
(begin
|
||||
(ocaml-eval body
|
||||
(ocaml-env-extend env name i))
|
||||
(set! i (+ i 1))
|
||||
(loop)))))
|
||||
(loop))))
|
||||
((= dir "descend")
|
||||
(let ((i lo))
|
||||
(begin
|
||||
(define loop
|
||||
(fn ()
|
||||
(when (>= i hi)
|
||||
(begin
|
||||
(ocaml-eval body
|
||||
(ocaml-env-extend env name i))
|
||||
(set! i (- i 1))
|
||||
(loop)))))
|
||||
(loop)))))
|
||||
nil)))
|
||||
((= tag "while")
|
||||
(let ((cond-ast (nth ast 1)) (body (nth ast 2)))
|
||||
(begin
|
||||
(define loop
|
||||
(fn ()
|
||||
(when (ocaml-eval cond-ast env)
|
||||
(begin
|
||||
(ocaml-eval body env)
|
||||
(loop)))))
|
||||
(loop)
|
||||
nil)))
|
||||
((= tag "let")
|
||||
(let ((name (nth ast 1)) (params (nth ast 2))
|
||||
(rhs (nth ast 3)) (body (nth ast 4)))
|
||||
|
||||
Reference in New Issue
Block a user