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
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:
@@ -574,6 +574,16 @@
|
||||
;; `(:field (:field M "x") "y")`.
|
||||
(let ((head (parse-atom)))
|
||||
(begin
|
||||
;; Module-path detector: head is :con, or :field chain
|
||||
;; whose innermost subject is :con. Used to choose between
|
||||
;; (:let-open M EXPR) and (:array-get ARR I) after `.(`.
|
||||
(define is-module-path?
|
||||
(fn (h)
|
||||
(cond
|
||||
((not (list? h)) false)
|
||||
((= (first h) "con") true)
|
||||
((= (first h) "field") (is-module-path? (nth h 1)))
|
||||
(else false))))
|
||||
(define loop
|
||||
(fn ()
|
||||
(when (at-op? ".")
|
||||
@@ -586,7 +596,10 @@
|
||||
(let ((inner (parse-expr)))
|
||||
(begin
|
||||
(consume! "op" ")")
|
||||
(set! head (list :let-open head inner))
|
||||
(set! head
|
||||
(if (is-module-path? head)
|
||||
(list :let-open head inner)
|
||||
(list :array-get head inner)))
|
||||
(loop)))))
|
||||
((at-op? "[")
|
||||
(begin
|
||||
|
||||
Reference in New Issue
Block a user