github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/expressions/exp00_generics.go (about) 1 package expressions 2 3 import ( 4 "fmt" 5 6 "github.com/lmorg/murex/lang/expressions/primitives" 7 "github.com/lmorg/murex/lang/types" 8 ) 9 10 func validateNumericalDataTypes(tree *ParserT, leftNode *astNodeT, rightNode *astNodeT, operation *astNodeT) (float64, float64, error) { 11 left, err := leftNode.dt.GetValue() 12 if err != nil { 13 return 0, 0, err 14 } 15 right, err := rightNode.dt.GetValue() 16 if err != nil { 17 return 0, 0, err 18 } 19 20 if tree.StrictTypes() { 21 switch { 22 case left.Primitive != primitives.Number: 23 return 0, 0, raiseError(tree.expression, leftNode, 0, fmt.Sprintf( 24 "cannot %s with %s types", tree.currentSymbol().key, left.Primitive, 25 )) 26 case right.Primitive != primitives.Number: 27 return 0, 0, raiseError(tree.expression, rightNode, 0, fmt.Sprintf( 28 "cannot %s with %s types", tree.currentSymbol().key, right.Primitive, 29 )) 30 default: 31 var lv, rv float64 32 switch t := left.Value.(type) { 33 case float64: 34 lv = t 35 case int: 36 lv = float64(t) 37 default: 38 return 0, 0, raiseError(tree.expression, leftNode, 0, fmt.Sprintf( 39 "value cannot be converted into an integer nor floating point number\nUnderlying data type: %T", t, 40 )) 41 } 42 43 switch t := right.Value.(type) { 44 case float64: 45 rv = t 46 case int: 47 rv = float64(t) 48 default: 49 return 0, 0, raiseError(tree.expression, rightNode, 0, fmt.Sprintf( 50 "value cannot be converted into an integer nor floating point number\nUnderlying data type: %T", t, 51 )) 52 } 53 return lv, rv, nil 54 } 55 } 56 57 lv, err := types.ConvertGoType(left.Value, types.Number) 58 if err != nil { 59 return 0, 0, raiseError(tree.expression, leftNode, 0, err.Error()) 60 } 61 62 rv, err := types.ConvertGoType(right.Value, types.Number) 63 if err != nil { 64 return 0, 0, raiseError(tree.expression, rightNode, 0, err.Error()) 65 } 66 67 return lv.(float64), rv.(float64), nil 68 } 69 70 func compareTypes(tree *ParserT, leftNode *astNodeT, rightNode *astNodeT) (interface{}, interface{}, error) { 71 left, err := leftNode.dt.GetValue() 72 if err != nil { 73 return nil, nil, err 74 } 75 right, err := rightNode.dt.GetValue() 76 if err != nil { 77 return nil, nil, err 78 } 79 80 if tree.StrictTypes() { 81 if left.Primitive != right.Primitive { 82 return nil, nil, raiseError(tree.expression, tree.currentSymbol(), 0, fmt.Sprintf( 83 "cannot compare %s with %s", left.Primitive, right.Primitive, 84 )) 85 } 86 return left.Value, right.Value, nil 87 } 88 89 if left.Primitive == right.Primitive { 90 return left.Value, right.Value, nil 91 } 92 93 if left.Primitive == primitives.Number || right.Primitive == primitives.Number { 94 lv, lErr := types.ConvertGoType(left.Value, types.Number) 95 rv, rErr := types.ConvertGoType(right.Value, types.Number) 96 if lErr == nil && rErr == nil { 97 return lv, rv, nil 98 } 99 } 100 101 lv, err := types.ConvertGoType(left.Value, types.String) 102 if err != nil { 103 return nil, nil, err 104 } 105 106 rv, err := types.ConvertGoType(right.Value, types.String) 107 if err != nil { 108 return nil, nil, err 109 } 110 111 return lv, rv, nil 112 }