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
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