...

Source file src/github.com/cloudwego/iasm/expr/ast.go

Documentation: github.com/cloudwego/iasm/expr

     1  //
     2  // Copyright 2024 CloudWeGo Authors
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package expr
    18  
    19  import (
    20      `fmt`
    21  )
    22  
    23  // Type is tyep expression type.
    24  type Type int
    25  
    26  const (
    27      // CONST indicates that the expression is a constant.
    28      CONST Type = iota
    29  
    30      // TERM indicates that the expression is a Term reference.
    31      TERM
    32  
    33      // EXPR indicates that the expression is a unary or binary expression.
    34      EXPR
    35  )
    36  
    37  var typeNames = map[Type]string {
    38      EXPR  : "Expr",
    39      TERM  : "Term",
    40      CONST : "Const",
    41  }
    42  
    43  // String returns the string representation of a Type.
    44  func (self Type) String() string {
    45      if v, ok := typeNames[self]; ok {
    46          return v
    47      } else {
    48          return fmt.Sprintf("expr.Type(%d)", self)
    49      }
    50  }
    51  
    52  // Operator represents an operation to perform when Type is EXPR.
    53  type Operator uint8
    54  
    55  const (
    56      // ADD performs "Add Expr.Left and Expr.Right".
    57      ADD Operator = iota
    58  
    59      // SUB performs "Subtract Expr.Left by Expr.Right".
    60      SUB
    61  
    62      // MUL performs "Multiply Expr.Left by Expr.Right".
    63      MUL
    64  
    65      // DIV performs "Divide Expr.Left by Expr.Right".
    66      DIV
    67  
    68      // MOD performs "Modulo Expr.Left by Expr.Right".
    69      MOD
    70  
    71      // AND performs "Bitwise AND Expr.Left and Expr.Right".
    72      AND
    73  
    74      // OR performs "Bitwise OR Expr.Left and Expr.Right".
    75      OR
    76  
    77      // XOR performs "Bitwise XOR Expr.Left and Expr.Right".
    78      XOR
    79  
    80      // SHL performs "Bitwise Shift Expr.Left to the Left by Expr.Right Bits".
    81      SHL
    82  
    83      // SHR performs "Bitwise Shift Expr.Left to the Right by Expr.Right Bits".
    84      SHR
    85  
    86      // POW performs "Raise Expr.Left to the power of Expr.Right"
    87      POW
    88  
    89      // NOT performs "Bitwise Invert Expr.Left".
    90      NOT
    91  
    92      // NEG performs "Negate Expr.Left".
    93      NEG
    94  )
    95  
    96  var operatorNames = map[Operator]string {
    97      ADD : "Add",
    98      SUB : "Subtract",
    99      MUL : "Multiply",
   100      DIV : "Divide",
   101      MOD : "Modulo",
   102      AND : "And",
   103      OR  : "Or",
   104      XOR : "ExclusiveOr",
   105      SHL : "ShiftLeft",
   106      SHR : "ShiftRight",
   107      POW : "Power",
   108      NOT : "Invert",
   109      NEG : "Negate",
   110  }
   111  
   112  // String returns the string representation of a Type.
   113  func (self Operator) String() string {
   114      if v, ok := operatorNames[self]; ok {
   115          return v
   116      } else {
   117          return fmt.Sprintf("expr.Operator(%d)", self)
   118      }
   119  }
   120  
   121  // Expr represents an expression node.
   122  type Expr struct {
   123      Type  Type
   124      Term  Term
   125      Op    Operator
   126      Left  *Expr
   127      Right *Expr
   128      Const int64
   129  }
   130  
   131  // Ref creates an expression from a Term.
   132  func Ref(t Term) (p *Expr) {
   133      p = newExpression()
   134      p.Term = t
   135      p.Type = TERM
   136      return
   137  }
   138  
   139  // Int creates an expression from an integer.
   140  func Int(v int64) (p *Expr) {
   141      p = newExpression()
   142      p.Type = CONST
   143      p.Const = v
   144      return
   145  }
   146  
   147  func (self *Expr) clear() {
   148      if self.Term != nil  { self.Term.Free() }
   149      if self.Left != nil  { self.Left.Free() }
   150      if self.Right != nil { self.Right.Free() }
   151  }
   152  
   153  // Free returns the Expr into pool.
   154  // Any operation performed after Free is undefined behavior.
   155  func (self *Expr) Free() {
   156      self.clear()
   157      freeExpression(self)
   158  }
   159  
   160  // Evaluate evaluates the expression into an integer.
   161  // It also implements the Term interface.
   162  func (self *Expr) Evaluate() (int64, error) {
   163      switch self.Type {
   164          case EXPR  : return self.eval()
   165          case TERM  : return self.Term.Evaluate()
   166          case CONST : return self.Const, nil
   167          default    : panic("invalid expression type: " + self.Type.String())
   168      }
   169  }
   170  
   171  /** Expression Combinator **/
   172  
   173  func combine(a *Expr, op Operator, b *Expr) (r *Expr) {
   174      r = newExpression()
   175      r.Op = op
   176      r.Type = EXPR
   177      r.Left = a
   178      r.Right = b
   179      return
   180  }
   181  
   182  func (self *Expr) Add(v *Expr) *Expr { return combine(self, ADD, v) }
   183  func (self *Expr) Sub(v *Expr) *Expr { return combine(self, SUB, v) }
   184  func (self *Expr) Mul(v *Expr) *Expr { return combine(self, MUL, v) }
   185  func (self *Expr) Div(v *Expr) *Expr { return combine(self, DIV, v) }
   186  func (self *Expr) Mod(v *Expr) *Expr { return combine(self, MOD, v) }
   187  func (self *Expr) And(v *Expr) *Expr { return combine(self, AND, v) }
   188  func (self *Expr) Or (v *Expr) *Expr { return combine(self, OR , v) }
   189  func (self *Expr) Xor(v *Expr) *Expr { return combine(self, XOR, v) }
   190  func (self *Expr) Shl(v *Expr) *Expr { return combine(self, SHL, v) }
   191  func (self *Expr) Shr(v *Expr) *Expr { return combine(self, SHR, v) }
   192  func (self *Expr) Pow(v *Expr) *Expr { return combine(self, POW, v) }
   193  func (self *Expr) Not()        *Expr { return combine(self, NOT, nil) }
   194  func (self *Expr) Neg()        *Expr { return combine(self, NEG, nil) }
   195  
   196  /** Expression Evaluator **/
   197  
   198  var binaryEvaluators = [256]func(int64, int64) (int64, error) {
   199      ADD: func(a, b int64) (int64, error) { return a + b, nil },
   200      SUB: func(a, b int64) (int64, error) { return a - b, nil },
   201      MUL: func(a, b int64) (int64, error) { return a * b, nil },
   202      DIV: idiv,
   203      MOD: imod,
   204      AND: func(a, b int64) (int64, error) { return a & b, nil },
   205       OR: func(a, b int64) (int64, error) { return a | b, nil },
   206      XOR: func(a, b int64) (int64, error) { return a ^ b, nil },
   207      SHL: func(a, b int64) (int64, error) { return a << b, nil },
   208      SHR: func(a, b int64) (int64, error) { return a >> b, nil },
   209      POW: ipow,
   210  }
   211  
   212  func (self *Expr) eval() (int64, error) {
   213      var lhs int64
   214      var rhs int64
   215      var err error
   216      var vfn func(int64, int64) (int64, error)
   217  
   218      /* evaluate LHS */
   219      if lhs, err = self.Left.Evaluate(); err != nil {
   220          return 0, err
   221      }
   222  
   223      /* check for unary operators */
   224      switch self.Op {
   225          case NOT: return self.unaryNot(lhs)
   226          case NEG: return self.unaryNeg(lhs)
   227      }
   228  
   229      /* check for operators */
   230      if vfn = binaryEvaluators[self.Op]; vfn == nil {
   231          panic("invalid operator: " + self.Op.String())
   232      }
   233  
   234      /* must be a binary expression */
   235      if self.Right == nil {
   236          panic("operator " + self.Op.String() + " is a binary operator")
   237      }
   238  
   239      /* evaluate RHS, and call the operator */
   240      if rhs, err = self.Right.Evaluate(); err != nil {
   241          return 0, err
   242      } else {
   243          return vfn(lhs, rhs)
   244      }
   245  }
   246  
   247  func (self *Expr) unaryNot(v int64) (int64, error) {
   248      if self.Right == nil {
   249          return ^v, nil
   250      } else {
   251          panic("operator Invert is an unary operator")
   252      }
   253  }
   254  
   255  func (self *Expr) unaryNeg(v int64) (int64, error) {
   256      if self.Right == nil {
   257          return -v, nil
   258      } else {
   259          panic("operator Negate is an unary operator")
   260      }
   261  }
   262  

View as plain text