github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/expressions/validate.go (about) 1 package expressions 2 3 import ( 4 "fmt" 5 6 "github.com/lmorg/murex/lang/expressions/symbols" 7 ) 8 9 func (tree *ParserT) validateExpression(exec bool) error { 10 // compile data types and check for errors in the AST 11 // 12 // first walk to ensure we have a: 13 // value, expression, value, expression, value....etc 14 15 if tree.charPos < 0 { 16 tree.charPos = 0 17 } 18 19 if len(tree.ast) == 0 { 20 return fmt.Errorf("missing expression: '%s'", string(tree.expression[:tree.charPos])) 21 } 22 23 if len(tree.ast) == 1 && 24 (tree.ast[0].key == symbols.Bareword || tree.ast[0].key == symbols.SubExpressionBegin || 25 tree.ast[0].key == symbols.QuoteSingle || tree.ast[0].key == symbols.QuoteDouble) { 26 if tree.charPos+1 > len(tree.expression) { 27 tree.charPos-- 28 } 29 return fmt.Errorf("not an expression: '%s'", string(tree.expression[:tree.charPos+1])) 30 } 31 32 var expectValue bool 33 34 for tree.astPos = 0; tree.astPos < len(tree.ast); tree.astPos++ { 35 prev := tree.prevSymbol() 36 node := tree.ast[tree.astPos] 37 next := tree.nextSymbol() 38 39 expectValue = !expectValue 40 41 // check for errors raised by the parser 42 if node.key < symbols.DataValues { 43 return raiseError(tree.expression, node, 0, errMessage[node.key]) 44 } 45 46 // check each operation has a left side and right side data value 47 if expectValue { 48 if (node.key < symbols.DataValues) || 49 node.key > symbols.Operations { 50 return raiseError(tree.expression, node, 0, "expecting a data value") 51 } 52 53 if node.dt != nil { 54 continue 55 } 56 primitive, err := node2primitive(node) 57 if err != nil { 58 return err 59 } 60 node.dt = primitive 61 62 } else { 63 if node.key < symbols.Operations { 64 return raiseError(tree.expression, node, 0, "expecting an operation") 65 } 66 67 switch node.key { 68 case symbols.Add, symbols.GreaterThan, symbols.LessThan: 69 if prev == nil || prev.key == symbols.Bareword || 70 next == nil || next.key == symbols.Bareword { 71 return raiseError(tree.expression, node, 0, fmt.Sprintf("cannot %s barewords", node.key)) 72 } 73 74 case symbols.Subtract, symbols.Divide, symbols.Multiply: 75 if prev == nil || (prev.key != symbols.Number && prev.key != symbols.Calculated && prev.key != symbols.SubExpressionBegin && prev.key != symbols.Scalar) || 76 next == nil || (next.key != symbols.Number && next.key != symbols.Calculated && next.key != symbols.SubExpressionBegin && next.key != symbols.Scalar) { 77 return raiseError(tree.expression, node, 0, fmt.Sprintf("cannot %s non-numeric data types", node.key)) 78 } 79 } 80 } 81 82 } 83 84 if !expectValue { 85 return raiseError(tree.expression, tree.ast[len(tree.ast)-1], 0, "unexpected end of expression") 86 } 87 88 return nil 89 }