From 7aa6061a924917bbdf72d414fdcf9acae5745050 Mon Sep 17 00:00:00 2001 From: George Lester Date: Sun, 17 Jun 2018 12:20:17 -0700 Subject: [PATCH 1/3] fixed case where logical operators could be hanging if followed by clause-close --- lexerState.go | 1 - parsingFailure_test.go | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lexerState.go b/lexerState.go index 6726e90..4698be4 100644 --- a/lexerState.go +++ b/lexerState.go @@ -221,7 +221,6 @@ var validLexerStates = []lexerState{ STRING, TIME, CLAUSE, - CLAUSE_CLOSE, }, }, lexerState{ diff --git a/parsingFailure_test.go b/parsingFailure_test.go index d8a3184..f335b5e 100644 --- a/parsingFailure_test.go +++ b/parsingFailure_test.go @@ -76,6 +76,12 @@ func TestParsingFailure(test *testing.T) { Input: "10 > 5 &&", Expected: UNEXPECTED_END, }, + ParsingFailureTest{ + + Name: "Hanging logical operation, followed by clause-close (#92)", + Input: "(amount > '100' &&) == false", + Expected: INVALID_TOKEN_TRANSITION, + }, ParsingFailureTest{ Name: "Premature end to expression, via ternary operator", From a564c5afba37580f1b43079b97bacc5029aa1cf2 Mon Sep 17 00:00:00 2001 From: Hossein Karimy Date: Wed, 11 Jul 2018 18:15:19 -0400 Subject: [PATCH 2/3] Passing parameters to functions --- evaluationStage.go | 6 +++--- expressionFunctions.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/evaluationStage.go b/evaluationStage.go index 11ea587..efff386 100644 --- a/evaluationStage.go +++ b/evaluationStage.go @@ -235,14 +235,14 @@ func makeFunctionStage(function ExpressionFunction) evaluationOperator { return func(left interface{}, right interface{}, parameters Parameters) (interface{}, error) { if right == nil { - return function() + return function(parameters) } switch right.(type) { case []interface{}: - return function(right.([]interface{})...) + return function(parameters, right.([]interface{})...) default: - return function(right) + return function(parameters, right) } } } diff --git a/expressionFunctions.go b/expressionFunctions.go index ac6592b..0c736e7 100644 --- a/expressionFunctions.go +++ b/expressionFunctions.go @@ -5,4 +5,4 @@ package govaluate This method must return an error if, for any reason, it is unable to produce exactly one unambiguous result. An error returned will halt execution of the expression. */ -type ExpressionFunction func(arguments ...interface{}) (interface{}, error) +type ExpressionFunction func(parameters Parameters, arguments ...interface{}) (interface{}, error) From 5b0e90f5bc6437ab180c5512ad4df6f29480bf8c Mon Sep 17 00:00:00 2001 From: Hossein Karimy Date: Mon, 16 Jul 2018 10:40:28 -0400 Subject: [PATCH 3/3] MapParameter Set Builtin Functions --- functions.go | 41 +++++++++++++++++++++++++++++++++++++++++ parameters.go | 5 +++++ sanitizedParameters.go | 4 ++++ 3 files changed, 50 insertions(+) create mode 100644 functions.go diff --git a/functions.go b/functions.go new file mode 100644 index 0000000..bff393d --- /dev/null +++ b/functions.go @@ -0,0 +1,41 @@ +package govaluate + +import "math" + +const ( + EFMax = "Max" + EFMin = "Min" + EFRound = "Round" +) + +func BuiltinFunctions() map[string]ExpressionFunction { + return map[string]ExpressionFunction{ + EFMax: ExpFuncMax, + EFMin: ExpFuncMin, + EFRound: ExpFuncRound, + } +} + +func ExpFuncMax(parameters Parameters, args ...interface{}) (interface{}, error) { + val := 0.0 + for _, a := range args { + if a.(float64) > val { + val = a.(float64) + } + } + return val, nil +} + +func ExpFuncMin(parameters Parameters, args ...interface{}) (interface{}, error) { + val := math.MaxFloat64 + for _, a := range args { + if a.(float64) < val { + val = a.(float64) + } + } + return val, nil +} + +func ExpFuncRound(parameters Parameters, args ...interface{}) (interface{}, error) { + return math.Round(args[0].(float64)), nil +} diff --git a/parameters.go b/parameters.go index 6c5b9ec..9887358 100644 --- a/parameters.go +++ b/parameters.go @@ -15,6 +15,7 @@ type Parameters interface { Failure to find the given parameter should be indicated by returning an error. */ Get(name string) (interface{}, error) + Set(name string, value interface{}) } type MapParameters map[string]interface{} @@ -30,3 +31,7 @@ func (p MapParameters) Get(name string) (interface{}, error) { return value, nil } + +func (p MapParameters) Set(name string, value interface{}) { + p[name] = value +} diff --git a/sanitizedParameters.go b/sanitizedParameters.go index 28bd795..ebbdc70 100644 --- a/sanitizedParameters.go +++ b/sanitizedParameters.go @@ -15,6 +15,10 @@ func (p sanitizedParameters) Get(key string) (interface{}, error) { return castToFloat64(value), nil } +func (p sanitizedParameters) Set(key string, value interface{}) { + p.orig.Set(key, value) +} + func castToFloat64(value interface{}) interface{} { switch value.(type) { case uint8: