lua: table library (insert/remove/concat/sort/unpack) +13 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
This commit is contained in:
@@ -991,3 +991,141 @@
|
||||
(dict-set! math "modf" lua-math-modf)
|
||||
(dict-set! math "random" lua-math-random)
|
||||
(dict-set! math "randomseed" lua-math-randomseed)
|
||||
|
||||
;; ── table library ─────────────────────────────────────────────
|
||||
(define table {})
|
||||
|
||||
(define
|
||||
lua-table-insert
|
||||
(fn (&rest args)
|
||||
(cond
|
||||
((= (len args) 2)
|
||||
(let ((t (first args)) (v (nth args 1)))
|
||||
(let ((n (lua-len t)))
|
||||
(dict-set! t (str (+ n 1)) v))))
|
||||
((= (len args) 3)
|
||||
(let ((t (first args)) (pos (nth args 1)) (v (nth args 2)))
|
||||
(let ((n (lua-len t)))
|
||||
(begin
|
||||
(define
|
||||
tbl-shift-up
|
||||
(fn (i)
|
||||
(when (>= i pos)
|
||||
(begin
|
||||
(dict-set! t (str (+ i 1)) (get t (str i)))
|
||||
(tbl-shift-up (- i 1))))))
|
||||
(tbl-shift-up n)
|
||||
(dict-set! t (str pos) v)))))
|
||||
(else (error "lua: table.insert: wrong args")))))
|
||||
|
||||
(define
|
||||
lua-table-remove
|
||||
(fn (&rest args)
|
||||
(let ((t (first args)))
|
||||
(let ((n (lua-len t)))
|
||||
(let ((pos (if (> (len args) 1) (nth args 1) n)))
|
||||
(cond
|
||||
((<= n 0) nil)
|
||||
(else
|
||||
(let ((v (get t (str pos))))
|
||||
(begin
|
||||
(define
|
||||
tbl-shift-down
|
||||
(fn (i)
|
||||
(when (< i n)
|
||||
(begin
|
||||
(dict-set! t (str i) (get t (str (+ i 1))))
|
||||
(tbl-shift-down (+ i 1))))))
|
||||
(tbl-shift-down pos)
|
||||
(dict-set! t (str n) nil)
|
||||
v)))))))))
|
||||
|
||||
(define
|
||||
lua-table-concat
|
||||
(fn (&rest args)
|
||||
(let ((t (first args))
|
||||
(sep (if (> (len args) 1) (nth args 1) ""))
|
||||
(i (if (> (len args) 2) (nth args 2) 1))
|
||||
(j (if (> (len args) 3) (nth args 3) (lua-len (first args)))))
|
||||
(cond
|
||||
((> i j) "")
|
||||
(else
|
||||
(let ((out (lua-concat-coerce (get t (str i)))))
|
||||
(begin
|
||||
(define
|
||||
loop
|
||||
(fn (k)
|
||||
(when (<= k j)
|
||||
(begin
|
||||
(set! out (str out sep (lua-concat-coerce (get t (str k)))))
|
||||
(loop (+ k 1))))))
|
||||
(loop (+ i 1))
|
||||
out)))))))
|
||||
|
||||
;; Simple insertion sort for tables
|
||||
(define
|
||||
lua-table-sort
|
||||
(fn (&rest args)
|
||||
(let ((t (first args))
|
||||
(comp (if (> (len args) 1) (nth args 1) nil)))
|
||||
(let ((n (lua-len t)))
|
||||
(begin
|
||||
(define
|
||||
lt?
|
||||
(fn (a b)
|
||||
(cond
|
||||
((= comp nil) (lua-lt a b))
|
||||
(else (lua-truthy? (lua-call comp a b))))))
|
||||
(define
|
||||
insert-sorted
|
||||
(fn (i)
|
||||
(when (> i 1)
|
||||
(let ((v (get t (str i))) (prev (get t (str (- i 1)))))
|
||||
(when (lt? v prev)
|
||||
(begin
|
||||
(dict-set! t (str i) prev)
|
||||
(dict-set! t (str (- i 1)) v)
|
||||
(insert-sorted (- i 1))))))))
|
||||
(define
|
||||
outer
|
||||
(fn (i)
|
||||
(when (<= i n)
|
||||
(begin
|
||||
(insert-sorted i)
|
||||
(outer (+ i 1))))))
|
||||
(outer 2)
|
||||
nil)))))
|
||||
|
||||
(define
|
||||
lua-unpack
|
||||
(fn (&rest args)
|
||||
(let ((t (first args))
|
||||
(i (if (> (len args) 1) (nth args 1) 1))
|
||||
(j (if (> (len args) 2) (nth args 2) (lua-len (first args)))))
|
||||
(cond
|
||||
((> i j) nil)
|
||||
(else
|
||||
(let ((out (list (quote lua-multi))))
|
||||
(begin
|
||||
(define
|
||||
loop
|
||||
(fn (k)
|
||||
(when (<= k j)
|
||||
(begin
|
||||
(set! out (append out (list (get t (str k)))))
|
||||
(loop (+ k 1))))))
|
||||
(loop i)
|
||||
out)))))))
|
||||
|
||||
(define
|
||||
lua-table-maxn
|
||||
(fn (t) (lua-len t)))
|
||||
|
||||
(dict-set! table "insert" lua-table-insert)
|
||||
(dict-set! table "remove" lua-table-remove)
|
||||
(dict-set! table "concat" lua-table-concat)
|
||||
(dict-set! table "sort" lua-table-sort)
|
||||
(dict-set! table "unpack" lua-unpack)
|
||||
(dict-set! table "maxn" lua-table-maxn)
|
||||
|
||||
(define unpack lua-unpack)
|
||||
|
||||
@@ -804,6 +804,34 @@ cat > "$TMPFILE" << 'EPOCHS'
|
||||
(epoch 1261)
|
||||
(eval "(lua-eval-ast \"local r = math.random(5, 10) return r >= 5 and r <= 10\")")
|
||||
|
||||
;; ── Phase 6: table library ────────────────────────────────────
|
||||
(epoch 1300)
|
||||
(eval "(lua-eval-ast \"local t = {1, 2, 3} table.insert(t, 4) return #t\")")
|
||||
(epoch 1301)
|
||||
(eval "(lua-eval-ast \"local t = {1, 2, 3} table.insert(t, 4) return t[4]\")")
|
||||
(epoch 1302)
|
||||
(eval "(lua-eval-ast \"local t = {10, 30} table.insert(t, 2, 20) return t[2]\")")
|
||||
(epoch 1303)
|
||||
(eval "(lua-eval-ast \"local t = {10, 20, 30} table.insert(t, 1, 5) return t[1] * 100 + t[2]\")")
|
||||
(epoch 1310)
|
||||
(eval "(lua-eval-ast \"local t = {1, 2, 3} local v = table.remove(t) return v * 10 + #t\")")
|
||||
(epoch 1311)
|
||||
(eval "(lua-eval-ast \"local t = {10, 20, 30} table.remove(t, 1) return t[1] * 10 + t[2]\")")
|
||||
(epoch 1320)
|
||||
(eval "(lua-eval-ast \"local t = {\\\"a\\\", \\\"b\\\", \\\"c\\\"} return table.concat(t)\")")
|
||||
(epoch 1321)
|
||||
(eval "(lua-eval-ast \"local t = {\\\"a\\\", \\\"b\\\", \\\"c\\\"} return table.concat(t, \\\"-\\\")\")")
|
||||
(epoch 1322)
|
||||
(eval "(lua-eval-ast \"local t = {1, 2, 3, 4} return table.concat(t, \\\",\\\", 2, 3)\")")
|
||||
(epoch 1330)
|
||||
(eval "(lua-eval-ast \"local t = {3, 1, 4, 1, 5, 9, 2, 6} table.sort(t) return t[1] * 100 + t[8]\")")
|
||||
(epoch 1331)
|
||||
(eval "(lua-eval-ast \"local t = {3, 1, 2} table.sort(t, function(a, b) return a > b end) return t[1] * 100 + t[3]\")")
|
||||
(epoch 1340)
|
||||
(eval "(lua-eval-ast \"local t = {10, 20, 30} local a, b, c = unpack(t) return a + b + c\")")
|
||||
(epoch 1341)
|
||||
(eval "(lua-eval-ast \"local t = {10, 20, 30, 40} local a, b = table.unpack(t, 2, 3) return a + b\")")
|
||||
|
||||
EPOCHS
|
||||
|
||||
OUTPUT=$(timeout 60 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||
@@ -1206,6 +1234,21 @@ check 1251 "math.modf(3.5) int part" '3'
|
||||
check 1260 "math.random(n) in range" 'true'
|
||||
check 1261 "math.random(m,n) in range" 'true'
|
||||
|
||||
# ── Phase 6: table library ────────────────────────────────────
|
||||
check 1300 "table.insert append → #t" '4'
|
||||
check 1301 "table.insert value" '4'
|
||||
check 1302 "table.insert(t,pos,v) mid" '20'
|
||||
check 1303 "table.insert(t,1,v) prepend" '510'
|
||||
check 1310 "table.remove() last" '33'
|
||||
check 1311 "table.remove(t,1) shift" '230'
|
||||
check 1320 "table.concat no sep" '"abc"'
|
||||
check 1321 "table.concat with sep" '"a-b-c"'
|
||||
check 1322 "table.concat range" '"2,3"'
|
||||
check 1330 "table.sort asc" '109'
|
||||
check 1331 "table.sort desc via cmp" '301'
|
||||
check 1340 "unpack global" '60'
|
||||
check 1341 "table.unpack(t,i,j)" '50'
|
||||
|
||||
TOTAL=$((PASS + FAIL))
|
||||
if [ $FAIL -eq 0 ]; then
|
||||
echo "ok $PASS/$TOTAL Lua-on-SX tests passed"
|
||||
|
||||
@@ -70,7 +70,7 @@ Each item: implement → tests → tick box → update progress log.
|
||||
### Phase 6 — standard library
|
||||
- [x] `string` — `format`, `sub`, `find`, `match`, `gmatch`, `gsub`, `len`, `rep`, `upper`, `lower`, `byte`, `char`
|
||||
- [x] `math` — full surface
|
||||
- [ ] `table` — `insert`, `remove`, `concat`, `sort`, `unpack`
|
||||
- [x] `table` — `insert`, `remove`, `concat`, `sort`, `unpack`
|
||||
- [ ] `io` — minimal stub (read/write to SX IO surface)
|
||||
- [ ] `os` — time/date subset
|
||||
|
||||
@@ -82,6 +82,7 @@ Each item: implement → tests → tick box → update progress log.
|
||||
|
||||
_Newest first. Agent appends on every commit._
|
||||
|
||||
- 2026-04-24: lua: `table` lib — insert (append / at pos, shifts up), remove (last / at pos, shifts down), concat (sep, i, j), sort (insertion sort, optional cmp), unpack + table.unpack, maxn. Caught trap: local helper named `shift` collides with SX's `shift` special form → renamed to `tbl-shift-up`/`tbl-shift-down`. 322 tests.
|
||||
- 2026-04-24: lua: `math` lib — pi/huge + abs/ceil/floor/sqrt/exp/log/log10/pow/trig (sin/cos/tan/asin/acos/atan/atan2)/deg/rad/min/max (&rest)/fmod/modf/random (0/1/2 arg)/randomseed. Most ops delegate to SX primitives; log w/ base via change-of-base. 309 tests.
|
||||
- 2026-04-24: lua: `string` lib — len/upper/lower/rep/sub (1-idx + neg)/byte/char/find/match/gmatch/gsub/format. Patterns are literal-only (no `%d`/etc.); format is `%s`/`%d`/`%f`/`%%` only. `string.char` uses printable-ASCII lookup + tab/nl/cr. 292 tests.
|
||||
- 2026-04-24: lua: phase 5 — coroutines (create/resume/yield/status/wrap) via `call/cc` (perform/cek-resume not exposed to SX userland). Handles multi-yield + final return + arg passthrough. Fix: body's final return must jump via `caller-k` to the **current** resume's caller, not unwind through the stale first-call continuation. 273 tests.
|
||||
|
||||
Reference in New Issue
Block a user