tcl: expr mini-language — recursive descent parser (+20 tests, 127 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 42s

Replaces 3-token flat evaluator with full recursive descent parser:
operator precedence, parentheses, unary ops, ** power, function calls
(abs/sqrt/pow/max/min/int/double), expression tokenizer for dense syntax.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 08:43:02 +00:00
parent 72ccaf4565
commit ac013c9381
3 changed files with 443 additions and 37 deletions

View File

@@ -153,6 +153,26 @@
((frame (get i :frame)))
(nil? (get (get frame :locals) "x")))))
(ok "eval" (tcl-var-get (run "eval {set x hello}") "x") "hello")
(ok "expr-precedence" (get (run "expr {3 + 4 * 2}") :result) "11")
(ok "expr-parens" (get (run "expr {(3 + 4) * 2}") :result) "14")
(ok "expr-unary-minus" (get (run "expr {-5}") :result) "-5")
(ok "expr-unary-not-0" (get (run "expr {!0}") :result) "1")
(ok "expr-unary-not-1" (get (run "expr {!1}") :result) "0")
(ok "expr-power" (get (run "expr {2 ** 10}") :result) "1024")
(ok "expr-le" (get (run "expr {3 <= 3}") :result) "1")
(ok "expr-ge" (get (run "expr {4 >= 5}") :result) "0")
(ok "expr-and" (get (run "expr {1 && 1}") :result) "1")
(ok "expr-or" (get (run "expr {0 || 1}") :result) "1")
(ok "expr-var-sub" (get (run "set x 7\nexpr {$x * 3}") :result) "21")
(ok "expr-abs-neg" (get (run "expr {abs(-3)}") :result) "3")
(ok "expr-abs-pos" (get (run "expr {abs(5)}") :result) "5")
(ok "expr-pow-fn" (get (run "expr {pow(2, 8)}") :result) "256")
(ok "expr-max" (get (run "expr {max(3, 7)}") :result) "7")
(ok "expr-min" (get (run "expr {min(3, 7)}") :result) "3")
(ok "expr-sqrt-9" (get (run "expr {sqrt(9)}") :result) "3")
(ok "expr-sqrt-16" (get (run "expr {sqrt(16)}") :result) "4")
(ok "expr-mod" (get (run "expr {17 % 5}") :result) "2")
(ok "expr-nospace" (get (run "expr {3+4*2}") :result) "11")
(ok "expr-add" (get (run "expr {3 + 4}") :result) "7")
(ok "expr-cmp" (get (run "expr {5 > 3}") :result) "1")
(ok