lua: string.format width/zero-pad/hex/octal/char/precision +6 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-25 00:24:05 +00:00
parent d170d5fbae
commit fd32bcf547
5 changed files with 183 additions and 66 deletions

View File

@@ -1145,6 +1145,39 @@
((= (type-of n) "number") (str (floor n)))
(else (str n)))))
(define
lua-fmt-pad
(fn (s width left-align zero-pad)
(let ((diff (- width (len s))))
(cond
((<= diff 0) s)
(else
(let ((pad (lua-string-rep (if (and zero-pad (not left-align)) "0" " ") diff)))
(if left-align (str s pad) (str pad s))))))))
(define
lua-fmt-int-base
(fn (n base upper)
(cond
((= n 0) "0")
(else
(let ((sign "") (v n) (out ""))
(begin
(when (< v 0) (begin (set! sign "-") (set! v (- 0 v))))
(set! v (floor v))
(define
ib-loop
(fn ()
(when (> v 0)
(let ((d (- v (* base (floor (/ v base))))))
(let ((c (cond
((< d 10) (char-at "0123456789" d))
(upper (char-at "ABCDEFGHIJKLMNOP" (- d 10)))
(else (char-at "abcdefghijklmnop" (- d 10))))))
(begin (set! out (str c out)) (set! v (floor (/ v base))) (ib-loop)))))))
(ib-loop)
(str sign out)))))))
(define
lua-string-format
(fn (&rest args)
@@ -1158,24 +1191,90 @@
(let ((c (char-at fmt i)))
(cond
((and (= c "%") (< (+ i 1) (len fmt)))
(let ((spec (char-at fmt (+ i 1))))
(cond
((= spec "%")
(begin (set! out (str out "%")) (set! i (+ i 2)) (loop)))
((= spec "s")
(let ((j (+ i 1)) (left-align false) (zero-pad false) (width 0) (prec -1))
(begin
(when (and (< j (len fmt)) (= (char-at fmt j) "-"))
(begin (set! left-align true) (set! j (+ j 1))))
(when (and (< j (len fmt)) (= (char-at fmt j) "0"))
(begin (set! zero-pad true) (set! j (+ j 1))))
(define
wd-loop
(fn ()
(when (and (< j (len fmt)) (>= (char-at fmt j) "0") (<= (char-at fmt j) "9"))
(begin
(set! width (+ (* width 10) (- (char-code (char-at fmt j)) (char-code "0"))))
(set! j (+ j 1))
(wd-loop)))))
(wd-loop)
(when (and (< j (len fmt)) (= (char-at fmt j) "."))
(begin
(set! out (str out (lua-concat-coerce (nth vals vi))))
(set! vi (+ vi 1)) (set! i (+ i 2)) (loop)))
((= spec "d")
(begin
(set! out (str out (lua-format-int (nth vals vi))))
(set! vi (+ vi 1)) (set! i (+ i 2)) (loop)))
((= spec "f")
(begin
(set! out (str out (str (nth vals vi))))
(set! vi (+ vi 1)) (set! i (+ i 2)) (loop)))
(else
(begin (set! out (str out c)) (set! i (+ i 1)) (loop))))))
(set! prec 0)
(set! j (+ j 1))
(define
pr-loop
(fn ()
(when (and (< j (len fmt)) (>= (char-at fmt j) "0") (<= (char-at fmt j) "9"))
(begin
(set! prec (+ (* prec 10) (- (char-code (char-at fmt j)) (char-code "0"))))
(set! j (+ j 1))
(pr-loop)))))
(pr-loop)))
(when (< j (len fmt))
(let ((spec (char-at fmt j)))
(cond
((= spec "%")
(begin (set! out (str out "%")) (set! i (+ j 1))))
((= spec "s")
(let ((v (lua-concat-coerce (nth vals vi))))
(let ((vt (if (and (>= prec 0) (< prec (len v))) (substring v 0 prec) v)))
(begin
(set! out (str out (lua-fmt-pad vt width left-align false)))
(set! vi (+ vi 1))
(set! i (+ j 1))))))
((= spec "d")
(let ((v (lua-fmt-int-base (lua-to-number (nth vals vi)) 10 false)))
(begin
(set! out (str out (lua-fmt-pad v width left-align zero-pad)))
(set! vi (+ vi 1))
(set! i (+ j 1)))))
((= spec "x")
(let ((v (lua-fmt-int-base (lua-to-number (nth vals vi)) 16 false)))
(begin
(set! out (str out (lua-fmt-pad v width left-align zero-pad)))
(set! vi (+ vi 1))
(set! i (+ j 1)))))
((= spec "X")
(let ((v (lua-fmt-int-base (lua-to-number (nth vals vi)) 16 true)))
(begin
(set! out (str out (lua-fmt-pad v width left-align zero-pad)))
(set! vi (+ vi 1))
(set! i (+ j 1)))))
((= spec "o")
(let ((v (lua-fmt-int-base (lua-to-number (nth vals vi)) 8 false)))
(begin
(set! out (str out (lua-fmt-pad v width left-align zero-pad)))
(set! vi (+ vi 1))
(set! i (+ j 1)))))
((= spec "f")
(let ((v (str (lua-to-number (nth vals vi)))))
(begin
(set! out (str out (lua-fmt-pad v width left-align zero-pad)))
(set! vi (+ vi 1))
(set! i (+ j 1)))))
((= spec "c")
(let ((v (lua-char-one (lua-to-number (nth vals vi)))))
(begin
(set! out (str out v))
(set! vi (+ vi 1))
(set! i (+ j 1)))))
((= spec "q")
(let ((v (str "\"" (lua-concat-coerce (nth vals vi)) "\"")))
(begin
(set! out (str out v))
(set! vi (+ vi 1))
(set! i (+ j 1)))))
(else (begin (set! out (str out c)) (set! i (+ i 1)))))))
(loop))))
(else
(begin (set! out (str out c)) (set! i (+ i 1)) (loop))))))))
(loop)