forked from zjryan/e8vm
/
for.go
72 lines (56 loc) · 1.13 KB
/
for.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
package g8
import (
"e8vm.io/e8vm/g8/tast"
)
func buildForStmt(b *builder, stmt *tast.ForStmt) {
if stmt.Init != nil {
b.buildStmt(stmt.Init)
}
if stmt.Cond == nil {
body := b.f.NewBlock(b.b)
iter := b.f.NewBlock(body)
after := b.f.NewBlock(iter)
iter.Jump(body)
b.b = body
b.breaks.push(after, "")
b.continues.push(iter, "")
b.buildStmt(stmt.Body)
b.breaks.pop()
b.continues.pop()
b.b = iter
if stmt.Iter != nil {
b.buildStmt(stmt.Iter)
}
b.b = after
return
}
condBlock := b.f.NewBlock(b.b)
body := b.f.NewBlock(condBlock)
iter := b.f.NewBlock(body)
after := b.f.NewBlock(iter)
iter.Jump(condBlock)
b.b = condBlock
c := b.buildExpr(stmt.Cond)
b.b.JumpIfNot(c.IR(), after)
b.b = body
b.breaks.push(after, "")
b.continues.push(iter, "")
b.buildStmt(stmt.Body)
b.breaks.pop()
b.continues.pop()
b.b = iter
if stmt.Iter != nil {
b.buildStmt(stmt.Iter)
}
b.b = after
}
func buildContinueStmt(b *builder) {
after := b.f.NewBlock(b.b)
b.b.Jump(b.continues.top())
b.b = after
}
func buildBreakStmt(b *builder) {
after := b.f.NewBlock(b.b)
b.b.Jump(b.breaks.top())
b.b = after
}