Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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
|
// Following this pass, the CFG is ready to run
|
||||||
func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||||
sc, pkgName := interp.initScopePkg(root)
|
sc, pkgName := interp.initScopePkg(root)
|
||||||
var loop, loopRestart *node
|
|
||||||
var initNodes []*node
|
var initNodes []*node
|
||||||
var iotaValue int
|
var iotaValue int
|
||||||
var err error
|
var err error
|
||||||
@@ -236,12 +235,12 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case forStmt0, forRangeStmt:
|
case forStmt0, forRangeStmt:
|
||||||
loop, loopRestart = n, n.child[0]
|
|
||||||
sc = sc.pushBloc()
|
sc = sc.pushBloc()
|
||||||
|
sc.loop, sc.loopRestart = n, n.child[0]
|
||||||
|
|
||||||
case forStmt1, forStmt2, forStmt3, forStmt3a, forStmt4:
|
case forStmt1, forStmt2, forStmt3, forStmt3a, forStmt4:
|
||||||
loop, loopRestart = n, n.lastChild()
|
|
||||||
sc = sc.pushBloc()
|
sc = sc.pushBloc()
|
||||||
|
sc.loop, sc.loopRestart = n, n.lastChild()
|
||||||
|
|
||||||
case funcLit:
|
case funcLit:
|
||||||
n.typ = nil // to force nodeType to recompute the type
|
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]
|
c[i], c[l] = c[l], c[i]
|
||||||
}
|
}
|
||||||
sc = sc.pushBloc()
|
sc = sc.pushBloc()
|
||||||
loop = n
|
sc.loop = n
|
||||||
|
|
||||||
case importSpec:
|
case importSpec:
|
||||||
var name, ipath string
|
var name, ipath string
|
||||||
@@ -698,14 +697,14 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
if len(n.child) > 0 {
|
if len(n.child) > 0 {
|
||||||
gotoLabel(n.sym)
|
gotoLabel(n.sym)
|
||||||
} else {
|
} else {
|
||||||
n.tnext = loop
|
n.tnext = sc.loop
|
||||||
}
|
}
|
||||||
|
|
||||||
case continueStmt:
|
case continueStmt:
|
||||||
if len(n.child) > 0 {
|
if len(n.child) > 0 {
|
||||||
gotoLabel(n.sym)
|
gotoLabel(n.sym)
|
||||||
} else {
|
} else {
|
||||||
n.tnext = loopRestart
|
n.tnext = sc.loopRestart
|
||||||
}
|
}
|
||||||
|
|
||||||
case gotoStmt:
|
case gotoStmt:
|
||||||
@@ -829,7 +828,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
body := n.child[0]
|
body := n.child[0]
|
||||||
n.start = body.start
|
n.start = body.start
|
||||||
body.tnext = n.start
|
body.tnext = n.start
|
||||||
loop, loopRestart = nil, nil
|
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
|
|
||||||
case forStmt1: // for cond {}
|
case forStmt1: // for cond {}
|
||||||
@@ -841,7 +839,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
cond.tnext = body.start
|
cond.tnext = body.start
|
||||||
cond.fnext = n
|
cond.fnext = n
|
||||||
body.tnext = cond.start
|
body.tnext = cond.start
|
||||||
loop, loopRestart = nil, nil
|
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
|
|
||||||
case forStmt2: // for init; cond; {}
|
case forStmt2: // for init; cond; {}
|
||||||
@@ -854,7 +851,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
cond.tnext = body.start
|
cond.tnext = body.start
|
||||||
cond.fnext = n
|
cond.fnext = n
|
||||||
body.tnext = cond.start
|
body.tnext = cond.start
|
||||||
loop, loopRestart = nil, nil
|
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
|
|
||||||
case forStmt3: // for ; cond; post {}
|
case forStmt3: // for ; cond; post {}
|
||||||
@@ -867,7 +863,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
cond.fnext = n
|
cond.fnext = n
|
||||||
body.tnext = post.start
|
body.tnext = post.start
|
||||||
post.tnext = cond.start
|
post.tnext = cond.start
|
||||||
loop, loopRestart = nil, nil
|
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
|
|
||||||
case forStmt3a: // for int; ; post {}
|
case forStmt3a: // for int; ; post {}
|
||||||
@@ -876,7 +871,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
init.tnext = body.start
|
init.tnext = body.start
|
||||||
body.tnext = post.start
|
body.tnext = post.start
|
||||||
post.tnext = body.start
|
post.tnext = body.start
|
||||||
loop, loopRestart = nil, nil
|
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
|
|
||||||
case forStmt4: // for init; cond; post {}
|
case forStmt4: // for init; cond; post {}
|
||||||
@@ -890,11 +884,9 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
cond.fnext = n
|
cond.fnext = n
|
||||||
body.tnext = post.start
|
body.tnext = post.start
|
||||||
post.tnext = cond.start
|
post.tnext = cond.start
|
||||||
loop, loopRestart = nil, nil
|
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
|
|
||||||
case forRangeStmt:
|
case forRangeStmt:
|
||||||
loop, loopRestart = nil, nil
|
|
||||||
n.start = n.child[0].start
|
n.start = n.child[0].start
|
||||||
n.child[0].fnext = n
|
n.child[0].fnext = n
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
@@ -1320,7 +1312,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
n.start = sbn.start
|
n.start = sbn.start
|
||||||
}
|
}
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
loop = nil
|
|
||||||
|
|
||||||
case switchIfStmt: // like an if-else chain
|
case switchIfStmt: // like an if-else chain
|
||||||
sbn := n.lastChild() // switch block node
|
sbn := n.lastChild() // switch block node
|
||||||
@@ -1357,7 +1348,6 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
n.start = sbn.start
|
n.start = sbn.start
|
||||||
}
|
}
|
||||||
sc = sc.pop()
|
sc = sc.pop()
|
||||||
loop = nil
|
|
||||||
|
|
||||||
case typeAssertExpr:
|
case typeAssertExpr:
|
||||||
if len(n.child) > 1 {
|
if len(n.child) > 1 {
|
||||||
|
|||||||
@@ -74,12 +74,14 @@ type symbol struct {
|
|||||||
// execution to the index in frame, created exactly from the types layout.
|
// execution to the index in frame, created exactly from the types layout.
|
||||||
//
|
//
|
||||||
type scope struct {
|
type scope struct {
|
||||||
anc *scope // Ancestor upper scope
|
anc *scope // Ancestor upper scope
|
||||||
def *node // function definition node this scope belongs to, or nil
|
def *node // function definition node this scope belongs to, or nil
|
||||||
types []reflect.Type // Frame layout, may be shared by same level scopes
|
loop *node // loop exit node for break statement
|
||||||
level int // Frame level: number of frame indirections to access var during execution
|
loopRestart *node // loop restart node for continue statement
|
||||||
sym map[string]*symbol // Map of symbols defined in this current scope
|
types []reflect.Type // Frame layout, may be shared by same level scopes
|
||||||
global bool // true if scope refers to global space (single frame for universe and package 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
|
// 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.global = s.global
|
||||||
sc.level = s.level
|
sc.level = s.level
|
||||||
}
|
}
|
||||||
|
// inherit loop state from ancestor
|
||||||
|
sc.loop, sc.loopRestart = s.loop, s.loopRestart
|
||||||
return &sc
|
return &sc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user