-
Notifications
You must be signed in to change notification settings - Fork 0
/
loop.go
95 lines (84 loc) · 1.83 KB
/
loop.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package ego
import "go/ast"
func (s *Scope) execFor(stmt *ast.ForStmt, label string) (*Scope, *branch, error) {
origScope := s
if stmt.Init != nil {
var err error
s, _, err = s.Exec(stmt.Init) // No branching possible here, only "simple statments" allowed.
if err != nil {
return nil, nil, err
}
}
for {
if stmt.Cond != nil {
val, err := s.Eval1(stmt.Cond)
if err != nil {
return nil, nil, err
}
b, err := val.Bool()
if err != nil {
return nil, nil, err
}
if !b {
return origScope, nil, nil
}
}
_, b, err := s.ExecStmts(stmt.Body.List)
if err != nil {
return nil, nil, err
}
if b != nil {
switch b.typ {
case branchBreak:
if b.label == "" || b.label == label {
return origScope, nil, nil
}
case branchContinue:
if b.label != "" && b.label != label {
return origScope, b, nil
}
case branchGoto:
return origScope, b, nil
case branchFallthrough:
// xxx err
case branchReturn:
return origScope, b, nil
}
}
if stmt.Post != nil {
_, _, err = s.ExecStmt(stmt.Post)
if err != nil {
return nil, nil, err
}
}
}
}
func (s *Scope) execRange(stmt *ast.RangeStmt, label string) (*Scope, *branch, error) {
origScope := s
if stmt.Tok == token.DEFINE {
s = NewScope(s)
}
// xxx do not eval X if at most one iteration var is present and
// len(X) is constant (https://golang.org/ref/spec#RangeClause)
rexp, err := s.Eval1(stmt.X)
if err != nil {
return nil, nil, err
}
switch rexp.Kind() {
case refl.Array, refl.Slice, refl.String:
l, _ := rexp.Len()
for i := 0; i < l; i++ {
// xxx assign to key, value if present
_, b, err := s.ExecStmts(stmt.Body.List)
if err != nil {
return nil, nil, err
}
if b != nil {
// xxx
}
}
return origScope, nil, nil
case refl.Map:
case refl.Chan:
}
}