Edva uses Pratt parsing to resolve operator precedence and associativity. This chapter specifies all operator tiers, comparison and range semantics, operator and field-accessor sections, and the scoping rules of the implicit placeholder _ and cycle index _i.
6.1 Precedence and binding power table
Tier
LBP
RBP
Operators
Associativity
cycle
10
20
@@@>---->--^
left
sequence
20
30
;
left
apply
30
30
$
right
feed
40
50
$>$>>
left
choice
50
60
|[pattern]!||->|+>|-->|++>
left
assignment
60
50
=:=+=::=
right
range
70
80
..
left
logical or
80
90
||
left
logical and
90
100
&&
left
bitwise or
100
105
.|.
left
bitwise xor
105
110
.^.
left
bitwise and
110
120
.&.
left
comparison
120
130
<>==!=!<!>
left, same-line
shift
130
140
.<..>.
left
addition
140
150
+-
left
multiplication
150
160
*/%
left
unary prefix
160
180
!+&++.!.~~???-x#size
right
postfix / apply
170
180
call ().::: cast{N}@[...]!!--!
left
primary
180
180
primary
left
Parsing Rule
Behavior
Left-associative tiers (RBP > LBP)
Operator binds tightly on the left (a - b - c\(\equiv\)(a - b) - c)
Right-associative tiers (RBP <= LBP)
Operator extends rightward (f $ g $ x\(\equiv\)f(g(x)))
Choice absorption ($ / $>)
$ (LBP 30) and $> (LBP 40) sit below choice (LBP 50), absorbing unparenthesized RHS choices (a $> b | c | d\(\equiv\)a $> (b | c | d))
Operator sections (op rhs)
13 binary operators with a leading operand omitted and mandatory trailing space form a 1-arg function over _ with RBP 130
6.2 Relational, equality, and chained comparisons
Comparisons sit at LBP 120, RBP 130 and return a bare flag <> (<+> or <->). Edva writes greater-or-equal as !< (“not less”) and less-or-equal as !> (“not greater”); <= and >= are not comparison operators (=> is the function arrow).
Operator
Meaning
Valid Operand Types
Floating-Point / Special Semantics
<
Less than
Numeric, Rune, String, Addr
Ordered (OLT); <-> if either operand is NaN. Rejected on rams/enums (E3127)
>
Greater than
Numeric, Rune, String, Addr
Ordered (OGT); <-> if either operand is NaN. Rejected on rams/enums (E3127)
!<
Greater than or equal (\(\ge\))
Numeric, Rune, String, Addr
Ordered (OGE); <-> if either operand is NaN (distinct from !(a < b))
!>
Less than or equal (\(\le\))
Numeric, Rune, String, Addr
Ordered (OLE); <-> if either operand is NaN (distinct from !(a > b))
==
Equal
Scalars, String, records, enums, Type, two bare Flags <>
Deep structural equality on records and enums; on two Flags, logical XNOR (E3027 on other rams, E3084 on fn payloads); zero-alloc segment check on str == (p1, p2, ...)
!=
Not equal
Scalars, String, records, enums, Type, two bare Flags <>
Logical negation of == (UNE on floats: <+> if either operand is NaN); on two Flags, logical XOR
6.2.1 Chained comparisons
Relational operators (<, >, !<, !>) on the same source line chain mathematically, evaluating interior operands at most once:
Chained Expression
Equivalent Short-Circuit Lowering
Middle Operand Evaluation
a < x < b
t = x; (a < t) && (t < b)
Evaluated at most once
a !> x < b
t = x; (a !> t) && (t < b)
Evaluated at most once
a !> x !> b
t = x; (a !> t) && (t !> b)
Evaluated at most once
b > f(x) > a
t = f(x); (b > t) && (t > a)
f(x) called at most once
#useioin_half_open: Int, Int, Int=><>in_half_open = x, lo, hi => lo !> x < hiio::out $ in_half_open(5, 0, 10) // <+>io::out $ in_half_open(10, 0, 10) // <->
6.3 Range operators (.., ..., ..=)
Range operators sit at LBP 70, RBP 80. Endpoints must be adjacent to the operator without whitespace (E2025). Ranges are consumed by choice guards [...], cycles @, and slice/substring calls x(...):
Operator
Interval Kind
Math Notation
Lower Bound a
Upper Bound b
Choice Guard [...]
Cycle @
Slice / View x(...)
a..b
Half-open (left-closed, right-open)
\([a, b)\)
Closed (\(a \le x\))
Open (\(x < b\))
a !> x < b
a through b - 1
Elements [a, b)
a...b / a..=b
Closed (both inclusive)
\([a, b]\)
Closed (\(a \le x\))
Closed (\(x \le b\))
a !> x !> b
a through b
Elements [a, b]
a..
Lower-bounded closed
\([a, \infty)\)
Closed (\(a \le x\))
Unbounded
x !< a
Unbounded from a
From a to ?x (-k.. from ?x - k)
..b
Upper-bounded open
\((-\infty, b)\)
Unbounded
Open (\(x < b\))
x < b
0 through b - 1
Elements [0, b)
...b / ..=b
Upper-bounded closed
\((-\infty, b]\)
Unbounded
Closed (\(x \le b\))
x !> b
0 through b
Elements [0, b]
..
Unbounded
\((-\infty, \infty)\)
Unbounded
Unbounded
<+>
Unbounded from 0
Full view [0, ?x)
6.4 Arithmetic, bitwise, shift, logical, and map operators
Category
Operators
Operand Types
Result Type & Semantics
Arithmetic
+-*/%
Numeric (Int, Float, i8..u64, f32, SIMD vectors)
Same numeric type (+ also concatenates String, Rune, and Builder)
Bitwise
.|..^..&..!.
Integerish (Int, i8..u64, integer SIMD vectors)
Same integer type (.!. is unary bitwise NOT)
Bit shift
.<..>.
Integerish
Left shift (.<.) and right shift (.>.); sections infer Int => Int
Logical
&&||
<> (Flag) or compatible heap ramifications
Short-circuiting AND / OR
Map access
m ^ k m ^? k m ^- k
Map K ^ V, key K
^: < V | Error > lookup (m ^ k = v inserts) ^?: <> key existence check ^-: <> key removal
6.5 Operator sections and field-accessor sections
An operator section writes a 1-argument function value => value op rhs by omitting the left operand of a supported binary operator. A field-accessor section writes a 1-argument projection r => r.field using a leading dot inside parentheses.
6.5.1 Section syntax and rules
Section Form
Syntax
Desugaring
Rules & Diagnostics
Additive section
(+ rhs), (- rhs)
_ => _ + rhs, _ => _ - rhs
Mandatory space after operator (-3 is negative literal; +b is Builder freeze)