@@ -127,23 +127,26 @@ func (p *parser) expect(kind Kind, values ...string) {
127
127
}
128
128
129
129
// parse functions
130
-
131
130
func (p * parser ) parseExpression (precedence int ) Node {
132
131
if precedence == 0 && p .current .Is (Operator , "let" ) {
133
132
return p .parseVariableDeclaration ()
134
133
}
135
134
136
135
nodeLeft := p .parsePrimary ()
136
+
137
137
prevOperator := ""
138
- for opToken := p .current ; opToken .Is (Operator ) && p .err == nil ; opToken = p .current {
138
+ opToken := p .current
139
+ for opToken .Is (Operator ) && p .err == nil {
139
140
negate := opToken .Is (Operator , "not" )
140
- var op operator.Operator
141
- var ok bool
141
+ var notToken Token
142
+
143
+ // Handle "not *" operator, like "not in" or "not contains".
142
144
if negate {
143
145
currentPos := p .pos
144
146
p .next ()
145
147
if operator .AllowedNegateSuffix (p .current .Value ) {
146
- if op , ok = operator .Binary [p .current .Value ]; ok && op .Precedence >= precedence {
148
+ if op , ok := operator .Binary [p .current .Value ]; ok && op .Precedence >= precedence {
149
+ notToken = p .current
147
150
opToken = p .current
148
151
} else {
149
152
p .pos = currentPos
@@ -154,39 +157,63 @@ func (p *parser) parseExpression(precedence int) Node {
154
157
p .error ("unexpected token %v" , p .current )
155
158
break
156
159
}
157
- } else if op , ok = operator .Binary [opToken .Value ]; ! ok || op .Precedence < precedence {
158
- break
159
160
}
160
- p .next ()
161
- if opToken .Value == "|" {
162
- identToken := p .current
163
- p .expect (Identifier )
164
- nodeLeft = p .parseCall (identToken , []Node {nodeLeft }, true )
165
- } else if prevOperator == "??" && opToken .Value != "??" && ! opToken .Is (Bracket , "(" ) {
166
- p .errorAt (opToken , "Operator (%v) and coalesce expressions (??) cannot be mixed. Wrap either by parentheses." , opToken .Value )
167
- break
168
- } else if op .Precedence == 20 {
169
- nodeLeft = p .parseComparison (nodeLeft , opToken , op .Precedence + 1 , negate )
170
- } else {
161
+
162
+ if op , ok := operator .Binary [opToken .Value ]; ok && op .Precedence >= precedence {
163
+ p .next ()
164
+
165
+ if opToken .Value == "|" {
166
+ identToken := p .current
167
+ p .expect (Identifier )
168
+ nodeLeft = p .parseCall (identToken , []Node {nodeLeft }, true )
169
+ goto next
170
+ }
171
+
172
+ if prevOperator == "??" && opToken .Value != "??" && ! opToken .Is (Bracket , "(" ) {
173
+ p .errorAt (opToken , "Operator (%v) and coalesce expressions (??) cannot be mixed. Wrap either by parentheses." , opToken .Value )
174
+ break
175
+ }
176
+
177
+ if op .Precedence == 20 {
178
+ nodeLeft = p .parseComparison (nodeLeft , opToken , op .Precedence + 1 , negate )
179
+ goto next
180
+ }
181
+
171
182
var nodeRight Node
172
183
if op .Associativity == operator .Left {
173
184
nodeRight = p .parseExpression (op .Precedence + 1 )
174
185
} else {
175
186
nodeRight = p .parseExpression (op .Precedence )
176
187
}
188
+
177
189
nodeLeft = & BinaryNode {
178
190
Operator : opToken .Value ,
179
191
Left : nodeLeft ,
180
192
Right : nodeRight ,
181
193
}
182
194
nodeLeft .SetLocation (opToken .Location )
195
+
196
+ if negate {
197
+ nodeLeft = & UnaryNode {
198
+ Operator : "not" ,
199
+ Node : nodeLeft ,
200
+ }
201
+ nodeLeft .SetLocation (notToken .Location )
202
+ }
203
+
204
+ goto next
183
205
}
206
+ break
207
+
208
+ next:
184
209
prevOperator = opToken .Value
210
+ opToken = p .current
185
211
}
186
212
187
213
if precedence == 0 {
188
214
nodeLeft = p .parseConditional (nodeLeft )
189
215
}
216
+
190
217
return nodeLeft
191
218
}
192
219
0 commit comments