ocaml: phase 4 'arr.(i)' and 'arr.(i) <- v' array indexing (+3 tests, 515 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s

parse-atom-postfix's '.()' branch now disambiguates between let-open
and array-get based on whether the head is a module path (':con' or
':field' chain rooted in ':con'). Module paths still emit
(:let-open M EXPR); everything else emits (:array-get ARR I).

Eval handles :array-get by reading the cell's underlying list at
index. The '<-' assignment handler now also accepts :array-get lhs
and rewrites the cell with one position changed.

Idiomatic OCaml array code now works:

  let a = Array.make 5 0 in
  for i = 0 to 4 do a.(i) <- i * i done;
  a.(3) + a.(4)               = 25

  let a = Array.init 4 (fun i -> i + 1) in
  a.(0) + a.(1) + a.(2) + a.(3)  = 10

  List.(length [1;2;3])         = 3   (* unchanged: List is a module *)
This commit is contained in:
2026-05-09 02:08:21 +00:00
parent 1ed3216ba6
commit 073588812a
4 changed files with 60 additions and 1 deletions

View File

@@ -490,6 +490,22 @@
(let ((target (ocaml-eval (nth lhs-ast 1) env))
(fname (nth lhs-ast 2)))
(begin (dict-set! target fname new-val) nil)))
((= (ocaml-tag-of lhs-ast) "array-get")
;; (:array-get ARR I) <- v : rewrite the underlying
;; list in the ref cell with one cell changed.
(let ((arr (ocaml-eval (nth lhs-ast 1) env))
(i (ocaml-eval (nth lhs-ast 2) env)))
(begin
(define replace
(fn (lst k)
(cond
((= lst (list)) (list))
((= k 0) (cons new-val (rest lst)))
(else
(cons (first lst)
(replace (rest lst) (- k 1)))))))
(set-nth! arr 0 (replace (nth arr 0) i))
nil)))
(else
(error
(str "ocaml-eval: <- expects a field-access lhs, got "
@@ -602,6 +618,11 @@
(let ((s (ocaml-eval (nth ast 1) env))
(i (ocaml-eval (nth ast 2) env)))
(nth s i)))
((= tag "array-get")
;; (:array-get ARR I) — Array.get on a ref-of-list.
(let ((arr (ocaml-eval (nth ast 1) env))
(i (ocaml-eval (nth ast 2) env)))
(nth (nth arr 0) i)))
((= tag "for")
;; (:for NAME LO HI DIR BODY) — DIR is "ascend" or "descend".
(let ((name (nth ast 1))