Skip to content

Commit

Permalink
Added Meta tag to Tokens to store the baked-in function names.
Browse files Browse the repository at this point in the history
  • Loading branch information
bhare committed Oct 15, 2018
1 parent 64cbc08 commit db9a73d
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 26 deletions.
14 changes: 5 additions & 9 deletions EvaluableExpression.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,20 +265,16 @@ func (this EvaluableExpression) String() string {
var expressionText string
for _, val := range this.Tokens() {
switch val.Kind {
case CLAUSE:
expressionText += fmt.Sprintf("%+v", "(")
case CLAUSE_CLOSE:
expressionText += fmt.Sprintf("%+v", ")")
case VARIABLE:
expressionText += fmt.Sprintf("[%+v]", val.Value)
expressionText += fmt.Sprintf("[%+v]", val.Meta)
case STRING, TIME:
expressionText += fmt.Sprintf("'%+v'", val.Value)
expressionText += fmt.Sprintf("'%+v'", val.Meta)
case COMPARATOR, LOGICALOP, MODIFIER, TERNARY:
expressionText += fmt.Sprintf(" %+v ", val.Value)
expressionText += fmt.Sprintf(" %+v ", val.Meta)
case SEPARATOR:
expressionText += fmt.Sprintf("%+v ", val.Value)
expressionText += fmt.Sprintf("%+v ", val.Meta)
default:
expressionText += fmt.Sprintf("%+v", val.Value)
expressionText += fmt.Sprintf("%+v", val.Meta)
}
}

Expand Down
1 change: 1 addition & 0 deletions ExpressionToken.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ package govaluate
type ExpressionToken struct {
Kind TokenKind
Value interface{}
Meta interface{}
}
19 changes: 12 additions & 7 deletions evaluationFailure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,27 @@ var EVALUATION_FAILURE_PARAMETERS = map[string]interface{}{
}

func TestFullCycle(test *testing.T) {
currentExpressionString := "2 > 1 &&" +
"'something' != 'nothing' || (1,2,3) != (3,2,1) ||" +
"'2014-01-20' < 'Wed Jul 8 23:07:35 MDT 2015' && " +
"[escapedVariable name with spaces] <= unescaped\\-variableName &&" +
"modifierTest + 1000 / 2 > (80 * 100 % 2) && true ? true : false"
currentExpressionString := "2 > 1 && " +
"'something' != 'nothing' || (1,2,3) != (3,2,1) || " +
"func1(1337,'leet',sawce) < 'Wed Jul 8 23:07:35 MDT 2015' && " +
"[escapedVariable name with spaces] <= unescaped\\-variableName && " +
"modifierTest + 0xa3a2b3 / 2 > (80 * 100 % 2) && true ? true : false"
extraFuncs := map[string]ExpressionFunction{
"func1": func(args ...interface{}) (interface{}, error) {
return "2014-01-20", nil
},
}

var initialExpression, cycledExpression, finalExpression *EvaluableExpression
initialExpression, err := NewEvaluableExpression(currentExpressionString)
initialExpression, err := NewEvaluableExpressionWithFunctions(currentExpressionString, extraFuncs)
if err != nil {
test.Errorf("Failed to build expression from string... ERROR: %+v", err)
}
cycledExpression, err = NewEvaluableExpressionFromTokens(initialExpression.Tokens())
if err != nil {
test.Errorf("Failed to build expression from tokens, from string... ERROR: %+v", err)
}
temp2, err := NewEvaluableExpression(cycledExpression.String())
temp2, err := NewEvaluableExpressionWithFunctions(cycledExpression.String(), extraFuncs)
if err != nil {
test.Errorf("Failed to build expression from string, from tokens, from string... ERROR: %+v", err)
}
Expand Down
27 changes: 17 additions & 10 deletions parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre
var found bool
var completed bool
var err error
var meta interface{}

// numeric is 0-9, or . or 0x followed by digits
// string starts with '
Expand All @@ -79,6 +80,7 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre
continue
}

meta = character
kind = UNKNOWN

// numeric constant
Expand All @@ -96,6 +98,7 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre
return ExpressionToken{}, errors.New(errorMsg), false
}

meta = "0x" + tokenString
kind = NUMERIC
tokenValue = float64(tokenValueInt)
break
Expand All @@ -111,6 +114,8 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre
errorMsg := fmt.Sprintf("Unable to parse numeric value '%v' to float64\n", tokenString)
return ExpressionToken{}, errors.New(errorMsg), false
}

meta = tokenString
kind = NUMERIC
break
}
Expand All @@ -119,6 +124,7 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre
if character == ',' {

tokenValue = ","
meta = tokenValue
kind = SEPARATOR
break
}
Expand All @@ -127,6 +133,7 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre
if character == '[' {

tokenValue, completed = readUntilFalse(stream, true, false, true, isNotClosingBracket)
meta = tokenValue
kind = VARIABLE

if !completed {
Expand All @@ -142,22 +149,15 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre
if unicode.IsLetter(character) {

tokenString = readTokenUntilFalse(stream, isVariableName)

meta = tokenString
tokenValue = tokenString
kind = VARIABLE

// boolean?
if tokenValue == "true" {
if tokenValue == "true" || tokenValue == "false" {

kind = BOOLEAN
tokenValue = true
} else {

if tokenValue == "false" {

kind = BOOLEAN
tokenValue = false
}
tokenValue = tokenValue == "true"
}

// textual operator?
Expand Down Expand Up @@ -205,6 +205,7 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre

if !isNotQuote(character) {
tokenValue, completed = readUntilFalse(stream, true, false, true, isNotQuote)
meta = tokenValue

if !completed {
return ExpressionToken{}, errors.New("Unclosed string literal"), false
Expand All @@ -225,19 +226,24 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre
}

if character == '(' {

meta = "("
tokenValue = character
kind = CLAUSE
break
}

if character == ')' {

meta = ")"
tokenValue = character
kind = CLAUSE_CLOSE
break
}

// must be a known symbol
tokenString = readTokenUntilFalse(stream, isNotAlphanumeric)
meta = tokenString
tokenValue = tokenString

// quick hack for the case where "-" can mean "prefixed negation" or "minus", which are used
Expand Down Expand Up @@ -284,6 +290,7 @@ func readToken(stream *lexerStream, state lexerState, functions map[string]Expre

ret.Kind = kind
ret.Value = tokenValue
ret.Meta = meta

return ret, nil, (kind != UNKNOWN)
}
Expand Down

0 comments on commit db9a73d

Please sign in to comment.