github.com/chenzhuoyu/iasm@v0.9.1/expr/ast.go (about) 1 package expr 2 3 import ( 4 `fmt` 5 ) 6 7 // Type is tyep expression type. 8 type Type int 9 10 const ( 11 // CONST indicates that the expression is a constant. 12 CONST Type = iota 13 14 // TERM indicates that the expression is a Term reference. 15 TERM 16 17 // EXPR indicates that the expression is a unary or binary expression. 18 EXPR 19 ) 20 21 var typeNames = map[Type]string { 22 EXPR : "Expr", 23 TERM : "Term", 24 CONST : "Const", 25 } 26 27 // String returns the string representation of a Type. 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 // Operator represents an operation to perform when Type is EXPR. 37 type Operator uint8 38 39 const ( 40 // ADD performs "Add Expr.Left and Expr.Right". 41 ADD Operator = iota 42 43 // SUB performs "Subtract Expr.Left by Expr.Right". 44 SUB 45 46 // MUL performs "Multiply Expr.Left by Expr.Right". 47 MUL 48 49 // DIV performs "Divide Expr.Left by Expr.Right". 50 DIV 51 52 // MOD performs "Modulo Expr.Left by Expr.Right". 53 MOD 54 55 // AND performs "Bitwise AND Expr.Left and Expr.Right". 56 AND 57 58 // OR performs "Bitwise OR Expr.Left and Expr.Right". 59 OR 60 61 // XOR performs "Bitwise XOR Expr.Left and Expr.Right". 62 XOR 63 64 // SHL performs "Bitwise Shift Expr.Left to the Left by Expr.Right Bits". 65 SHL 66 67 // SHR performs "Bitwise Shift Expr.Left to the Right by Expr.Right Bits". 68 SHR 69 70 // POW performs "Raise Expr.Left to the power of Expr.Right" 71 POW 72 73 // NOT performs "Bitwise Invert Expr.Left". 74 NOT 75 76 // NEG performs "Negate Expr.Left". 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 // String returns the string representation of a Type. 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 // Expr represents an expression node. 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 // Ref creates an expression from a Term. 116 func Ref(t Term) (p *Expr) { 117 p = newExpression() 118 p.Term = t 119 p.Type = TERM 120 return 121 } 122 123 // Int creates an expression from an integer. 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 // Free returns the Expr into pool. 138 // Any operation performed after Free is undefined behavior. 139 func (self *Expr) Free() { 140 self.clear() 141 freeExpression(self) 142 } 143 144 // Evaluate evaluates the expression into an integer. 145 // It also implements the Term interface. 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 /** Expression Combinator **/ 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 /** Expression Evaluator **/ 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 /* evaluate LHS */ 203 if lhs, err = self.Left.Evaluate(); err != nil { 204 return 0, err 205 } 206 207 /* check for unary operators */ 208 switch self.Op { 209 case NOT: return self.unaryNot(lhs) 210 case NEG: return self.unaryNeg(lhs) 211 } 212 213 /* check for operators */ 214 if vfn = binaryEvaluators[self.Op]; vfn == nil { 215 panic("invalid operator: " + self.Op.String()) 216 } 217 218 /* must be a binary expression */ 219 if self.Right == nil { 220 panic("operator " + self.Op.String() + " is a binary operator") 221 } 222 223 /* evaluate RHS, and call the operator */ 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 }