Skip to content

Commit 76a10cb

Browse files
committed
extract loop evaluators from control runtime
1 parent eb0a5dc commit 76a10cb

3 files changed

Lines changed: 161 additions & 161 deletions

File tree

docs/architecture.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Key files:
3535
- `vibes/execution_blocks.go` (block literal creation and block/yield invocation)
3636
- `vibes/execution_operators.go` (unary/index/binary operator evaluation)
3737
- `vibes/execution_control.go` (range/case/loop/try evaluation)
38+
- `vibes/execution_loops.go` (`for`/`while`/`until` loop execution)
3839
- `vibes/execution_try_raise.go` (raise/try-rescue-ensure execution flow)
3940
- `vibes/execution_rescue_types.go` (rescue type matching and control-signal classification helpers)
4041
- `vibes/execution_errors.go` (runtime error model, wrapping, and quota/signal sentinels)

vibes/execution_control.go

Lines changed: 0 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package vibes
22

3-
import (
4-
"errors"
5-
)
6-
73
func (exec *Execution) evalRangeExpr(expr *RangeExpr, env *Env) (Value, error) {
84
startVal, err := exec.evalExpression(expr.Start, env)
95
if err != nil {
@@ -74,160 +70,3 @@ func (exec *Execution) evalCaseExpr(expr *CaseExpr, env *Env) (Value, error) {
7470

7571
return NewNil(), nil
7672
}
77-
78-
func (exec *Execution) evalForStatement(stmt *ForStmt, env *Env) (Value, bool, error) {
79-
exec.loopDepth++
80-
defer func() {
81-
exec.loopDepth--
82-
}()
83-
84-
iterable, err := exec.evalExpression(stmt.Iterable, env)
85-
if err != nil {
86-
return NewNil(), false, err
87-
}
88-
if err := exec.checkMemoryWith(iterable); err != nil {
89-
return NewNil(), false, err
90-
}
91-
last := NewNil()
92-
93-
switch iterable.Kind() {
94-
case KindArray:
95-
arr := iterable.Array()
96-
for _, item := range arr {
97-
env.Assign(stmt.Iterator, item)
98-
val, returned, err := exec.evalStatements(stmt.Body, env)
99-
if err != nil {
100-
if errors.Is(err, errLoopBreak) {
101-
return last, false, nil
102-
}
103-
if errors.Is(err, errLoopNext) {
104-
continue
105-
}
106-
return NewNil(), false, err
107-
}
108-
if returned {
109-
return val, true, nil
110-
}
111-
last = val
112-
}
113-
case KindRange:
114-
r := iterable.Range()
115-
if r.Start <= r.End {
116-
for i := r.Start; i <= r.End; i++ {
117-
env.Assign(stmt.Iterator, NewInt(i))
118-
val, returned, err := exec.evalStatements(stmt.Body, env)
119-
if err != nil {
120-
if errors.Is(err, errLoopBreak) {
121-
return last, false, nil
122-
}
123-
if errors.Is(err, errLoopNext) {
124-
continue
125-
}
126-
return NewNil(), false, err
127-
}
128-
if returned {
129-
return val, true, nil
130-
}
131-
last = val
132-
}
133-
} else {
134-
for i := r.Start; i >= r.End; i-- {
135-
env.Assign(stmt.Iterator, NewInt(i))
136-
val, returned, err := exec.evalStatements(stmt.Body, env)
137-
if err != nil {
138-
if errors.Is(err, errLoopBreak) {
139-
return last, false, nil
140-
}
141-
if errors.Is(err, errLoopNext) {
142-
continue
143-
}
144-
return NewNil(), false, err
145-
}
146-
if returned {
147-
return val, true, nil
148-
}
149-
last = val
150-
}
151-
}
152-
default:
153-
return NewNil(), false, exec.errorAt(stmt.Pos(), "cannot iterate over %s", iterable.Kind())
154-
}
155-
156-
return last, false, nil
157-
}
158-
159-
func (exec *Execution) evalWhileStatement(stmt *WhileStmt, env *Env) (Value, bool, error) {
160-
exec.loopDepth++
161-
defer func() {
162-
exec.loopDepth--
163-
}()
164-
165-
last := NewNil()
166-
for {
167-
if err := exec.step(); err != nil {
168-
return NewNil(), false, exec.wrapError(err, stmt.Pos())
169-
}
170-
condition, err := exec.evalExpression(stmt.Condition, env)
171-
if err != nil {
172-
return NewNil(), false, err
173-
}
174-
if err := exec.checkMemoryWith(condition); err != nil {
175-
return NewNil(), false, err
176-
}
177-
if !condition.Truthy() {
178-
return last, false, nil
179-
}
180-
val, returned, err := exec.evalStatements(stmt.Body, env)
181-
if err != nil {
182-
if errors.Is(err, errLoopBreak) {
183-
return last, false, nil
184-
}
185-
if errors.Is(err, errLoopNext) {
186-
continue
187-
}
188-
return NewNil(), false, err
189-
}
190-
if returned {
191-
return val, true, nil
192-
}
193-
last = val
194-
}
195-
}
196-
197-
func (exec *Execution) evalUntilStatement(stmt *UntilStmt, env *Env) (Value, bool, error) {
198-
exec.loopDepth++
199-
defer func() {
200-
exec.loopDepth--
201-
}()
202-
203-
last := NewNil()
204-
for {
205-
if err := exec.step(); err != nil {
206-
return NewNil(), false, exec.wrapError(err, stmt.Pos())
207-
}
208-
condition, err := exec.evalExpression(stmt.Condition, env)
209-
if err != nil {
210-
return NewNil(), false, err
211-
}
212-
if err := exec.checkMemoryWith(condition); err != nil {
213-
return NewNil(), false, err
214-
}
215-
if condition.Truthy() {
216-
return last, false, nil
217-
}
218-
val, returned, err := exec.evalStatements(stmt.Body, env)
219-
if err != nil {
220-
if errors.Is(err, errLoopBreak) {
221-
return last, false, nil
222-
}
223-
if errors.Is(err, errLoopNext) {
224-
continue
225-
}
226-
return NewNil(), false, err
227-
}
228-
if returned {
229-
return val, true, nil
230-
}
231-
last = val
232-
}
233-
}

vibes/execution_loops.go

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package vibes
2+
3+
import "errors"
4+
5+
func (exec *Execution) evalForStatement(stmt *ForStmt, env *Env) (Value, bool, error) {
6+
exec.loopDepth++
7+
defer func() {
8+
exec.loopDepth--
9+
}()
10+
11+
iterable, err := exec.evalExpression(stmt.Iterable, env)
12+
if err != nil {
13+
return NewNil(), false, err
14+
}
15+
if err := exec.checkMemoryWith(iterable); err != nil {
16+
return NewNil(), false, err
17+
}
18+
last := NewNil()
19+
20+
switch iterable.Kind() {
21+
case KindArray:
22+
arr := iterable.Array()
23+
for _, item := range arr {
24+
env.Assign(stmt.Iterator, item)
25+
val, returned, err := exec.evalStatements(stmt.Body, env)
26+
if err != nil {
27+
if errors.Is(err, errLoopBreak) {
28+
return last, false, nil
29+
}
30+
if errors.Is(err, errLoopNext) {
31+
continue
32+
}
33+
return NewNil(), false, err
34+
}
35+
if returned {
36+
return val, true, nil
37+
}
38+
last = val
39+
}
40+
case KindRange:
41+
r := iterable.Range()
42+
if r.Start <= r.End {
43+
for i := r.Start; i <= r.End; i++ {
44+
env.Assign(stmt.Iterator, NewInt(i))
45+
val, returned, err := exec.evalStatements(stmt.Body, env)
46+
if err != nil {
47+
if errors.Is(err, errLoopBreak) {
48+
return last, false, nil
49+
}
50+
if errors.Is(err, errLoopNext) {
51+
continue
52+
}
53+
return NewNil(), false, err
54+
}
55+
if returned {
56+
return val, true, nil
57+
}
58+
last = val
59+
}
60+
} else {
61+
for i := r.Start; i >= r.End; i-- {
62+
env.Assign(stmt.Iterator, NewInt(i))
63+
val, returned, err := exec.evalStatements(stmt.Body, env)
64+
if err != nil {
65+
if errors.Is(err, errLoopBreak) {
66+
return last, false, nil
67+
}
68+
if errors.Is(err, errLoopNext) {
69+
continue
70+
}
71+
return NewNil(), false, err
72+
}
73+
if returned {
74+
return val, true, nil
75+
}
76+
last = val
77+
}
78+
}
79+
default:
80+
return NewNil(), false, exec.errorAt(stmt.Pos(), "cannot iterate over %s", iterable.Kind())
81+
}
82+
83+
return last, false, nil
84+
}
85+
86+
func (exec *Execution) evalWhileStatement(stmt *WhileStmt, env *Env) (Value, bool, error) {
87+
exec.loopDepth++
88+
defer func() {
89+
exec.loopDepth--
90+
}()
91+
92+
last := NewNil()
93+
for {
94+
if err := exec.step(); err != nil {
95+
return NewNil(), false, exec.wrapError(err, stmt.Pos())
96+
}
97+
condition, err := exec.evalExpression(stmt.Condition, env)
98+
if err != nil {
99+
return NewNil(), false, err
100+
}
101+
if err := exec.checkMemoryWith(condition); err != nil {
102+
return NewNil(), false, err
103+
}
104+
if !condition.Truthy() {
105+
return last, false, nil
106+
}
107+
val, returned, err := exec.evalStatements(stmt.Body, env)
108+
if err != nil {
109+
if errors.Is(err, errLoopBreak) {
110+
return last, false, nil
111+
}
112+
if errors.Is(err, errLoopNext) {
113+
continue
114+
}
115+
return NewNil(), false, err
116+
}
117+
if returned {
118+
return val, true, nil
119+
}
120+
last = val
121+
}
122+
}
123+
124+
func (exec *Execution) evalUntilStatement(stmt *UntilStmt, env *Env) (Value, bool, error) {
125+
exec.loopDepth++
126+
defer func() {
127+
exec.loopDepth--
128+
}()
129+
130+
last := NewNil()
131+
for {
132+
if err := exec.step(); err != nil {
133+
return NewNil(), false, exec.wrapError(err, stmt.Pos())
134+
}
135+
condition, err := exec.evalExpression(stmt.Condition, env)
136+
if err != nil {
137+
return NewNil(), false, err
138+
}
139+
if err := exec.checkMemoryWith(condition); err != nil {
140+
return NewNil(), false, err
141+
}
142+
if condition.Truthy() {
143+
return last, false, nil
144+
}
145+
val, returned, err := exec.evalStatements(stmt.Body, env)
146+
if err != nil {
147+
if errors.Is(err, errLoopBreak) {
148+
return last, false, nil
149+
}
150+
if errors.Is(err, errLoopNext) {
151+
continue
152+
}
153+
return NewNil(), false, err
154+
}
155+
if returned {
156+
return val, true, nil
157+
}
158+
last = val
159+
}
160+
}

0 commit comments

Comments
 (0)