tcl: array get/set/names/size/exists/unset commands (+8 tests, 337 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2903,6 +2903,150 @@
|
||||
(define tcl-cmd-tell (fn (interp args) (assoc interp :result "0")))
|
||||
|
||||
(define tcl-cmd-flush (fn (interp args) (assoc interp :result "")))
|
||||
(define
|
||||
tcl-cmd-array
|
||||
(fn
|
||||
(interp args)
|
||||
(if
|
||||
(= 0 (len args))
|
||||
(error "array: wrong # args")
|
||||
(let
|
||||
((sub (first args)) (rest-args (rest args)))
|
||||
(cond
|
||||
((equal? sub "get")
|
||||
(if (= 0 (len rest-args))
|
||||
(error "array get: wrong # args")
|
||||
(let
|
||||
((arr-name (first rest-args))
|
||||
(pattern (if (> (len rest-args) 1) (nth rest-args 1) nil)))
|
||||
(let
|
||||
((prefix (str arr-name "("))
|
||||
(locals (get (get interp :frame) :locals)))
|
||||
(let
|
||||
((pl (string-length prefix)))
|
||||
(let
|
||||
((arr-keys (filter (fn (k) (tcl-starts-with? k prefix)) (keys locals))))
|
||||
(let
|
||||
((filtered
|
||||
(if
|
||||
(nil? pattern)
|
||||
arr-keys
|
||||
(filter
|
||||
(fn (k)
|
||||
(let ((kn (substring k pl (- (string-length k) 1))))
|
||||
(tcl-glob-match (split pattern "") (split kn ""))))
|
||||
arr-keys))))
|
||||
(assoc interp :result
|
||||
(join " "
|
||||
(reduce
|
||||
(fn (acc k)
|
||||
(let ((kn (substring k pl (- (string-length k) 1))))
|
||||
(append acc (list kn) (list (get locals k)))))
|
||||
(list)
|
||||
filtered))))))))))
|
||||
((equal? sub "set")
|
||||
(if
|
||||
(< (len rest-args) 2)
|
||||
(error "array set: wrong # args")
|
||||
(let
|
||||
((arr-name (first rest-args))
|
||||
(flat (tcl-list-split (nth rest-args 1))))
|
||||
(let
|
||||
loop
|
||||
((pairs flat) (acc interp))
|
||||
(if
|
||||
(< (len pairs) 2)
|
||||
(assoc acc :result "")
|
||||
(loop
|
||||
(rest (rest pairs))
|
||||
(tcl-var-set acc
|
||||
(str arr-name "(" (first pairs) ")")
|
||||
(nth pairs 1))))))))
|
||||
((equal? sub "names")
|
||||
(if
|
||||
(= 0 (len rest-args))
|
||||
(error "array names: wrong # args")
|
||||
(let
|
||||
((arr-name (first rest-args))
|
||||
(pattern (if (> (len rest-args) 1) (nth rest-args 1) nil)))
|
||||
(let
|
||||
((prefix (str arr-name "("))
|
||||
(locals (get (get interp :frame) :locals)))
|
||||
(let
|
||||
((pl (string-length prefix)))
|
||||
(let
|
||||
((arr-keys (filter (fn (k) (tcl-starts-with? k prefix)) (keys locals))))
|
||||
(let
|
||||
((filtered
|
||||
(if
|
||||
(nil? pattern)
|
||||
arr-keys
|
||||
(filter
|
||||
(fn (k)
|
||||
(let ((kn (substring k pl (- (string-length k) 1))))
|
||||
(tcl-glob-match (split pattern "") (split kn ""))))
|
||||
arr-keys))))
|
||||
(assoc interp :result
|
||||
(join " " (map (fn (k) (substring k pl (- (string-length k) 1))) filtered))))))))))
|
||||
((equal? sub "size")
|
||||
(if
|
||||
(= 0 (len rest-args))
|
||||
(error "array size: wrong # args")
|
||||
(let
|
||||
((prefix (str (first rest-args) "("))
|
||||
(locals (get (get interp :frame) :locals)))
|
||||
(assoc interp :result
|
||||
(str (len (filter (fn (k) (tcl-starts-with? k prefix)) (keys locals))))))))
|
||||
((equal? sub "exists")
|
||||
(if
|
||||
(= 0 (len rest-args))
|
||||
(error "array exists: wrong # args")
|
||||
(let
|
||||
((prefix (str (first rest-args) "("))
|
||||
(locals (get (get interp :frame) :locals)))
|
||||
(assoc interp :result
|
||||
(if (> (len (filter (fn (k) (tcl-starts-with? k prefix)) (keys locals))) 0) "1" "0")))))
|
||||
((equal? sub "unset")
|
||||
(if
|
||||
(= 0 (len rest-args))
|
||||
(error "array unset: wrong # args")
|
||||
(let
|
||||
((arr-name (first rest-args))
|
||||
(pattern (if (> (len rest-args) 1) (nth rest-args 1) nil)))
|
||||
(let
|
||||
((prefix (str arr-name "("))
|
||||
(locals (get (get interp :frame) :locals)))
|
||||
(let
|
||||
((pl (string-length prefix)))
|
||||
(let
|
||||
((to-delete
|
||||
(filter
|
||||
(fn (k)
|
||||
(if
|
||||
(tcl-starts-with? k prefix)
|
||||
(if
|
||||
(nil? pattern)
|
||||
true
|
||||
(let ((kn (substring k pl (- (string-length k) 1))))
|
||||
(tcl-glob-match (split pattern "") (split kn ""))))
|
||||
false))
|
||||
(keys locals))))
|
||||
(let
|
||||
((new-locals
|
||||
(reduce
|
||||
(fn (acc k)
|
||||
(if
|
||||
(contains? to-delete k)
|
||||
acc
|
||||
(assoc acc k (get locals k))))
|
||||
{}
|
||||
(keys locals))))
|
||||
(assoc interp
|
||||
:frame (assoc (get interp :frame) :locals new-locals)
|
||||
:result ""))))))))
|
||||
(else (error (str "array: unknown subcommand \"" sub "\""))))))))
|
||||
|
||||
|
||||
(define
|
||||
tcl-cmd-apply
|
||||
(fn
|
||||
@@ -3194,4 +3338,4 @@
|
||||
((i (tcl-register i "flush" tcl-cmd-flush)))
|
||||
(let ((i (tcl-register i "file" tcl-cmd-file)))
|
||||
(let ((i (tcl-register i "regexp" tcl-cmd-regexp)))
|
||||
(let ((i (tcl-register i "regsub" tcl-cmd-regsub))) (tcl-register i "apply" tcl-cmd-apply)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
|
||||
(let ((i (tcl-register i "regsub" tcl-cmd-regsub))) (let ((i (tcl-register i "apply" tcl-cmd-apply))) (tcl-register i "array" tcl-cmd-array))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
|
||||
|
||||
Reference in New Issue
Block a user