Expressions
Hybrix expressions are made of variables, literal values, and operators. Operators accept operands (depicted as __ in the table below), allowing them to be combined to make compound expressions. For example, x + 1 is an expression that uses the + operator. The operands are the variable x and the literal value 1.
Literal values
| Example | Purpose |
|---|---|
123 $0000_ff23 | integer literal |
"hello{n}" | string literal |
@my_label | data label |
null | null object |
self | object self-reference |
true false | boolean literal |
Operators
The table below lists all the expression operators for the Hybrix language, in order of decreasing precedence according to the order of operations. For example, and has a higher precedence than or, therefore a or b and c or d will be parsed as a or (b and c) or d.
| Operator group | Example | Purpose |
|---|---|---|
new __ ( __ ) class_id( __ ) (literal value) | new int[](3) class_id(my_class) -123 | create a new object get the class ID (see table above) |
__ . __ __ :: __ __ ( __ ) __ [ __ ] | my_object.member my_module::member my_func(x, y)my_array[3] | access a class member access a module member call a function access an array element |
- __ | -x + -5 | negate a number |
__ * __ __ / __ __ % __ __ // __ __ %% __ | x * y / 2 | multiply, divide, remainder |
__ + __ __ - __ | 2 + 2 | add and subtract numbers |
__ & __ | "hello" & "world" | append text strings ⚠️ not implemented yet |
__ as __ | target as player | type cast for class objects |
__ <= __ __ < __ __ = __ __ > __ __ >= __ __ <> __ | x <> 3 | compare two numbers |
not __ | not x > 3 | boolean NOT |
__ and __ | x < 0 and x > 3 | boolean AND |
__ or __ | x < 0 or x > 3 | boolean OR |
Division and remainder
The // and %% operators perform Euclidean integer division and remainder (modulus). For example, 17 divided by 5 equals 3 with a remainder of 2. Therefore 17 / 5 returns 3, and 17 % 5 returns remainder 2. For negative numbers, the Euclidean approach ensures that the remainder is always a positive number.
The Euclidean approach is the most mathematically correct way to divide; however, for historical reasons, most programming languages such as C and Rust instead use truncated division, where the remainder can be a negative number if the dividend is negative. For consistency with those languages, Hybrix also provides / and % operators which implement truncated integer division and remainder.
| Truncated quotient | Truncated remainder |
|---|---|
17 / 5 = 3 | 17 % 5 = 2 |
-17 / 5 = -3 | -17 % 5 = -2 |
17 / -5 = -3 | 17 % -5 = 2 |
-17 / -5 = 3 | -17 % -5 = -2 |
| Euclidean quotient | Euclidean remainder |
|---|---|
17 // 5 = 3 | 17 %% 5 = 2 |
-17 // 5 = -4 | -17 %% 5 = 3 |
17 // -5 = -3 | 17 %% -5 = 2 |
-17 // -5 = 4 | -17 %% -5 = 3 |
Function-like operators
The type conversion operators look like regular function calls, but their names are reserved words such as to_int.
| Example | Purpose |
|---|---|
to_byte(x) | convert a numeric value x to a byte type |
to_pair(x) | convert a numeric value x to a pair type |
to_int(x) | convert a numeric value x to an int type |
to_address(p) | convert a pointer value p its memory address as an int value |
Important points:
- Type conversions can cause overflow. For example,
to_byte(257)will produce abytewith value 1. - To convert between classes types, use the
asoperator instead. to_address()produces the memory address of the object being pointed to (not the address of the variable itself). Thus it requires a heap-allocated type such as an array, object, or function pointer.