go: eval.sx — range-over-{slice,map,chan} + 7 tests; break-env fix [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 30s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 30s
Phase 5 cont. New go-eval-range-for handles the parser's :range-for
AST shape. Dispatches on the collection's runtime type:
:go-slice → bind index + element, iterate by position
:go-map → bind key + value, walk entries assoc list
:go-chan → bind value, drain until buffer empty (v0 limitation)
Each loop carries:
- go-range-extend: handles 0/1/2-name binding patterns uniformly
- go-range-body: evaluates body whether it's a :block or other shape
- per-collection loop helper: threads env, catches :break/:continue/
:return-value/:eval-error sentinels
**Subtle break fix:** loops were previously returning the *pre-loop*
env when break fired, clobbering all assignments made in prior
iterations. Now returns the current iteration's input env (which
carries forward successful iterations' state). Patched for the three
range variants and for the regular for-loop where the same pattern
applied. The shape:
(= r :break) env ;; was: (= r :break) original-env
Tests:
range: slice — sum of 1..5 = 15
range: slice — key only (index)
range: map — sum values
range: channel — collect all buffered
range: slice with break exits early
range: slice with continue skips an element
range: empty slice — body never runs
range: chan + goroutine producer
runtime 26/26, total 483/483.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -152,6 +152,62 @@
|
||||
(go-env-lookup env "result"))
|
||||
7)
|
||||
|
||||
(go-rt-test
|
||||
"range: slice — sum of 1..5"
|
||||
(let
|
||||
((env (go-eval-program go-env-builtins (list (go-parse "var sum = 0") (go-parse "a := []int{1, 2, 3, 4, 5}") (go-parse "for i, v := range a { sum = sum + v }")))))
|
||||
(go-env-lookup env "sum"))
|
||||
15)
|
||||
|
||||
(go-rt-test
|
||||
"range: slice — key only (index)"
|
||||
(let
|
||||
((env (go-eval-program go-env-builtins (list (go-parse "var s = 0") (go-parse "a := []int{10, 20, 30}") (go-parse "for i := range a { s = s + i }")))))
|
||||
(go-env-lookup env "s"))
|
||||
3)
|
||||
|
||||
(go-rt-test
|
||||
"range: map — sum values"
|
||||
(let
|
||||
((env (go-eval-program go-env-builtins (list (go-parse "var s = 0") (go-parse "m := map[string]int{\"a\": 1, \"b\": 2, \"c\": 3}") (go-parse "for k, v := range m { s = s + v }")))))
|
||||
(go-env-lookup env "s"))
|
||||
6)
|
||||
|
||||
(go-rt-test
|
||||
"range: channel — collect all buffered"
|
||||
(let
|
||||
((env (go-eval-program go-env-builtins (list (go-parse "ch := make()") (go-parse "ch <- 1") (go-parse "ch <- 2") (go-parse "ch <- 3") (go-parse "var sum = 0") (go-parse "for v := range ch { sum = sum + v }")))))
|
||||
(go-env-lookup env "sum"))
|
||||
6)
|
||||
|
||||
(go-rt-test
|
||||
"range: slice with break exits early"
|
||||
(let
|
||||
((env (go-eval-program go-env-builtins (list (go-parse "var s = 0") (go-parse "a := []int{1, 2, 3, 4, 5}") (go-parse "for i, v := range a { if v == 3 { break } ; s = s + v }")))))
|
||||
(go-env-lookup env "s"))
|
||||
3)
|
||||
|
||||
(go-rt-test
|
||||
"range: slice with continue skips an element"
|
||||
(let
|
||||
((env (go-eval-program go-env-builtins (list (go-parse "var s = 0") (go-parse "a := []int{1, 2, 3, 4, 5}") (go-parse "for i, v := range a { if v == 3 { continue } ; s = s + v }")))))
|
||||
(go-env-lookup env "s"))
|
||||
12)
|
||||
|
||||
(go-rt-test
|
||||
"range: empty slice — body never runs"
|
||||
(let
|
||||
((env (go-eval-program go-env-builtins (list (go-parse "var s = 0") (go-parse "a := []int{}") (go-parse "for v := range a { s = s + v }")))))
|
||||
(go-env-lookup env "s"))
|
||||
0)
|
||||
|
||||
(go-rt-test
|
||||
"range: chan + goroutine producer"
|
||||
(let
|
||||
((env (go-eval-program go-env-builtins (list (go-parse "func emit(c chan int) { c <- 10 ; c <- 20 ; c <- 30 }") (go-parse "ch := make()") (go-parse "go emit(ch)") (go-parse "var total = 0") (go-parse "for v := range ch { total = total + v }")))))
|
||||
(go-env-lookup env "total"))
|
||||
60)
|
||||
|
||||
(define
|
||||
go-rt-test-summary
|
||||
(str "runtime " go-rt-test-pass "/" go-rt-test-count))
|
||||
|
||||
Reference in New Issue
Block a user