1 package expr
2
3 import (
4 `fmt`
5 )
6
7
8 type Type int
9
10 const (
11
12 CONST Type = iota
13
14
15 TERM
16
17
18 EXPR
19 )
20
21 var typeNames = map[Type]string {
22 EXPR : "Expr",
23 TERM : "Term",
24 CONST : "Const",
25 }
26
27
28 func (self Type) String() string {
29 if v, ok := typeNames[self]; ok {
30 return v
31 } else {
32 return fmt.Sprintf("expr.Type(%d)", self)
33 }
34 }
35
36
37 type Operator uint8
38
39 const (
40
41 ADD Operator = iota
42
43
44 SUB
45
46
47 MUL
48
49
50 DIV
51
52
53 MOD
54
55
56 AND
57
58
59 OR
60
61
62 XOR
63
64
65 SHL
66
67
68 SHR
69
70
71 POW
72
73
74 NOT
75
76
77 NEG
78 )
79
80 var operatorNames = map[Operator]string {
81 ADD : "Add",
82 SUB : "Subtract",
83 MUL : "Multiply",
84 DIV : "Divide",
85 MOD : "Modulo",
86 AND : "And",
87 OR : "Or",
88 XOR : "ExclusiveOr",
89 SHL : "ShiftLeft",
90 SHR : "ShiftRight",
91 POW : "Power",
92 NOT : "Invert",
93 NEG : "Negate",
94 }
95
96
97 func (self Operator) String() string {
98 if v, ok := operatorNames[self]; ok {
99 return v
100 } else {
101 return fmt.Sprintf("expr.Operator(%d)", self)
102 }
103 }
104
105
106 type Expr struct {
107 Type Type
108 Term Term
109 Op Operator
110 Left *Expr
111 Right *Expr
112 Const int64
113 }
114
115
116 func Ref(t Term) (p *Expr) {
117 p = newExpression()
118 p.Term = t
119 p.Type = TERM
120 return
121 }
122
123
124 func Int(v int64) (p *Expr) {
125 p = newExpression()
126 p.Type = CONST
127 p.Const = v
128 return
129 }
130
131 func (self *Expr) clear() {
132 if self.Term != nil { self.Term.Free() }
133 if self.Left != nil { self.Left.Free() }
134 if self.Right != nil { self.Right.Free() }
135 }
136
137
138
139 func (self *Expr) Free() {
140 self.clear()
141 freeExpression(self)
142 }
143
144
145
146 func (self *Expr) Evaluate() (int64, error) {
147 switch self.Type {
148 case EXPR : return self.eval()
149 case TERM : return self.Term.Evaluate()
150 case CONST : return self.Const, nil
151 default : panic("invalid expression type: " + self.Type.String())
152 }
153 }
154
155
156
157 func combine(a *Expr, op Operator, b *Expr) (r *Expr) {
158 r = newExpression()
159 r.Op = op
160 r.Type = EXPR
161 r.Left = a
162 r.Right = b
163 return
164 }
165
166 func (self *Expr) Add(v *Expr) *Expr { return combine(self, ADD, v) }
167 func (self *Expr) Sub(v *Expr) *Expr { return combine(self, SUB, v) }
168 func (self *Expr) Mul(v *Expr) *Expr { return combine(self, MUL, v) }
169 func (self *Expr) Div(v *Expr) *Expr { return combine(self, DIV, v) }
170 func (self *Expr) Mod(v *Expr) *Expr { return combine(self, MOD, v) }
171 func (self *Expr) And(v *Expr) *Expr { return combine(self, AND, v) }
172 func (self *Expr) Or (v *Expr) *Expr { return combine(self, OR , v) }
173 func (self *Expr) Xor(v *Expr) *Expr { return combine(self, XOR, v) }
174 func (self *Expr) Shl(v *Expr) *Expr { return combine(self, SHL, v) }
175 func (self *Expr) Shr(v *Expr) *Expr { return combine(self, SHR, v) }
176 func (self *Expr) Pow(v *Expr) *Expr { return combine(self, POW, v) }
177 func (self *Expr) Not() *Expr { return combine(self, NOT, nil) }
178 func (self *Expr) Neg() *Expr { return combine(self, NEG, nil) }
179
180
181
182 var binaryEvaluators = [256]func(int64, int64) (int64, error) {
183 ADD: func(a, b int64) (int64, error) { return a + b, nil },
184 SUB: func(a, b int64) (int64, error) { return a - b, nil },
185 MUL: func(a, b int64) (int64, error) { return a * b, nil },
186 DIV: idiv,
187 MOD: imod,
188 AND: func(a, b int64) (int64, error) { return a & b, nil },
189 OR: func(a, b int64) (int64, error) { return a | b, nil },
190 XOR: func(a, b int64) (int64, error) { return a ^ b, nil },
191 SHL: func(a, b int64) (int64, error) { return a << b, nil },
192 SHR: func(a, b int64) (int64, error) { return a >> b, nil },
193 POW: ipow,
194 }
195
196 func (self *Expr) eval() (int64, error) {
197 var lhs int64
198 var rhs int64
199 var err error
200 var vfn func(int64, int64) (int64, error)
201
202
203 if lhs, err = self.Left.Evaluate(); err != nil {
204 return 0, err
205 }
206
207
208 switch self.Op {
209 case NOT: return self.unaryNot(lhs)
210 case NEG: return self.unaryNeg(lhs)
211 }
212
213
214 if vfn = binaryEvaluators[self.Op]; vfn == nil {
215 panic("invalid operator: " + self.Op.String())
216 }
217
218
219 if self.Right == nil {
220 panic("operator " + self.Op.String() + " is a binary operator")
221 }
222
223
224 if rhs, err = self.Right.Evaluate(); err != nil {
225 return 0, err
226 } else {
227 return vfn(lhs, rhs)
228 }
229 }
230
231 func (self *Expr) unaryNot(v int64) (int64, error) {
232 if self.Right == nil {
233 return ^v, nil
234 } else {
235 panic("operator Invert is an unary operator")
236 }
237 }
238
239 func (self *Expr) unaryNeg(v int64) (int64, error) {
240 if self.Right == nil {
241 return -v, nil
242 } else {
243 panic("operator Negate is an unary operator")
244 }
245 }
246
View as plain text