ocaml: phase 1+6 Buffer + parser !x in app args (+3 tests, 425 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s

Parser fix: at-app-start? and parse-app's loop recognise prefix !
as a deref of the next app arg. So 'List.rev !b' parses as
'(:app List.rev (:deref b))' instead of stalling at !.

Buffer module backed by a ref holding string list:
  create _ = ref []
  add_string b s = b := s :: !b
  contents b = String.concat "" (List.rev !b)
  add_char/length/clear/reset
This commit is contained in:
2026-05-08 16:16:52 +00:00
parent dbe3c6c203
commit 2f271fa6a6
4 changed files with 39 additions and 3 deletions

View File

@@ -167,7 +167,7 @@
((= tt "ctor") true)
((and (= tt "keyword") (or (= tv "true") (= tv "false")))
true)
((and (= tt "op") (or (= tv "(") (= tv "[") (= tv "{"))) true)
((and (= tt "op") (or (= tv "(") (= tv "[") (= tv "{") (= tv "!"))) true)
(else false)))))
(set!
parse-pattern-atom
@@ -532,7 +532,7 @@
((= tt "ctor") true)
((and (= tt "keyword") (or (= tv "true") (= tv "false") (= tv "begin")))
true)
((and (= tt "op") (or (= tv "(") (= tv "[") (= tv "{"))) true)
((and (= tt "op") (or (= tv "(") (= tv "[") (= tv "{") (= tv "!"))) true)
(else false)))))
(define parse-atom-postfix
(fn ()
@@ -568,7 +568,12 @@
(when
(at-app-start?)
(let
((arg (parse-atom-postfix)))
((arg
(cond
((at-op? "!")
(begin (advance-tok!)
(list :deref (parse-atom-postfix))))
(else (parse-atom-postfix)))))
(begin (set! head (list :app head arg)) (loop))))))
(loop)
head))))

View File

@@ -366,6 +366,16 @@
let printf fmt = print_string fmt
end ;;
module Buffer = struct
let create _ = ref []
let add_string b s = b := s :: !b
let add_char b c = b := c :: !b
let contents b = String.concat \"\" (List.rev !b)
let length b = String.length (String.concat \"\" (List.rev !b))
let clear b = b := []
let reset = clear
end ;;
module Sys = struct
let os_type = \"SX\"
let word_size = 64

View File

@@ -1044,6 +1044,14 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 3403)
(eval "(ocaml-run-program \"module IntOrd = struct let compare a b = compare a b end ;; module IntSet = Set.Make(IntOrd) ;; let a = IntSet.add 1 (IntSet.add 2 (IntSet.add 3 IntSet.empty)) ;; let b = IntSet.add 2 (IntSet.add 3 (IntSet.add 4 IntSet.empty)) ;; IntSet.elements (IntSet.inter a b)\")")
;; ── Buffer module ──────────────────────────────────────────────
(epoch 3500)
(eval "(ocaml-run-program \"let b = Buffer.create 16 ;; Buffer.add_string b \\\"Hello\\\" ;; Buffer.add_string b \\\", \\\" ;; Buffer.add_string b \\\"World\\\" ;; Buffer.contents b\")")
(epoch 3501)
(eval "(ocaml-run-program \"let b = Buffer.create 16 ;; Buffer.add_string b \\\"abc\\\" ;; Buffer.length b\")")
(epoch 3502)
(eval "(ocaml-run-program \"let b = Buffer.create 16 ;; Buffer.add_string b \\\"x\\\" ;; Buffer.clear b ;; Buffer.contents b\")")
EPOCHS
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
@@ -1652,6 +1660,11 @@ check 3401 "Map.is_empty false" 'false'
check 3402 "Set.union" '(1 2 3)'
check 3403 "Set.inter" '(2 3)'
# ── Buffer module ──────────────────────────────────────────────
check 3500 "Buffer concat 'Hello, World'" '"Hello, World"'
check 3501 "Buffer.length 3" '3'
check 3502 "Buffer.clear empties" '""'
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"