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  }