Operators and punctuations
Operators in Jacy are not something internally special in comparison with
functions. When calling a + b
the trait std::ops::Add
will be used. Mostly
all operators are overloadable.
Operators in expressions
Operator | Trait to overload |
---|---|
a + b | std::ops::Add |
a - b | std::ops::Sub |
a * b | std::ops::Mul |
a / b | std::ops::Div |
a % b | std::ops::Rem |
a ** b (*) | std::ops::Pow |
a or b | N/A |
a and b | N/A |
!a | std::ops::Not |
a & b | std::ops::BitAnd |
a ∣ b | std::ops::BitOr |
a << b | std::ops::Shl |
a >> b | std::ops::Shr |
a ^ b | std::ops::Xor |
a < b a > b a >= b a <= b a <=> b | std::ops::Cmp |
a == b a != b | std::ops::Eq |
a === b a !== b | ??? (Not described) |
a..b | std::ops::Range |
a..=b | std::ops::RangeIncl |
..b | std::ops::RangeTo |
a.. | std::ops::RangeFrom |
..=b | std::ops::RangeToIncl |
.. | std::ops::RangeFull (**) |
a += b | std::ops::AddAssign |
a -= b | std::ops::SubAssign |
a *= b | std::ops::MulAssign |
a /= b | std::ops::DivAssign |
a %= b | std::ops::RemAssign |
a **= b | std::ops::PowAssign |
a ∣= b | std::ops::BitOrAssign |
a &= b | std::ops::BitAndAssign |
a <<= b | std::ops::ShlAssign |
a >>= b | std::ops::ShrAssign |
a ^= b | std::ops::XorAssign |
a? | std::ops::Try::branch |
a! | std::ops::Try::unwrap |
a.b | N/A |
a() | std::ops::Invoke |
*a | std::ops::Deref |
*a = b | std::ops::DerefMut |
&a | N/A |
a ∣> b | N/A |
- (*) For the exponentiation operator, there can be a conflict with
dereferencing operator
*
, to solve it you need to put white space between terms. E.g.a**b
==a ** b
as far asa **b
==a ** b
but not ==a * *b
, anda*b
==a * b
. So, with dereferencing, always put white space before*
(as dereferencing operator). - (**)
RangeFull
is not a real operator, it is an emptystruct
which can be passed somewhere.
Punctuations
Symbol | Usages |
---|---|
: | Type annotations in almost all constructions, function call argument name |
-> | Function types, lambdas |
; | Statement terminator, body ignorance, item declaration |
=> | match arms |
Operators and punctuations precedence
Precedence (from highest to lowest)
This table shows which operators are stronger than others, associativity is marked as "left to right" for left-associative operators and "right to left" for right-associative operators. This table also includes expressions that are not operator expressions, anyway, it might be helpful to know that they are parsed assuming this figurative precedence.
Precedence index is placed just for some help, sometimes you need to know the order.
The table is from high to low precedence ordered -- the operators in the first row have the strongest precedence.
Non-Assoc means non-associative operator, i.e. it is not allowed to combine it with itself like so
a OP b OP c
N | Operator groups / expressions | Associativity |
---|---|---|
20 | Paths (:: ) | N/A |
19 | Field expression (aka member access - a.b ) | left to right |
18 | Invocations (aka calls - a(...) ), array access (aka indexing - a[...] ) | N/A |
17 | [Postfix operators] ? | N/A |
16 | [Prefix operators] ! , & , &mut , - , * | N/A |
15 | as | left |
14 | * / % | left |
13 | + - | left |
12 | .. ..= | non-assoc |
11 | << >> | left |
10 | & (infix) | left |
9 | ^ | left |
8 | ∣ | left |
7 | in | non-assoc |
6 | <=> | non-assoc |
5 | < > <= => | non-assoc |
4 | == != | non-assoc |
3 | and | left |
2 | or | left |
1 | = += -= *= /= %= &= ∣= ^= <<= >>= | left |
Prefix operators: not
, &
(borrow), &mut
(borrow as mutable, &
and mut
can have whitespace between), -
(negation), *
(dereference).
Postfix operators: ?
(optional chaining), !
(unwrap).
Range operators precedence [why?]
Range operators have this kind of precedence as we want to write `a..b+1` which means `a..(b+1)` as far as writing `a..b == c..d` which means `(a..b) == (c..d)`