fix: continue statement was not applied correctly
This commit is contained in:
committed by
Traefiker Bot
parent
f1cde2be0f
commit
5381ee65d1
18
_test/for8.go
Normal file
18
_test/for8.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
for i := 0; i < 4; i++ {
|
||||
for {
|
||||
break
|
||||
}
|
||||
if i == 1 {
|
||||
continue
|
||||
}
|
||||
println(i)
|
||||
}
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 2
|
||||
// 3
|
||||
26
_test/primes.go
Normal file
26
_test/primes.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
func Primes(n int) int {
|
||||
var xs []int
|
||||
for i := 2; len(xs) < n; i++ {
|
||||
ok := true
|
||||
for _, x := range xs {
|
||||
if i%x == 0 {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
xs = append(xs, i)
|
||||
}
|
||||
return xs[n-1]
|
||||
}
|
||||
|
||||
func main() {
|
||||
println(Primes(3))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 5
|
||||
@@ -44,7 +44,6 @@ var identifier = regexp.MustCompile(`([\pL_][\pL_\d]*)$`)
|
||||
// Following this pass, the CFG is ready to run
|
||||
func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
sc, pkgName := interp.initScopePkg(root)
|
||||
var loop, loopRestart *node
|
||||
var initNodes []*node
|
||||
var iotaValue int
|
||||
var err error
|
||||
@@ -236,12 +235,12 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
}
|
||||
|
||||
case forStmt0, forRangeStmt:
|
||||
loop, loopRestart = n, n.child[0]
|
||||
sc = sc.pushBloc()
|
||||
sc.loop, sc.loopRestart = n, n.child[0]
|
||||
|
||||
case forStmt1, forStmt2, forStmt3, forStmt3a, forStmt4:
|
||||
loop, loopRestart = n, n.lastChild()
|
||||
sc = sc.pushBloc()
|
||||
sc.loop, sc.loopRestart = n, n.lastChild()
|
||||
|
||||
case funcLit:
|
||||
n.typ = nil // to force nodeType to recompute the type
|
||||
@@ -313,7 +312,7 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
c[i], c[l] = c[l], c[i]
|
||||
}
|
||||
sc = sc.pushBloc()
|
||||
loop = n
|
||||
sc.loop = n
|
||||
|
||||
case importSpec:
|
||||
var name, ipath string
|
||||
@@ -698,14 +697,14 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
if len(n.child) > 0 {
|
||||
gotoLabel(n.sym)
|
||||
} else {
|
||||
n.tnext = loop
|
||||
n.tnext = sc.loop
|
||||
}
|
||||
|
||||
case continueStmt:
|
||||
if len(n.child) > 0 {
|
||||
gotoLabel(n.sym)
|
||||
} else {
|
||||
n.tnext = loopRestart
|
||||
n.tnext = sc.loopRestart
|
||||
}
|
||||
|
||||
case gotoStmt:
|
||||
@@ -829,7 +828,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
body := n.child[0]
|
||||
n.start = body.start
|
||||
body.tnext = n.start
|
||||
loop, loopRestart = nil, nil
|
||||
sc = sc.pop()
|
||||
|
||||
case forStmt1: // for cond {}
|
||||
@@ -841,7 +839,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
cond.tnext = body.start
|
||||
cond.fnext = n
|
||||
body.tnext = cond.start
|
||||
loop, loopRestart = nil, nil
|
||||
sc = sc.pop()
|
||||
|
||||
case forStmt2: // for init; cond; {}
|
||||
@@ -854,7 +851,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
cond.tnext = body.start
|
||||
cond.fnext = n
|
||||
body.tnext = cond.start
|
||||
loop, loopRestart = nil, nil
|
||||
sc = sc.pop()
|
||||
|
||||
case forStmt3: // for ; cond; post {}
|
||||
@@ -867,7 +863,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
cond.fnext = n
|
||||
body.tnext = post.start
|
||||
post.tnext = cond.start
|
||||
loop, loopRestart = nil, nil
|
||||
sc = sc.pop()
|
||||
|
||||
case forStmt3a: // for int; ; post {}
|
||||
@@ -876,7 +871,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
init.tnext = body.start
|
||||
body.tnext = post.start
|
||||
post.tnext = body.start
|
||||
loop, loopRestart = nil, nil
|
||||
sc = sc.pop()
|
||||
|
||||
case forStmt4: // for init; cond; post {}
|
||||
@@ -890,11 +884,9 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
cond.fnext = n
|
||||
body.tnext = post.start
|
||||
post.tnext = cond.start
|
||||
loop, loopRestart = nil, nil
|
||||
sc = sc.pop()
|
||||
|
||||
case forRangeStmt:
|
||||
loop, loopRestart = nil, nil
|
||||
n.start = n.child[0].start
|
||||
n.child[0].fnext = n
|
||||
sc = sc.pop()
|
||||
@@ -1320,7 +1312,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
n.start = sbn.start
|
||||
}
|
||||
sc = sc.pop()
|
||||
loop = nil
|
||||
|
||||
case switchIfStmt: // like an if-else chain
|
||||
sbn := n.lastChild() // switch block node
|
||||
@@ -1357,7 +1348,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
n.start = sbn.start
|
||||
}
|
||||
sc = sc.pop()
|
||||
loop = nil
|
||||
|
||||
case typeAssertExpr:
|
||||
if len(n.child) > 1 {
|
||||
|
||||
@@ -74,12 +74,14 @@ type symbol struct {
|
||||
// execution to the index in frame, created exactly from the types layout.
|
||||
//
|
||||
type scope struct {
|
||||
anc *scope // Ancestor upper scope
|
||||
def *node // function definition node this scope belongs to, or nil
|
||||
types []reflect.Type // Frame layout, may be shared by same level scopes
|
||||
level int // Frame level: number of frame indirections to access var during execution
|
||||
sym map[string]*symbol // Map of symbols defined in this current scope
|
||||
global bool // true if scope refers to global space (single frame for universe and package level scopes)
|
||||
anc *scope // Ancestor upper scope
|
||||
def *node // function definition node this scope belongs to, or nil
|
||||
loop *node // loop exit node for break statement
|
||||
loopRestart *node // loop restart node for continue statement
|
||||
types []reflect.Type // Frame layout, may be shared by same level scopes
|
||||
level int // Frame level: number of frame indirections to access var during execution
|
||||
sym map[string]*symbol // Map of symbols defined in this current scope
|
||||
global bool // true if scope refers to global space (single frame for universe and package level scopes)
|
||||
}
|
||||
|
||||
// push creates a new scope and chain it to the current one
|
||||
@@ -95,6 +97,8 @@ func (s *scope) push(indirect bool) *scope {
|
||||
sc.global = s.global
|
||||
sc.level = s.level
|
||||
}
|
||||
// inherit loop state from ancestor
|
||||
sc.loop, sc.loopRestart = s.loop, s.loopRestart
|
||||
return &sc
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user