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:
@@ -790,46 +790,51 @@
|
||||
((at-kw? "module") nil)
|
||||
((at-kw? "open") nil)
|
||||
((at-kw? "include") nil)
|
||||
((at-kw? "and") nil)
|
||||
(else (begin (advance-tok!) (skip-to-boundary!))))))
|
||||
(define
|
||||
parse-decl-let
|
||||
(fn
|
||||
()
|
||||
(fn ()
|
||||
(advance-tok!)
|
||||
(let
|
||||
((reccy false))
|
||||
(let ((reccy false) (bindings (list)))
|
||||
(begin
|
||||
(when
|
||||
(at-kw? "rec")
|
||||
(begin (advance-tok!) (set! reccy true)))
|
||||
(let
|
||||
((name (ocaml-tok-value (consume! "ident" nil)))
|
||||
(params (list)))
|
||||
(begin
|
||||
(define
|
||||
collect-params
|
||||
(fn
|
||||
()
|
||||
(when
|
||||
(check-tok? "ident" nil)
|
||||
(begin
|
||||
(append! params (ocaml-tok-value (peek-tok)))
|
||||
(advance-tok!)
|
||||
(collect-params)))))
|
||||
(collect-params)
|
||||
(consume! "op" "=")
|
||||
(let
|
||||
((expr-start (cur-pos)))
|
||||
(when (at-kw? "rec") (begin (advance-tok!) (set! reccy true)))
|
||||
(define parse-one!
|
||||
(fn ()
|
||||
(let ((nm (ocaml-tok-value (consume! "ident" nil)))
|
||||
(ps (list)))
|
||||
(begin
|
||||
(skip-to-boundary!)
|
||||
(let
|
||||
((expr-src (slice src expr-start (cur-pos))))
|
||||
(let
|
||||
((expr (ocaml-parse expr-src)))
|
||||
(if
|
||||
reccy
|
||||
(list :def-rec name params expr)
|
||||
(list :def name params expr))))))))))))
|
||||
(define collect-params
|
||||
(fn ()
|
||||
(when (check-tok? "ident" nil)
|
||||
(begin
|
||||
(append! ps (ocaml-tok-value (peek-tok)))
|
||||
(advance-tok!)
|
||||
(collect-params)))))
|
||||
(collect-params)
|
||||
(consume! "op" "=")
|
||||
(let ((expr-start (cur-pos)))
|
||||
(begin
|
||||
(skip-to-boundary!)
|
||||
(let ((expr-src (slice src expr-start (cur-pos))))
|
||||
(let ((expr (ocaml-parse expr-src)))
|
||||
(append! bindings (list nm ps expr))))))))))
|
||||
(parse-one!)
|
||||
(define more
|
||||
(fn ()
|
||||
(when (at-kw? "and")
|
||||
(begin (advance-tok!) (parse-one!) (more)))))
|
||||
(more)
|
||||
(cond
|
||||
((= (len bindings) 1)
|
||||
(let ((b (first bindings)))
|
||||
(if reccy
|
||||
(list :def-rec (nth b 0) (nth b 1) (nth b 2))
|
||||
(list :def (nth b 0) (nth b 1) (nth b 2)))))
|
||||
(else
|
||||
(if reccy
|
||||
(list :def-rec-mut bindings)
|
||||
(list :def-mut bindings))))))))
|
||||
(define
|
||||
parse-decl-expr
|
||||
(fn
|
||||
|
||||
Reference in New Issue
Block a user