cl: Phase 6 FORMAT + substr fixes — 514/514 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 39s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 39s
FORMAT with ~A/~S/~D/~F/~%/~&/~T/~P/~{...~}/~^; cl-fmt-loop,
cl-fmt-find-close, cl-fmt-iterate, cl-fmt-a/cl-fmt-s helpers.
Fix substr(start,length) semantics throughout: SUBSEQ end formula
corrected to (- end start), cl-fmt-loop char extraction fixed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -191,6 +191,140 @@
|
||||
(cl-eval-body body e5)))))))))))))
|
||||
|
||||
|
||||
;; ── FORMAT helpers ──────────────────────────────────────────────
|
||||
|
||||
(define cl-fmt-a
|
||||
(fn (arg)
|
||||
(cond
|
||||
((= arg nil) "()")
|
||||
((= arg true) "T")
|
||||
((= arg false) "NIL")
|
||||
((string? arg) arg)
|
||||
((number? arg) (str arg))
|
||||
((list? arg)
|
||||
(if (= (len arg) 0) "()"
|
||||
(str "("
|
||||
(reduce (fn (a x) (str a " " (cl-fmt-a x)))
|
||||
(cl-fmt-a (nth arg 0))
|
||||
(rest arg))
|
||||
")")))
|
||||
((and (dict? arg) (= (get arg "cl-type") "keyword"))
|
||||
(str ":" (get arg "name")))
|
||||
((and (dict? arg) (= (get arg "cl-type") "char"))
|
||||
(get arg "value"))
|
||||
(:else (str arg)))))
|
||||
|
||||
(define cl-fmt-s
|
||||
(fn (arg)
|
||||
(cond
|
||||
((= arg nil) "NIL")
|
||||
((= arg true) "T")
|
||||
((= arg false) "NIL")
|
||||
((string? arg) (str "\"" arg "\""))
|
||||
((number? arg) (str arg))
|
||||
((list? arg)
|
||||
(if (= (len arg) 0) "NIL"
|
||||
(str "("
|
||||
(reduce (fn (a x) (str a " " (cl-fmt-s x)))
|
||||
(cl-fmt-s (nth arg 0))
|
||||
(rest arg))
|
||||
")")))
|
||||
((and (dict? arg) (= (get arg "cl-type") "keyword"))
|
||||
(str ":" (get arg "name")))
|
||||
((and (dict? arg) (= (get arg "cl-type") "char"))
|
||||
(str "#\\" (get arg "value")))
|
||||
(:else (str arg)))))
|
||||
|
||||
;; Find position of ~CH (tilde+ch) in ctrl, starting from i, tracking nesting
|
||||
(define cl-fmt-find-close
|
||||
(fn (ctrl ch i depth)
|
||||
(if (>= i (- (len ctrl) 1)) -1
|
||||
(let ((c (substr ctrl i 1)))
|
||||
(if (= c "~")
|
||||
(let ((nxt (upcase (substr ctrl (+ i 1) 1))))
|
||||
(cond
|
||||
((= nxt ch)
|
||||
(if (= depth 0) i (cl-fmt-find-close ctrl ch (+ i 2) (- depth 1))))
|
||||
((or (= nxt "{") (= nxt "["))
|
||||
(cl-fmt-find-close ctrl ch (+ i 2) (+ depth 1)))
|
||||
(:else
|
||||
(cl-fmt-find-close ctrl ch (+ i 2) depth))))
|
||||
(cl-fmt-find-close ctrl ch (+ i 1) depth))))))
|
||||
|
||||
;; Process inner ~{...~} string over each element of a list
|
||||
(define cl-fmt-iterate
|
||||
(fn (inner items)
|
||||
(if (= items nil) ""
|
||||
(if (= (len items) 0) ""
|
||||
(reduce
|
||||
(fn (acc x)
|
||||
(str acc (get (cl-fmt-loop inner (list x) 0 "") "out")))
|
||||
"" items)))))
|
||||
|
||||
;; Main format loop: returns {:out string :args remaining}
|
||||
(define cl-fmt-loop
|
||||
(fn (ctrl args i out)
|
||||
(if (>= i (len ctrl))
|
||||
{:out out :args args}
|
||||
(let ((ch (substr ctrl i 1)))
|
||||
(if (not (= ch "~"))
|
||||
(cl-fmt-loop ctrl args (+ i 1) (str out ch))
|
||||
(let ((dir (if (< (+ i 1) (len ctrl))
|
||||
(upcase (substr ctrl (+ i 1) 1))
|
||||
"")))
|
||||
(cond
|
||||
((= dir "A")
|
||||
(cl-fmt-loop ctrl (rest args) (+ i 2)
|
||||
(str out (if (> (len args) 0) (cl-fmt-a (nth args 0)) ""))))
|
||||
((= dir "S")
|
||||
(cl-fmt-loop ctrl (rest args) (+ i 2)
|
||||
(str out (if (> (len args) 0) (cl-fmt-s (nth args 0)) ""))))
|
||||
((or (= dir "D") (= dir "F") (= dir "B") (= dir "X") (= dir "O"))
|
||||
(cl-fmt-loop ctrl (rest args) (+ i 2)
|
||||
(str out (if (> (len args) 0) (str (nth args 0)) ""))))
|
||||
((= dir "%")
|
||||
(cl-fmt-loop ctrl args (+ i 2) (str out "\n")))
|
||||
((= dir "&")
|
||||
(cl-fmt-loop ctrl args (+ i 2)
|
||||
(if (or (= (len out) 0)
|
||||
(= (substr out (- (len out) 1) 1) "\n"))
|
||||
out (str out "\n"))))
|
||||
((= dir "T")
|
||||
(cl-fmt-loop ctrl args (+ i 2) (str out "\t")))
|
||||
((= dir "P")
|
||||
(let ((arg (if (> (len args) 0) (nth args 0) 1)))
|
||||
(cl-fmt-loop ctrl (rest args) (+ i 2)
|
||||
(str out (if (= arg 1) "" "s")))))
|
||||
((= dir "{")
|
||||
(let ((end-i (cl-fmt-find-close ctrl "}" (+ i 2) 0)))
|
||||
(if (= end-i -1)
|
||||
{:out (str out "~{") :args args}
|
||||
(let ((inner (if (> end-i (+ i 2))
|
||||
(substr ctrl (+ i 2) (- end-i (+ i 2)))
|
||||
"")))
|
||||
(let ((list-arg (if (> (len args) 0) (nth args 0) (list))))
|
||||
(cl-fmt-loop ctrl (rest args) (+ end-i 2)
|
||||
(str out (cl-fmt-iterate inner (if (= list-arg nil) (list) list-arg)))))))))
|
||||
((= dir "[")
|
||||
(let ((end-i (cl-fmt-find-close ctrl "]" (+ i 2) 0)))
|
||||
(if (= end-i -1)
|
||||
{:out (str out "~[") :args args}
|
||||
(let ((inner (if (> end-i (+ i 2))
|
||||
(substr ctrl (+ i 2) (- end-i (+ i 2)))
|
||||
"")))
|
||||
(let ((arg (if (> (len args) 0) (nth args 0) 0)))
|
||||
(let ((chosen (if (= arg true) "T"
|
||||
(if (= arg nil) "NIL"
|
||||
(get (cl-fmt-loop inner (list arg) 0 "") "out")))))
|
||||
(cl-fmt-loop ctrl (rest args) (+ end-i 2)
|
||||
(str out chosen))))))))
|
||||
((= dir "~")
|
||||
(cl-fmt-loop ctrl args (+ i 2) (str out "~")))
|
||||
((= dir "^")
|
||||
{:out out :args args})
|
||||
(:else
|
||||
(cl-fmt-loop ctrl args (+ i 2) (str out "~" dir))))))))))
|
||||
|
||||
;; ── sequence/list helpers (needed by builtins) ───────────────────
|
||||
|
||||
(define cl-member-helper
|
||||
@@ -520,7 +654,7 @@
|
||||
(start (nth args 1))
|
||||
(end (if (> (len args) 2) (nth args 2) nil)))
|
||||
(if (string? seq)
|
||||
(if end (substr seq start (- end 1)) (substr seq start (- (len seq) 1)))
|
||||
(if end (substr seq start (- end start)) (substr seq start (- (len seq) start)))
|
||||
(if (= seq nil) (list)
|
||||
(if end (slice seq start end) (slice seq start (len seq)))))))
|
||||
"STRING" (fn (args)
|
||||
@@ -552,6 +686,12 @@
|
||||
(reduce (fn (a c) (str a (if (dict? c) (get c "value") c))) "" x)
|
||||
(str x)))
|
||||
(:else x))))
|
||||
"FORMAT" (fn (args)
|
||||
(let ((dest (nth args 0))
|
||||
(ctrl (if (> (len args) 1) (nth args 1) ""))
|
||||
(fargs (if (> (len args) 2) (slice args 2 (len args)) (list))))
|
||||
(let ((result (get (cl-fmt-loop ctrl fargs 0 "") "out")))
|
||||
(if (= dest nil) result nil))))
|
||||
"MAKE-LIST" (fn (args)
|
||||
(let ((n (nth args 0)))
|
||||
(map (fn (_) nil) (range 0 n))))))
|
||||
|
||||
Reference in New Issue
Block a user