Class NotOperandParenthesesOrError

java.lang.Object
org.ek9lang.compiler.phase1.NotOperandParenthesesOrError
All Implemented Interfaces:
Consumer<EK9Parser.ExpressionContext>

final class NotOperandParenthesesOrError extends Object implements Consumer<EK9Parser.ExpressionContext>
E08273 (Steve, 2026-10-07, P5; 2026-10-08, P6): word not is never an UNPARENTHESISED operand of another operator, except and, xor and or - so neither of any other binary operator (P5) nor of a prefix operator (P6: ~not b, $ not b, #? not b, ...).

Word not binds below the comparisons, like Python and SQL (PRECEDENCE (7)): not a == b is not (a == b). Read from the right, the same rule makes a == not b mean a == (not b) - a not that does NOT reach past the == to its left. Python rejects that form outright; so does EK9, and the parentheses say which reading is meant: a == (not b) or not (a == b).

Covered: ^, the coalescing level (?? ?: <? <=? >? >=?), * / mod rem, + -, << >>, <=> <~>, the comparisons < <= > >=, [not] matches, [not] contains, [is] [not] in (including the start of x in a ... b), and == <> !=; and every prefix operator (BinaryExpressions.PREFIX_OPERATORS: $$ $ #^ length #< #> #? abs sqrt ~ and unary -) - each binds tighter than word not, so $ not b reads as $ (not b) while not a == b reads as not (a == b): the same trap, written the other way round. Fix-it $ (not b). The exception is a NEGATION of word not (~not b, -not b): a negation of a negation, which is E08274 (DoubleNegationOrError) - parentheses would not mend it, since -(not b) is E08274 too. Legal: x and not y, x or not y, x xor not y - the logical connectives bind below not, so there is only one reading - and a == (not b).

Purely syntactic, so it runs in phase 1 over the parse tree (see BinaryExpressions). A word not on the LEFT of such an operator cannot occur unparenthesised: it takes the whole comparison.