...

Source file src/github.com/PaesslerAG/gval/operator.go

Documentation: github.com/PaesslerAG/gval

     1  package gval
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"reflect"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/shopspring/decimal"
    11  )
    12  
    13  type stage struct {
    14  	Evaluable
    15  	infixBuilder
    16  	operatorPrecedence
    17  }
    18  
    19  type stageStack []stage //operatorPrecedence in stacktStage is continuously, monotone ascending
    20  
    21  func (s *stageStack) push(b stage) error {
    22  	for len(*s) > 0 && s.peek().operatorPrecedence >= b.operatorPrecedence {
    23  		a := s.pop()
    24  		eval, err := a.infixBuilder(a.Evaluable, b.Evaluable)
    25  		if err != nil {
    26  			return err
    27  		}
    28  		if a.IsConst() && b.IsConst() {
    29  			v, err := eval(nil, nil)
    30  			if err != nil {
    31  				return err
    32  			}
    33  			b.Evaluable = constant(v)
    34  			continue
    35  		}
    36  		b.Evaluable = eval
    37  	}
    38  	*s = append(*s, b)
    39  	return nil
    40  }
    41  
    42  func (s *stageStack) peek() stage {
    43  	return (*s)[len(*s)-1]
    44  }
    45  
    46  func (s *stageStack) pop() stage {
    47  	a := s.peek()
    48  	(*s) = (*s)[:len(*s)-1]
    49  	return a
    50  }
    51  
    52  type infixBuilder func(a, b Evaluable) (Evaluable, error)
    53  
    54  func (l Language) isSymbolOperation(r rune) bool {
    55  	_, in := l.operatorSymbols[r]
    56  	return in
    57  }
    58  
    59  func (l Language) isOperatorPrefix(op string) bool {
    60  	for k := range l.operators {
    61  		if strings.HasPrefix(k, op) {
    62  			return true
    63  		}
    64  	}
    65  	return false
    66  }
    67  
    68  func (op *infix) initiate(name string) {
    69  	f := func(a, b interface{}) (interface{}, error) {
    70  		return nil, fmt.Errorf("invalid operation (%T) %s (%T)", a, name, b)
    71  	}
    72  	if op.arbitrary != nil {
    73  		f = op.arbitrary
    74  	}
    75  	for _, typeConvertion := range []bool{true, false} {
    76  		if op.text != nil && (!typeConvertion || op.arbitrary == nil) {
    77  			f = getStringOpFunc(op.text, f, typeConvertion)
    78  		}
    79  		if op.boolean != nil {
    80  			f = getBoolOpFunc(op.boolean, f, typeConvertion)
    81  		}
    82  		if op.number != nil {
    83  			f = getFloatOpFunc(op.number, f, typeConvertion)
    84  		}
    85  		if op.decimal != nil {
    86  			f = getDecimalOpFunc(op.decimal, f, typeConvertion)
    87  		}
    88  	}
    89  	if op.shortCircuit == nil {
    90  		op.builder = func(a, b Evaluable) (Evaluable, error) {
    91  			return func(c context.Context, x interface{}) (interface{}, error) {
    92  				a, err := a(c, x)
    93  				if err != nil {
    94  					return nil, err
    95  				}
    96  				b, err := b(c, x)
    97  				if err != nil {
    98  					return nil, err
    99  				}
   100  				return f(a, b)
   101  			}, nil
   102  		}
   103  		return
   104  	}
   105  	shortF := op.shortCircuit
   106  	op.builder = func(a, b Evaluable) (Evaluable, error) {
   107  		return func(c context.Context, x interface{}) (interface{}, error) {
   108  			a, err := a(c, x)
   109  			if err != nil {
   110  				return nil, err
   111  			}
   112  			if r, ok := shortF(a); ok {
   113  				return r, nil
   114  			}
   115  			b, err := b(c, x)
   116  			if err != nil {
   117  				return nil, err
   118  			}
   119  			return f(a, b)
   120  		}, nil
   121  	}
   122  }
   123  
   124  type opFunc func(a, b interface{}) (interface{}, error)
   125  
   126  func getStringOpFunc(s func(a, b string) (interface{}, error), f opFunc, typeConversion bool) opFunc {
   127  	if typeConversion {
   128  		return func(a, b interface{}) (interface{}, error) {
   129  			if a != nil && b != nil {
   130  				return s(fmt.Sprintf("%v", a), fmt.Sprintf("%v", b))
   131  			}
   132  			return f(a, b)
   133  		}
   134  	}
   135  	return func(a, b interface{}) (interface{}, error) {
   136  		s1, k := a.(string)
   137  		s2, l := b.(string)
   138  		if k && l {
   139  			return s(s1, s2)
   140  		}
   141  		return f(a, b)
   142  	}
   143  }
   144  func convertToBool(o interface{}) (bool, bool) {
   145  	if b, ok := o.(bool); ok {
   146  		return b, true
   147  	}
   148  	v := reflect.ValueOf(o)
   149  	for o != nil && v.Kind() == reflect.Ptr {
   150  		v = v.Elem()
   151  		if !v.IsValid() {
   152  			return false, false
   153  		}
   154  		o = v.Interface()
   155  	}
   156  	if o == false || o == nil || o == "false" || o == "FALSE" {
   157  		return false, true
   158  	}
   159  	if o == true || o == "true" || o == "TRUE" {
   160  		return true, true
   161  	}
   162  	if f, ok := convertToFloat(o); ok {
   163  		return f != 0., true
   164  	}
   165  	return false, false
   166  }
   167  func getBoolOpFunc(o func(a, b bool) (interface{}, error), f opFunc, typeConversion bool) opFunc {
   168  	if typeConversion {
   169  		return func(a, b interface{}) (interface{}, error) {
   170  			x, k := convertToBool(a)
   171  			y, l := convertToBool(b)
   172  			if k && l {
   173  				return o(x, y)
   174  			}
   175  			return f(a, b)
   176  		}
   177  	}
   178  	return func(a, b interface{}) (interface{}, error) {
   179  		x, k := a.(bool)
   180  		y, l := b.(bool)
   181  		if k && l {
   182  			return o(x, y)
   183  		}
   184  		return f(a, b)
   185  	}
   186  }
   187  func convertToFloat(o interface{}) (float64, bool) {
   188  	if i, ok := o.(float64); ok {
   189  		return i, true
   190  	}
   191  	v := reflect.ValueOf(o)
   192  	for o != nil && v.Kind() == reflect.Ptr {
   193  		v = v.Elem()
   194  		if !v.IsValid() {
   195  			return 0, false
   196  		}
   197  		o = v.Interface()
   198  	}
   199  	switch v.Kind() {
   200  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   201  		return float64(v.Int()), true
   202  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   203  		return float64(v.Uint()), true
   204  	case reflect.Float32, reflect.Float64:
   205  		return v.Float(), true
   206  	}
   207  	if s, ok := o.(string); ok {
   208  		f, err := strconv.ParseFloat(s, 64)
   209  		if err == nil {
   210  			return f, true
   211  		}
   212  	}
   213  	return 0, false
   214  }
   215  func getFloatOpFunc(o func(a, b float64) (interface{}, error), f opFunc, typeConversion bool) opFunc {
   216  	if typeConversion {
   217  		return func(a, b interface{}) (interface{}, error) {
   218  			x, k := convertToFloat(a)
   219  			y, l := convertToFloat(b)
   220  			if k && l {
   221  				return o(x, y)
   222  			}
   223  
   224  			return f(a, b)
   225  		}
   226  	}
   227  	return func(a, b interface{}) (interface{}, error) {
   228  		x, k := a.(float64)
   229  		y, l := b.(float64)
   230  		if k && l {
   231  			return o(x, y)
   232  		}
   233  
   234  		return f(a, b)
   235  	}
   236  }
   237  func convertToDecimal(o interface{}) (decimal.Decimal, bool) {
   238  	if i, ok := o.(decimal.Decimal); ok {
   239  		return i, true
   240  	}
   241  	if i, ok := o.(float64); ok {
   242  		return decimal.NewFromFloat(i), true
   243  	}
   244  	v := reflect.ValueOf(o)
   245  	for o != nil && v.Kind() == reflect.Ptr {
   246  		v = v.Elem()
   247  		if !v.IsValid() {
   248  			return decimal.Zero, false
   249  		}
   250  		o = v.Interface()
   251  	}
   252  	switch v.Kind() {
   253  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   254  		return decimal.NewFromInt(v.Int()), true
   255  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   256  		return decimal.NewFromFloat(float64(v.Uint())), true
   257  	case reflect.Float32, reflect.Float64:
   258  		return decimal.NewFromFloat(v.Float()), true
   259  	}
   260  	if s, ok := o.(string); ok {
   261  		f, err := strconv.ParseFloat(s, 64)
   262  		if err == nil {
   263  			return decimal.NewFromFloat(f), true
   264  		}
   265  	}
   266  	return decimal.Zero, false
   267  }
   268  func getDecimalOpFunc(o func(a, b decimal.Decimal) (interface{}, error), f opFunc, typeConversion bool) opFunc {
   269  	if typeConversion {
   270  		return func(a, b interface{}) (interface{}, error) {
   271  			x, k := convertToDecimal(a)
   272  			y, l := convertToDecimal(b)
   273  			if k && l {
   274  				return o(x, y)
   275  			}
   276  
   277  			return f(a, b)
   278  		}
   279  	}
   280  	return func(a, b interface{}) (interface{}, error) {
   281  		x, k := a.(decimal.Decimal)
   282  		y, l := b.(decimal.Decimal)
   283  		if k && l {
   284  			return o(x, y)
   285  		}
   286  
   287  		return f(a, b)
   288  	}
   289  }
   290  
   291  type operator interface {
   292  	merge(operator) operator
   293  	precedence() operatorPrecedence
   294  	initiate(name string)
   295  }
   296  
   297  type operatorPrecedence uint8
   298  
   299  func (pre operatorPrecedence) merge(op operator) operator {
   300  	if op, ok := op.(operatorPrecedence); ok {
   301  		if op > pre {
   302  			return op
   303  		}
   304  		return pre
   305  	}
   306  	if op == nil {
   307  		return pre
   308  	}
   309  	return op.merge(pre)
   310  }
   311  
   312  func (pre operatorPrecedence) precedence() operatorPrecedence {
   313  	return pre
   314  }
   315  
   316  func (pre operatorPrecedence) initiate(name string) {}
   317  
   318  type infix struct {
   319  	operatorPrecedence
   320  	number       func(a, b float64) (interface{}, error)
   321  	decimal      func(a, b decimal.Decimal) (interface{}, error)
   322  	boolean      func(a, b bool) (interface{}, error)
   323  	text         func(a, b string) (interface{}, error)
   324  	arbitrary    func(a, b interface{}) (interface{}, error)
   325  	shortCircuit func(a interface{}) (interface{}, bool)
   326  	builder      infixBuilder
   327  }
   328  
   329  func (op infix) merge(op2 operator) operator {
   330  	switch op2 := op2.(type) {
   331  	case *infix:
   332  		if op.number == nil {
   333  			op.number = op2.number
   334  		}
   335  		if op.decimal == nil {
   336  			op.decimal = op2.decimal
   337  		}
   338  		if op.boolean == nil {
   339  			op.boolean = op2.boolean
   340  		}
   341  		if op.text == nil {
   342  			op.text = op2.text
   343  		}
   344  		if op.arbitrary == nil {
   345  			op.arbitrary = op2.arbitrary
   346  		}
   347  		if op.shortCircuit == nil {
   348  			op.shortCircuit = op2.shortCircuit
   349  		}
   350  	}
   351  	if op2 != nil && op2.precedence() > op.operatorPrecedence {
   352  		op.operatorPrecedence = op2.precedence()
   353  	}
   354  	return &op
   355  }
   356  
   357  type directInfix struct {
   358  	operatorPrecedence
   359  	infixBuilder
   360  }
   361  
   362  func (op directInfix) merge(op2 operator) operator {
   363  	switch op2 := op2.(type) {
   364  	case operatorPrecedence:
   365  		op.operatorPrecedence = op2
   366  	}
   367  	if op2 != nil && op2.precedence() > op.operatorPrecedence {
   368  		op.operatorPrecedence = op2.precedence()
   369  	}
   370  	return op
   371  }
   372  
   373  type extension func(context.Context, *Parser) (Evaluable, error)
   374  
   375  type postfix struct {
   376  	operatorPrecedence
   377  	f func(context.Context, *Parser, Evaluable, operatorPrecedence) (Evaluable, error)
   378  }
   379  
   380  func (op postfix) merge(op2 operator) operator {
   381  	switch op2 := op2.(type) {
   382  	case postfix:
   383  		if op2.f != nil {
   384  			op.f = op2.f
   385  		}
   386  	}
   387  	if op2 != nil && op2.precedence() > op.operatorPrecedence {
   388  		op.operatorPrecedence = op2.precedence()
   389  	}
   390  	return op
   391  }
   392  

View as plain text