go: eval.sx — for / break / continue / inc-dec + 7 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
Phase 4 cont. go-eval-for handles all three for-header shapes:
for { ... } — infinite (cond defaults to true)
for cond { ... } — while-like (init=nil, post=nil)
for init ; cond ; post { ... } — C-style
Implementation:
* Run INIT (if any), extending env.
* Loop: eval COND. If false, exit with current env.
Eval body (a :block). Catch sentinels:
:return-value → propagate up
:break → exit loop with pre-break env
:continue → still runs POST, then re-loops
Otherwise: run POST, re-loop.
:break and :continue propagate as keyword sentinels through
go-eval-block alongside the existing :return-value sentinel. The
block returns whichever sentinel hit first; control-flow constructs
(for, switch, select) catch them.
inc-dec (x++ / x--) updates env via the same shadowing model used by
assign — `(go-env-extend env name (+ current 1))`.
**Iterative fact(5) = 120 and the classic sum-to-9 = 45 both
evaluate.** Demonstrates the for-loop machinery is solid enough for
real programs.
eval 40/40, total 417/417.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -146,6 +146,55 @@
|
||||
(go-eval env (go-parse "fib(5)")))
|
||||
5)
|
||||
|
||||
(go-eval-test
|
||||
"for: count to 10 with sum"
|
||||
(let
|
||||
((env (go-eval-program go-env-empty (list (go-parse "var sum = 0") (go-parse "for i := 0; i < 10; i++ { sum = sum + i }")))))
|
||||
(go-env-lookup env "sum"))
|
||||
45)
|
||||
|
||||
(go-eval-test
|
||||
"inc-dec: x++ updates env"
|
||||
(let
|
||||
((env (go-eval-program (go-env-extend go-env-empty "x" 5) (list (go-parse "x++")))))
|
||||
(go-env-lookup env "x"))
|
||||
6)
|
||||
|
||||
(go-eval-test
|
||||
"inc-dec: x-- updates env"
|
||||
(let
|
||||
((env (go-eval-program (go-env-extend go-env-empty "x" 5) (list (go-parse "x--")))))
|
||||
(go-env-lookup env "x"))
|
||||
4)
|
||||
|
||||
(go-eval-test
|
||||
"for: break exits the loop"
|
||||
(let
|
||||
((env (go-eval-program go-env-empty (list (go-parse "var i = 0") (go-parse "for i < 100 { if i == 5 { break } ; i++ }")))))
|
||||
(go-env-lookup env "i"))
|
||||
5)
|
||||
|
||||
(go-eval-test
|
||||
"for: continue skips body but runs post"
|
||||
(let
|
||||
((env (go-eval-program go-env-empty (list (go-parse "var sum = 0") (go-parse "for i := 0; i < 5; i++ { if i == 2 { continue } ; sum = sum + i }")))))
|
||||
(go-env-lookup env "sum"))
|
||||
8)
|
||||
|
||||
(go-eval-test
|
||||
"for: infinite + break with sum"
|
||||
(let
|
||||
((env (go-eval-program go-env-empty (list (go-parse "var s = 0") (go-parse "var i = 1") (go-parse "for { if i > 4 { break } ; s = s + i ; i++ }")))))
|
||||
(go-env-lookup env "s"))
|
||||
10)
|
||||
|
||||
(go-eval-test
|
||||
"fn: iterative factorial via for-loop"
|
||||
(let
|
||||
((env (go-eval-program go-env-empty (list (go-parse "func fact(n int) int { r := 1 ; for i := 2 ; i <= n ; i++ { r = r * i } ; return r }")))))
|
||||
(go-eval env (go-parse "fact(5)")))
|
||||
120)
|
||||
|
||||
(define
|
||||
go-eval-test-summary
|
||||
(str "eval " go-eval-test-pass "/" go-eval-test-count))
|
||||
|
||||
Reference in New Issue
Block a user