ocaml: phase 6 Hashtbl.iter / Hashtbl.fold (+2 tests, 494 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 35s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 35s
New host primitive _hashtbl_to_list returns the entries as a list of
OCaml tuples — ('tuple' k v) form, matching the AST representation
that the pattern-match VM (:ptuple) expects. Without that exact
shape, '(k, v) :: rest' patterns fail to match.
Hashtbl.iter / Hashtbl.fold in runtime walk that list with the user
fn. This closes a long-standing gap: previously Hashtbl was opaque
once values were written (we could only find_opt one key at a time).
let t = Hashtbl.create 4 in
Hashtbl.add t "a" 1; Hashtbl.add t "b" 2; Hashtbl.add t "c" 3;
Hashtbl.fold (fun _ v acc -> acc + v) t 0 = 6
This commit is contained in:
@@ -115,7 +115,23 @@
|
||||
(list "_hashtbl_mem"
|
||||
(fn (t) (fn (k) (has-key? (nth t 0) (str k)))))
|
||||
(list "_hashtbl_length"
|
||||
(fn (t) (len (keys (nth t 0))))))))
|
||||
(fn (t) (len (keys (nth t 0)))))
|
||||
;; _hashtbl_to_list: returns [(k, v); ...] as a list of pairs.
|
||||
;; Keys are returned as the stringified form used internally.
|
||||
(list "_hashtbl_to_list"
|
||||
(fn (t)
|
||||
(let ((d (nth t 0)) (out (list)))
|
||||
(begin
|
||||
(define ks (keys d))
|
||||
(define loop
|
||||
(fn (xs)
|
||||
(when (not (= xs (list)))
|
||||
(begin
|
||||
(append! out
|
||||
(list "tuple" (first xs) (get d (first xs))))
|
||||
(loop (rest xs))))))
|
||||
(loop ks)
|
||||
out)))))))
|
||||
|
||||
(define ocaml-env-lookup
|
||||
(fn (env name)
|
||||
|
||||
@@ -530,6 +530,24 @@
|
||||
| Some v -> v
|
||||
let mem t k = _hashtbl_mem t k
|
||||
let length t = _hashtbl_length t
|
||||
|
||||
(* iter / fold over (k, v) pairs. Keys come back as their string
|
||||
representation since the host coerces all keys via `str`. *)
|
||||
let iter f t =
|
||||
let rec go xs =
|
||||
match xs with
|
||||
| [] -> ()
|
||||
| (k, v) :: rest -> f k v; go rest
|
||||
in
|
||||
go (_hashtbl_to_list t)
|
||||
|
||||
let fold f t acc =
|
||||
let rec go xs a =
|
||||
match xs with
|
||||
| [] -> a
|
||||
| (k, v) :: rest -> go rest (f k v a)
|
||||
in
|
||||
go (_hashtbl_to_list t) acc
|
||||
end ;;
|
||||
|
||||
module Map = struct
|
||||
|
||||
@@ -1222,6 +1222,12 @@ cat > "$TMPFILE" << 'EPOCHS'
|
||||
(epoch 4944)
|
||||
(eval "(ocaml-run \"string_of_int 7 ^ \\\"-\\\" ^ string_of_bool true\")")
|
||||
|
||||
;; ── Hashtbl.iter / Hashtbl.fold ─────────────────────────────
|
||||
(epoch 4950)
|
||||
(eval "(ocaml-run \"let t = Hashtbl.create 4 in Hashtbl.add t \\\"a\\\" 1; Hashtbl.add t \\\"b\\\" 2; Hashtbl.add t \\\"c\\\" 3; Hashtbl.fold (fun _ v acc -> acc + v) t 0\")")
|
||||
(epoch 4951)
|
||||
(eval "(ocaml-run \"let t = Hashtbl.create 4 in Hashtbl.add t \\\"x\\\" 10; Hashtbl.add t \\\"y\\\" 20; let total = ref 0 in Hashtbl.iter (fun _ v -> total := !total + v) t; !total\")")
|
||||
|
||||
EPOCHS
|
||||
|
||||
OUTPUT=$(timeout 360 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||
@@ -1938,6 +1944,10 @@ check 4942 "sprintf %s = %d" '"answer = 42"'
|
||||
check 4943 "sprintf %d%% literal percent" '"50%"'
|
||||
check 4944 "string_of_int + string_of_b" '"7-true"'
|
||||
|
||||
# ── Hashtbl.iter / Hashtbl.fold ─────────────────────────────────
|
||||
check 4950 "Hashtbl.fold sum 1+2+3" '6'
|
||||
check 4951 "Hashtbl.iter ref accum 10+20" '30'
|
||||
|
||||
TOTAL=$((PASS + FAIL))
|
||||
if [ $FAIL -eq 0 ]; then
|
||||
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
||||
|
||||
@@ -407,6 +407,12 @@ _Newest first._
|
||||
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
|
||||
'a tree`) with insert + in-order traversal. Tests parametric ADT,
|
||||
recursive match, List.append, List.fold_left.
|
||||
- 2026-05-09 Phase 6 — Hashtbl.iter / Hashtbl.fold (+2 tests, 494
|
||||
total). New host primitive `_hashtbl_to_list` returns the entries
|
||||
as a list of OCaml tuples (`("tuple" k v)` form, matching the AST
|
||||
representation that pattern matching expects). Hashtbl.iter / fold
|
||||
in runtime walk that list with the user fn. Closes a long-standing
|
||||
gap: previously Hashtbl was opaque after writing to it.
|
||||
- 2026-05-09 Phase 6 — Printf.sprintf with %d/%s/%f/%c/%b/%% (+4
|
||||
tests) and global `string_of_int`/`string_of_float`/`string_of_bool`
|
||||
(+1 test). 492 total. sprintf walks fmt char-by-char accumulating
|
||||
|
||||
Reference in New Issue
Block a user