github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/expressions/expression.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/expressions/symbols" 8 "github.com/lmorg/murex/utils/consts" 9 ) 10 11 func (tree *ParserT) executeExpr() (*primitives.DataType, error) { 12 err := tree.validateExpression(true) 13 if err != nil { 14 return nil, err 15 } 16 17 for i := range orderOfOperations { 18 err = executeExpression(tree, orderOfOperations[i]) 19 if err != nil { 20 return nil, err 21 } 22 } 23 24 if len(tree.ast) > 1 { 25 return nil, fmt.Errorf( 26 "expression failed to execute correctly (AST results > 1).\n%s", 27 consts.IssueTrackerURL) 28 } 29 30 return tree.ast[0].dt, nil 31 } 32 33 // To allow for extendability and developer expectations, the order of operations 34 // will follow what is defined by (for example) C, as outlined in the following: 35 // https://en.wikipedia.org/wiki/Order_of_operations#Programming_languages 36 // Not all operations will be available in murex and some are likely to be added 37 // in future versions of this package. 38 // 39 // Please also note that the slice below is just defining the groupings. Each 40 // operator within the _same_ group will then be processed from left to right. 41 // Read the `executeExpression` function further down this source file to view 42 // every supported operator 43 var orderOfOperations = []symbols.Exp{ 44 // 01. Function call, scope, array/member access 45 // 02. (most) unary operators, sizeof and type casts (right to left) 46 // 03. Multiplication, division, modulo 47 symbols.Multiply, 48 49 // 04. Addition and subtraction 50 symbols.Add, 51 52 // 05. Bitwise shift left and right 53 // 06. Comparisons: less-than and greater-than 54 symbols.GreaterThan, 55 56 // 07. Comparisons: equal and not equal 57 symbols.EqualTo, 58 59 // 08. Bitwise AND 60 // 09. Bitwise exclusive OR (XOR) 61 // 10. Bitwise inclusive (normal) OR 62 // 11. Logical AND 63 symbols.LogicalAnd, 64 65 // 12. Logical OR 66 symbols.LogicalOr, 67 68 // 13. Conditional expression (ternary) 69 symbols.Elvis, 70 71 // 14. Assignment operators (right to left) 72 symbols.Assign, 73 74 // 15. Comma operator 75 } 76 77 func executeExpression(tree *ParserT, order symbols.Exp) (err error) { 78 for tree.astPos = 0; tree.astPos < len(tree.ast); tree.astPos++ { 79 node := tree.ast[tree.astPos] 80 81 if node.key < order { 82 continue 83 } 84 85 switch node.key { 86 87 // 15. Comma operator 88 // 14. Assignment operators (right to left) 89 case symbols.Assign: 90 err = expAssign(tree, true) 91 case symbols.AssignUpdate: 92 err = expAssign(tree, false) 93 case symbols.AssignAndAdd: 94 err = expAssignAdd(tree) 95 case symbols.AssignAndSubtract: 96 err = expAssignAndOperate(tree, _assSub) 97 case symbols.AssignAndDivide: 98 err = expAssignAndOperate(tree, _assDiv) 99 case symbols.AssignAndMultiply: 100 err = expAssignAndOperate(tree, _assMulti) 101 case symbols.AssignAndMerge: 102 err = expAssignMerge(tree) 103 104 // 13. Conditional expression (ternary) 105 case symbols.NullCoalescing: 106 err = expNullCoalescing(tree) 107 case symbols.Elvis: 108 err = expElvis(tree) 109 110 // 12. Logical OR 111 case symbols.LogicalOr: 112 err = expLogicalOr(tree) 113 114 // 11. Logical AND 115 case symbols.LogicalAnd: 116 err = expLogicalAnd(tree) 117 118 // 10. Bitwise inclusive (normal) OR 119 // 09. Bitwise exclusive OR (XOR) 120 // 08. Bitwise AND 121 // 07. Comparisons: equal and not equal 122 case symbols.EqualTo: 123 err = expEqualTo(tree) 124 case symbols.NotEqualTo: 125 err = expNotEqualTo(tree) 126 case symbols.Like: 127 err = expLike(tree, true) 128 case symbols.NotLike: 129 err = expLike(tree, false) 130 case symbols.Regexp: 131 err = expRegexp(tree, true) 132 case symbols.NotRegexp: 133 err = expRegexp(tree, false) 134 135 // 06. Comparisons: less-than and greater-than 136 case symbols.GreaterThan: 137 err = expGtLt(tree, _gtF, _gtS) 138 case symbols.GreaterThanOrEqual: 139 err = expGtLt(tree, _gtEqF, _gtEqS) 140 case symbols.LessThan: 141 err = expGtLt(tree, _ltF, _ltS) 142 case symbols.LessThanOrEqual: 143 err = expGtLt(tree, _ltEqF, _ltEqS) 144 145 // 05. Bitwise shift left and right 146 // 04. Addition and subtraction 147 case symbols.Add: 148 err = expAdd(tree) 149 case symbols.Subtract: 150 err = expSubtract(tree) 151 case symbols.MergeInto: 152 err = expMergeInto(tree) 153 154 // 03. Multiplication, division, modulo 155 case symbols.Multiply: 156 err = expMultiply(tree) 157 case symbols.Divide: 158 err = expDivide(tree) 159 160 // 02. (most) unary operators, sizeof and type casts (right to left) 161 // 01. Function call, scope, array/member access 162 163 default: 164 err = raiseError(tree.expression, node, 0, fmt.Sprintf( 165 "no code written to handle symbol (%s)", 166 consts.IssueTrackerURL)) 167 } 168 169 if err != nil { 170 return err 171 } 172 173 tree.astPos = 0 174 } 175 176 return nil 177 }