forked from zjryan/e8vm
/
bool_op.go
71 lines (54 loc) · 1.31 KB
/
bool_op.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
package g8
import (
"e8vm.io/e8vm/g8/tast"
"e8vm.io/e8vm/g8/types"
)
func binaryOpBool(b *builder, op string, A, B *ref) *ref {
switch op {
case "==", "!=":
ret := b.newTemp(types.Bool)
b.b.Arith(ret.IR(), A.IR(), op, B.IR())
return ret
}
panic("bug")
}
func buildLogicAnd(b *builder, A *ref, B tast.Expr) *ref {
blockB := b.f.NewBlock(b.b)
retFalse := b.f.NewBlock(blockB)
after := b.f.NewBlock(retFalse)
ret := b.newTemp(types.Bool)
b.b.JumpIfNot(A.IR(), retFalse)
// evaluate expression B
b.b = blockB
refB := b.buildExpr(B)
b.b.Assign(ret.IR(), refB.IR()) // and save it as result
b.b.Jump(after)
retFalse.Assign(ret.IR(), refFalse.IR())
retFalse.Jump(after)
b.b = after
return ret
}
func buildLogicOr(b *builder, A *ref, B tast.Expr) *ref {
blockB := b.f.NewBlock(b.b)
retTrue := b.f.NewBlock(blockB)
after := b.f.NewBlock(retTrue)
ret := b.newTemp(types.Bool)
b.b.JumpIf(A.IR(), retTrue)
// evaluate expression B
b.b = blockB
refB := b.buildExpr(B)
b.b.Assign(ret.IR(), refB.IR()) // and save it as result
b.b.Jump(after)
retTrue.Assign(ret.IR(), refTrue.IR())
retTrue.Jump(after)
b.b = after
return ret
}
func unaryOpBool(b *builder, op string, B *ref) *ref {
if op != "!" {
panic("bug")
}
ret := b.newTemp(types.Bool)
b.b.Arith(ret.IR(), nil, op, B.IR())
return ret
}