Skip to content

Commit fd6f279

Browse files
committed
feat: add not operator
added operator to flip logic operator result
1 parent 8dfd3d2 commit fd6f279

5 files changed

Lines changed: 410 additions & 41 deletions

File tree

script/standard/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,9 @@ Using the root or current symbol allows to embed a JSONPath selector within an e
4646
The nil and null tokens can be used interchangeably to represent a nil value.
4747

4848
> remember that the @ character has different meaning in subscripts than it does in filters.
49+
50+
## Limitations
51+
52+
The script parser does not infer meaning from symbols/tokens and the neighboring characters, what may be considered a valid mathematical equation is not always a valid script expression.
53+
54+
For example, the equations `8+3-3*6+2(2*3)` will not be parsed correctly as the engine does not under stand that `2(2*3)` is the same as `2*(2*3)`, if you needed such an equation you would remove any ambiguity of what a number next to a bracket means like so `8+3-3*6+2*(2*3)`.

script/standard/engine.go

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
// TODO : add support for bitwise operators | &^ ^ & << >> after + and -
1414
var defaultTokens []string = []string{
1515
"||", "&&",
16-
"==", "!=", "<=", ">=", "<", ">", "=~",
16+
"==", "!=", "<=", ">=", "<", ">", "=~", "!",
1717
"+", "-",
1818
"**", "*", "/", "%",
1919
"@", "$",
@@ -75,116 +75,134 @@ func (engine *ScriptEngine) buildOperators(expression string, tokens []string, o
7575

7676
// check right for more tokens, or use raw string as input
7777
// right check needs done first as some expressions just have left sides
78-
arg2Str := strings.TrimSpace(expression[idx+(len(nextToken)):])
79-
if arg2Str == "" && (nextToken != "$" && nextToken != "@") {
78+
rightsideString := strings.TrimSpace(expression[idx+(len(nextToken)):])
79+
if rightsideString == "" && (nextToken != "$" && nextToken != "@") {
8080
if len(tokens) == 1 {
8181
return nil, nil
8282
}
8383
// if none of these tokens, move onto next token
8484
return engine.buildOperators(expression, tokens[1:], options)
8585
}
8686

87-
arg2, err := engine.parseArgument(arg2Str, tokens, options)
87+
rightside, err := engine.parseArgument(rightsideString, tokens, options)
8888
if err != nil {
8989
return nil, err
9090
}
9191

9292
// check left for more tokens, or use raw string as input
93-
arg1Str := strings.TrimSpace(expression[0:idx])
94-
if arg1Str == "" && (nextToken != "$" && nextToken != "@") {
93+
leftsideString := strings.TrimSpace(expression[0:idx])
94+
if leftsideString == "" && (nextToken != "$" && nextToken != "@" && nextToken != "!") {
9595
if len(tokens) == 1 {
9696
return nil, nil
9797
}
9898
// if none of these tokens, move onto next token
9999
return engine.buildOperators(expression, tokens[1:], options)
100100
}
101101

102-
arg1, err := engine.parseArgument(arg1Str, tokens, options)
102+
leftside, err := engine.parseArgument(leftsideString, tokens, options)
103103
if err != nil {
104104
return nil, err
105105
}
106106

107107
switch nextToken {
108108
case "@", "$":
109+
if leftside != nil {
110+
// There should not be a left side to this operator
111+
if len(tokens) == 1 {
112+
return nil, nil
113+
}
114+
return engine.buildOperators(expression, tokens[1:], options)
115+
}
109116
selector, err := newSelectorOperator(expression, engine, options)
110117
if err != nil {
111118
return nil, err
112119
}
113120
return selector, nil
114121
case "=~":
115122
return &regexOperator{
116-
arg1: arg1,
117-
arg2: arg2,
123+
arg1: leftside,
124+
arg2: rightside,
125+
}, nil
126+
case "!":
127+
if leftside != nil {
128+
// There should not be a left side to this operator
129+
if len(tokens) == 1 {
130+
return nil, nil
131+
}
132+
return engine.buildOperators(expression, tokens[1:], options)
133+
}
134+
return &notOperator{
135+
arg: rightside,
118136
}, nil
119137
case "||":
120138
return &orOperator{
121-
arg1: arg1,
122-
arg2: arg2,
139+
arg1: leftside,
140+
arg2: rightside,
123141
}, nil
124142
case "&&":
125143
return &andOperator{
126-
arg1: arg1,
127-
arg2: arg2,
144+
arg1: leftside,
145+
arg2: rightside,
128146
}, nil
129147
case "==":
130148
return &equalsOperator{
131-
arg1: arg1,
132-
arg2: arg2,
149+
arg1: leftside,
150+
arg2: rightside,
133151
}, nil
134152
case "!=":
135153
return &notEqualsOperator{
136-
arg1: arg1,
137-
arg2: arg2,
154+
arg1: leftside,
155+
arg2: rightside,
138156
}, nil
139157
case "<=":
140158
return &lessThanOrEqualOperator{
141-
arg1: arg1,
142-
arg2: arg2,
159+
arg1: leftside,
160+
arg2: rightside,
143161
}, nil
144162
case ">=":
145163
return &greaterThanOrEqualOperator{
146-
arg1: arg1,
147-
arg2: arg2,
164+
arg1: leftside,
165+
arg2: rightside,
148166
}, nil
149167
case "<":
150168
return &lessThanOperator{
151-
arg1: arg1,
152-
arg2: arg2,
169+
arg1: leftside,
170+
arg2: rightside,
153171
}, nil
154172
case ">":
155173
return &greaterThanOperator{
156-
arg1: arg1,
157-
arg2: arg2,
174+
arg1: leftside,
175+
arg2: rightside,
158176
}, nil
159177
case "+":
160178
return &plusOperator{
161-
arg1: arg1,
162-
arg2: arg2,
179+
arg1: leftside,
180+
arg2: rightside,
163181
}, nil
164182
case "-":
165183
return &subtractOperator{
166-
arg1: arg1,
167-
arg2: arg2,
184+
arg1: leftside,
185+
arg2: rightside,
168186
}, nil
169187
case "**":
170188
return &powerOfOperator{
171-
arg1: arg1,
172-
arg2: arg2,
189+
arg1: leftside,
190+
arg2: rightside,
173191
}, nil
174192
case "*":
175193
return &multiplyOperator{
176-
arg1: arg1,
177-
arg2: arg2,
194+
arg1: leftside,
195+
arg2: rightside,
178196
}, nil
179197
case "/":
180198
return &divideOperator{
181-
arg1: arg1,
182-
arg2: arg2,
199+
arg1: leftside,
200+
arg2: rightside,
183201
}, nil
184202
case "%":
185203
return &modulusOperator{
186-
arg1: arg1,
187-
arg2: arg2,
204+
arg1: leftside,
205+
arg2: rightside,
188206
}, nil
189207
}
190208

@@ -201,6 +219,10 @@ func (engine *ScriptEngine) parseArgument(argument string, tokens []string, opti
201219
}
202220

203221
argument = strings.TrimSpace(argument)
222+
if argument == "" {
223+
return nil, nil
224+
}
225+
204226
var arg interface{} = argument
205227
if strings.HasPrefix(argument, "[") && strings.HasSuffix(argument, "]") {
206228
val := make([]interface{}, 0)

0 commit comments

Comments
 (0)