(precedence int)
| 218 | } |
| 219 | |
| 220 | func (p *Parser) parseExpression(precedence int) Node { |
| 221 | if p.err != nil { |
| 222 | return nil |
| 223 | } |
| 224 | |
| 225 | if precedence == 0 && p.current.Is(Operator, "let") { |
| 226 | return p.parseVariableDeclaration() |
| 227 | } |
| 228 | |
| 229 | if precedence == 0 && (p.config == nil || !p.config.DisableIfOperator) && p.current.Is(Operator, "if") { |
| 230 | return p.parseConditionalIf() |
| 231 | } |
| 232 | |
| 233 | nodeLeft := p.parsePrimary() |
| 234 | |
| 235 | prevOperator := "" |
| 236 | opToken := p.current |
| 237 | for opToken.Is(Operator) && p.err == nil { |
| 238 | negate := opToken.Is(Operator, "not") |
| 239 | var notToken Token |
| 240 | |
| 241 | // Handle "not *" operator, like "not in" or "not contains". |
| 242 | if negate { |
| 243 | tokenBackup := p.current |
| 244 | p.next() |
| 245 | if operator.AllowedNegateSuffix(p.current.Value) { |
| 246 | if op, ok := operator.Binary[p.current.Value]; ok && op.Precedence >= precedence { |
| 247 | notToken = p.current |
| 248 | opToken = p.current |
| 249 | } else { |
| 250 | p.hasStash = true |
| 251 | p.stashed = p.current |
| 252 | p.current = tokenBackup |
| 253 | break |
| 254 | } |
| 255 | } else { |
| 256 | p.error("unexpected token %v", p.current) |
| 257 | break |
| 258 | } |
| 259 | } |
| 260 | |
| 261 | if op, ok := operator.Binary[opToken.Value]; ok && op.Precedence >= precedence { |
| 262 | p.next() |
| 263 | |
| 264 | if opToken.Value == "|" { |
| 265 | identToken := p.current |
| 266 | p.expect(Identifier) |
| 267 | nodeLeft = p.parseCall(identToken, []Node{nodeLeft}, true) |
| 268 | goto next |
| 269 | } |
| 270 | |
| 271 | if prevOperator == "??" && opToken.Value != "??" && !opToken.Is(Bracket, "(") { |
| 272 | p.errorAt(opToken, "Operator (%v) and coalesce expressions (??) cannot be mixed. Wrap either by parentheses.", opToken.Value) |
| 273 | break |
| 274 | } |
| 275 | |
| 276 | if operator.IsComparison(opToken.Value) { |
| 277 | nodeLeft = p.parseComparison(nodeLeft, opToken, op.Precedence) |
no test coverage detected