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  }