ocaml: phase 1+2 records {x=1;y=2} + with-update (+6 tests, 289 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: { f = e; f = e; ... } -> (:record (F E)...). { base with f = e;
... } -> (:record-update BASE (F E)...). Eval builds a dict from field
bindings; record-update merges the new fields over the base dict — the
same dict representation already used for modules.
{ also added to at-app-start? so records are valid arg atoms. Field
access via the existing :field postfix unifies record/module access.
Record patterns deferred to a later iteration.
This commit is contained in:
@@ -381,6 +381,37 @@
|
||||
;; matches its argument against the clauses.
|
||||
(let ((clauses (nth ast 1)) (captured env))
|
||||
(fn (arg) (ocaml-match-clauses arg clauses captured))))
|
||||
((= tag "record")
|
||||
(let ((fields (rest ast)) (result {}))
|
||||
(begin
|
||||
(define loop
|
||||
(fn (xs)
|
||||
(when (not (= xs (list)))
|
||||
(let ((kv (first xs)))
|
||||
(let ((k (first kv)) (v (ocaml-eval (nth kv 1) env)))
|
||||
(begin
|
||||
(set! result (merge result (dict k v)))
|
||||
(loop (rest xs))))))))
|
||||
(loop fields)
|
||||
result)))
|
||||
((= tag "record-update")
|
||||
(let ((base-ast (nth ast 1)) (fields (rest (rest ast))))
|
||||
(let ((base (ocaml-eval base-ast env)))
|
||||
(cond
|
||||
((dict? base)
|
||||
(let ((result base))
|
||||
(begin
|
||||
(define loop
|
||||
(fn (xs)
|
||||
(when (not (= xs (list)))
|
||||
(let ((kv (first xs)))
|
||||
(let ((k (first kv)) (v (ocaml-eval (nth kv 1) env)))
|
||||
(begin
|
||||
(set! result (merge result (dict k v)))
|
||||
(loop (rest xs))))))))
|
||||
(loop fields)
|
||||
result)))
|
||||
(else (error (str "ocaml-eval: with-update on non-record: " base)))))))
|
||||
((= tag "field")
|
||||
;; `e.name` — evaluate e, expect a dict (record/module), get name.
|
||||
;; Special case: `(:field (:con "M") "x")` looks up M as a module
|
||||
|
||||
Reference in New Issue
Block a user