Operators
Operators in Cyrus work similarly to those in C. They are categorized by their functionality and precedence. Operators are evaluated based on their precedence (priority) and associativity (left-to-right or right-to-left).
Arithmetic Operators
Arithmetic operators perform mathematical calculations between numeric operands.
| Operator | Meaning | Example | Result |
|---|---|---|---|
| + | Addition | 5 + 2 | 7 |
| - | Subtraction | 5 - 2 | 3 |
| * | Multiplication | 5 * 2 | 10 |
| / | Division | 5 / 2 | 2 |
| % | Modulo (Truncated) | 5 % 2 | 1 |
| | | Bitwise OR (integers) | 6 | 3 | 7 |
| ~ | Bitwise XOR (integers) | 6 ~ 3 | 5 |
| & | Bitwise AND (integers) | 6 & 3 | 2 |
&~ | Bitwise AND-NOT (integers) | 6 &~ 3 | 4 |
| << | Left Shift (integer << non-negative integer) | 3 << 2 | 12 |
| >> | Right Shift (integer >> non-negative integer) | 12 >> 2 | 3 |
Comparison Operators
Comparison operators evaluate the relationship between two operands and return a bool result (true or false).
| Operator | Meaning | Example | Result |
|---|---|---|---|
| == | Equal to | 5 == 5 | true |
| != | Not equal to | 5 != 3 | true |
| < | Less than | 3 < 5 | true |
| > | Greater than | 7 > 2 | true |
| <= | Less than or equal to | 3 <= 3 | true |
| >= | Greater than or equal to | 5 >= 2 | true |
Logical Operators
Logical operators are used to combine or invert boolean values. They always operate on true and false values and return a boolean result.
| Operator | Meaning | Example | Result |
|---|---|---|---|
| && | Logical AND | true && false | false |
| || | Logical OR | true || false | true |
| ! | Logical NOT | !true | false |
Assignment Operators
Assignment operators are used to assign values to variables. The simplest form is =, but there are also compound assignments that perform an operation and assignment in one step.
| Operator | Meaning | Example | Result |
|---|---|---|---|
| = | Assignment | a = 10 | a = 10 |
| += | Add and assign | a += 5 | a = a + 5 |
| -= | Subtract and assign | a -= 5 | a = a - 5 |
| *= | Multiply and assign | a *= 5 | a = a * 5 |
| /= | Divide and assign | a /= 5 | a = a / 5 |
| %= | Modulo and assign | a %= 5 | a = a % 5 |
| &= | Bitwise AND and assign | a &= 5 | a = a & 5 |
| ~= | Bitwise XOR and assign | a ~= 5 | a = a ~ 5 |
| &~= | Bitwise AND NOT and assign | a &~= 5 | a = a &~ 5 |
| <<= | Left shift and assign | a <<= 2 | a = a << 2 |
| >>= | Right shift and assign | a >>= 2 | a = a >> 2 |
Operator Precedence & Associativity
Associativity determines how operators of the same precedence are grouped: left-to-right or right-to-left. Parentheses () can be used to explicitly control evaluation order.
| Operator / Type | Description | Precedence / Associativity |
|---|---|---|
| Lowest | Represents the lowest precedence. Used internally as a default when no other precedence applies. | Lowest |
| sizeof | Returns the size of a type or expression in bytes. | High / Right-to-left |
| || | Logical OR. Returns true if at least one operand is true. | Low / Left-to-right |
| && | Logical AND. Returns true only if both operands are true. | Low / Left-to-right |
| ==, != | Equality and inequality comparison operators. | Low-Mid / Left-to-right |
| >, <, >=, <= | Relational operators to compare values. | Mid / Left-to-right |
| +, - | Addition and subtraction operators. | Mid-High / Left-to-right |
| *, /, % | Multiplication, division, and modulo operators. | High / Left-to-right |
| &, |, ~, &~ | Bitwise AND, OR, NOT, and custom combination (~&). | High / Left-to-right |
| -X, !X | Unary prefix operators: negation and logical NOT. | High / Right-to-left |
| & | Address-of operator. Returns the memory address of its operand. | Lower than member access / Right-to-left |
| * | Dereference operator. Accesses the value pointed to by a pointer. | Higher than member access / Right-to-left |
| my_function(x) | Function call. Evaluates arguments and calls the function. | Very High / Left-to-right |
| array[index] | Array indexing. Access the element at a specific position. | Very High / Left-to-right |
| Type conversion (cast) | Explicitly converts a value to a different type. | High / Right-to-left |
| . | Member access. Accesses a field of a struct or object. | High / Left-to-right |
| -> | Pointer member access. Dereferences a pointer to access a field of a struct or object. | High / Left-to-right |
Unary Operators
Unary operators operate on a single operand and modify its value by 1.
Prefix (++i, --i) updates the variable before it’s used in an expression.
Postfix (i++, i--) updates the variable after it’s used in an expression.
| Operator | Meaning | Example | Result |
|---|---|---|---|
| i++ | Post-increment: returns current value, then increases by 1 | i = 5; j = i++ | i = 6, j = 5 |
| ++i | Pre-increment: increases by 1, then returns the new value | i = 5; j = ++i | i = 6, j = 6 |
| i-- | Post-decrement: returns current value, then decreases by 1 | i = 5; j = i-- | i = 4, j = 5 |
| --i | Pre-decrement: decreases by 1, then returns the new value | i = 5; j = --i | i = 4, j = 4 |
Notes:
- Works only on mutable lvalues; using on constants or rvalues should be a compile error.
- Avoid relying on multiple increments of the same variable within a single expression if your language disallows/diagnoses unspecified order of evaluation.
Null-Coalescing Operator
The null-coalescing operator (||) is used with pointers to select the first non-null value from a chain of operands.
It evaluates operands from left to right and returns the first pointer that is not null.
If all operands are null, the result is null.
var p1: int* = null;
var p2: int* = &x;
var p3: int* = &y;
var result1 = p1 || p2; // returns p2
var result2 = p1 || null; // returns null
var result3 = p1 || p2 || p3; // returns p2 (first non-null)

