tcl: Phase 7 — try/trap, exec pipelines, string audit, regexp, TclOO [WIP]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s

7a try/trap: tcl-cmd-try extended with `trap pattern varlist body` clause
   matching errorcode prefix. Handler varlist supports {result optsdict}.
   Added tcl-try-trap-matches?, tcl-try-build-opts helpers.

7b exec pipelines: new exec-pipeline SX primitive parses `|`, `< file`,
   `> file`, `>> file`, `2> file`, `2>@1` and builds a process pipeline
   via Unix.pipe + create_process. tcl-cmd-exec dispatches to it on
   metachar presence.

7c string audit: added string equal (-nocase, -length), totitle, reverse,
   replace; added string is true/false/xdigit/ascii classes.

7d TclOO: minimal `oo::class create NAME body` with method/constructor/
   destructor/superclass; instances via `Cls new ?args?`; method dispatch
   via per-object Tcl command; single inheritance via :super chain.
   Stored in interp :classes / :oo-objects / :oo-counter.

7e regexp audit: existing Re.Pcre wrapper handles ^/$ anchors, \\b
   boundaries, -nocase, captures, regsub -all. Added regression tests.

+22 idiom tests (5 try, 5 exec pipeline, 7 string, 6 regexp, 5 TclOO).

[WIP — full suite verification pending]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-08 22:45:16 +00:00
parent 21028c4fb0
commit 14986d787d
3 changed files with 681 additions and 6 deletions

View File

@@ -524,6 +524,159 @@
(get (run "exec /bin/echo -n test") :result)
"test")
; 83-87. Phase 7a try/trap with varlist
(ok "try-trap-prefix-match"
(get
(run
"try {throw {ARITH DIVZERO} divide-by-zero} trap {ARITH} {res} {set caught $res}")
:result)
"divide-by-zero")
(ok "try-trap-full-pattern"
(get
(run
"try {throw {FOO BAR} bad} trap {FOO BAR} {res} {return matched-foo-bar}")
:result)
"matched-foo-bar")
(ok "try-on-error-opts"
(get
(run
"try {error oops} on error {res opts} {dict get $opts -code}")
:result)
"1")
(ok "try-trap-no-match-falls-through"
(get
(run
"set caught notrun\ncatch {try {throw {NOPE} bad} trap {OTHER} {r} {set caught matched}}\nset caught")
:result)
"notrun")
(ok "try-trap-then-on-error"
(get
(run
"try {error generic} trap {SPECIFIC} {r} {return trap-fired} on error {r} {return on-error-fired}")
:result)
"on-error-fired")
; 88-92. Phase 7b exec pipelines + redirection
(ok "exec-pipeline-tr"
(get (run "exec echo hello world | tr a-z A-Z") :result)
"HELLO WORLD")
(ok "exec-pipeline-wc"
(get (run "exec /bin/echo abc | wc -c") :result)
"4")
(ok "exec-redirect-stdout"
(get
(run
"set f /tmp/tcl-7b-out.txt\nexec echo hello > $f\nset r [exec cat $f]\nfile delete $f\nreturn $r")
:result)
"hello")
(ok "exec-redirect-stdin"
(get
(run
"set f /tmp/tcl-7b-in.txt\nset c [open $f w]\nputs -nonewline $c hi\nclose $c\nset r [exec cat < $f]\nfile delete $f\nreturn $r")
:result)
"hi")
(ok "exec-pipeline-three-stages"
(get (run "exec echo {alpha beta gamma} | tr { } \\n | wc -l") :result)
"3")
; 93-99. Phase 7c string command audit
(ok "string-equal"
(get (run "string equal hello hello") :result)
"1")
(ok "string-equal-nocase"
(get (run "string equal -nocase HELLO hello") :result)
"1")
(ok "string-totitle"
(get (run "string totitle hello") :result)
"Hello")
(ok "string-reverse"
(get (run "string reverse hello") :result)
"olleh")
(ok "string-replace"
(get (run "string replace hello 1 3 ZZZ") :result)
"hZZZo")
(ok "string-is-xdigit-yes"
(get (run "string is xdigit ff00aa") :result)
"1")
(ok "string-is-true-yes"
(get (run "string is true yes") :result)
"1")
; 100-105. Phase 7e regexp anchoring/boundary audit
(ok "regexp-anchor-start"
(get (run "regexp {^hello} hello-world") :result)
"1")
(ok "regexp-anchor-end"
(get (run "regexp {world$} hello-world") :result)
"1")
(ok "regexp-word-boundary"
(get (run "regexp {\\bword\\b} \"the word here\"") :result)
"1")
(ok "regexp-nocase"
(get (run "regexp -nocase {HELLO} hello") :result)
"1")
(ok "regexp-capture-var"
(get (run "regexp {[0-9]+} abc123def captured\nset captured") :result)
"123")
(ok "regsub-all"
(get (run "regsub -all {[0-9]+} a1b22c333 X") :result)
"aXbXcX")
; 106-110. Phase 7d TclOO basics
(ok "oo-class-method"
(get
(run
"oo::class create C {\nmethod get {} { return 42 }\n}\nset c [C new]\n$c get")
:result)
"42")
(ok "oo-constructor"
(get
(run
"oo::class create G {\nconstructor {n} { set ::g-name $n }\nmethod hello {} { return [string cat \"hi \" $::g-name] }\n}\nset g [G new World]\n$g hello")
:result)
"hi World")
(ok "oo-inheritance-overridden"
(get
(run
"oo::class create Animal {\nmethod sound {} { return generic }\n}\noo::class create Dog {\nsuperclass Animal\nmethod sound {} { return woof }\n}\nset d [Dog new]\n$d sound")
:result)
"woof")
(ok "oo-inheritance-inherited"
(get
(run
"oo::class create Animal {\nmethod sound {} { return generic }\n}\noo::class create Cat {\nsuperclass Animal\n}\nset c [Cat new]\n$c sound")
:result)
"generic")
(ok "oo-multiple-instances"
(get
(run
"oo::class create N {\nconstructor {x} { set ::n-val $x }\nmethod get {} { return $::n-val }\n}\nset a [N new 1]\nset b [N new 99]\n$b get")
:result)
"99")
(dict
"passed"
tcl-idiom-pass