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)
|
||||
|
||||
Reference in New Issue
Block a user