github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/expressions/exp07.go (about) 1 package expressions 2 3 import ( 4 "fmt" 5 "regexp" 6 "strings" 7 8 "github.com/lmorg/murex/lang/expressions/primitives" 9 "github.com/lmorg/murex/lang/expressions/symbols" 10 "github.com/lmorg/murex/lang/types" 11 ) 12 13 func expEqualFunc(tree *ParserT) (*primitives.DataType, error) { 14 left, right, err := tree.getLeftAndRightSymbols() 15 if err != nil { 16 return nil, err 17 } 18 19 lv, rv, err := compareTypes(tree, left, right) 20 if err != nil { 21 return nil, err 22 } 23 24 return primitives.NewPrimitive(primitives.Boolean, lv == rv), nil 25 } 26 27 func expEqualTo(tree *ParserT) error { 28 dt, err := expEqualFunc(tree) 29 if err != nil { 30 return err 31 } 32 33 return tree.foldAst(&astNodeT{ 34 key: symbols.Boolean, 35 pos: tree.ast[tree.astPos].pos, 36 dt: dt, 37 }) 38 } 39 40 func expNotEqualTo(tree *ParserT) error { 41 dt, err := expEqualFunc(tree) 42 if err != nil { 43 return err 44 } 45 46 dt.NotValue() 47 48 return tree.foldAst(&astNodeT{ 49 key: symbols.Boolean, 50 pos: tree.ast[tree.astPos].pos, 51 dt: dt, 52 }) 53 } 54 55 func expLike(tree *ParserT, eq bool) error { 56 leftNode, rightNode, err := tree.getLeftAndRightSymbols() 57 if err != nil { 58 return err 59 } 60 61 left, err := leftNode.dt.GetValue() 62 if err != nil { 63 return err 64 } 65 66 right, err := rightNode.dt.GetValue() 67 if err != nil { 68 return err 69 } 70 71 lv, rv := left.Value, right.Value 72 // convert to number, if possible 73 if left.Primitive == primitives.String { 74 if v, err := types.ConvertGoType(left.Value, types.Number); err == nil { 75 lv = v 76 } 77 } 78 if right.Primitive == primitives.String { 79 if v, err := types.ConvertGoType(right.Value, types.Number); err == nil { 80 rv = v 81 } 82 } 83 84 // convert to string 85 lv, err = types.ConvertGoType(lv, types.String) 86 if err != nil { 87 return raiseError(tree.expression, tree.currentSymbol(), 0, err.Error()) 88 } 89 rv, err = types.ConvertGoType(rv, types.String) 90 if err != nil { 91 return raiseError(tree.expression, tree.currentSymbol(), 0, err.Error()) 92 } 93 94 // trim and lowercase string 95 lv = strings.TrimSpace(strings.ToLower(lv.(string))) 96 rv = strings.TrimSpace(strings.ToLower(rv.(string))) 97 98 return tree.foldAst(&astNodeT{ 99 key: symbols.Boolean, 100 pos: tree.ast[tree.astPos].pos, 101 dt: primitives.NewPrimitive(primitives.Boolean, (lv == rv) == eq), 102 }) 103 } 104 105 func expRegexp(tree *ParserT, eq bool) error { 106 leftNode, rightNode, err := tree.getLeftAndRightSymbols() 107 if err != nil { 108 return err 109 } 110 111 left, err := leftNode.dt.GetValue() 112 if err != nil { 113 return err 114 } 115 116 right, err := rightNode.dt.GetValue() 117 if err != nil { 118 return err 119 } 120 121 var lv string 122 123 if tree.StrictTypes() { 124 if left.Primitive != primitives.String { 125 return raiseError(tree.expression, leftNode, 0, fmt.Sprintf( 126 "left side should be %s, instead received %s", 127 primitives.String, left.Primitive)) 128 } 129 lv = left.Value.(string) 130 } else { 131 v, err := types.ConvertGoType(left.Value, types.String) 132 if err != nil { 133 return fmt.Errorf("cannot convert left side %s into a %s: %s", 134 left.Primitive, primitives.String, err.Error()) 135 } 136 lv = v.(string) 137 } 138 139 if right.Primitive != primitives.String { 140 return raiseError(tree.expression, rightNode, 0, fmt.Sprintf( 141 "right side should be a regexp expression, instead received %s", 142 right.Primitive)) 143 } 144 145 rx, err := regexp.Compile(right.Value.(string)) 146 if err != nil { 147 return raiseError(tree.expression, rightNode, 0, err.Error()) 148 } 149 150 return tree.foldAst(&astNodeT{ 151 key: symbols.Boolean, 152 pos: tree.ast[tree.astPos].pos, 153 dt: primitives.NewPrimitive(primitives.Boolean, rx.MatchString(lv) == eq), 154 }) 155 }