Skip to main content

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​

ExamplePurpose
123
$0000_ff23
integer literal
"hello{n}"string literal
'{n}'character literal
@my_labeldata label
nullnull object
selfobject 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 groupExamplePurpose
__ . __
__ :: __
__ ( __ )
__ [ __ ]
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 + -5negate a number
__ * __
__ / __
__ % __
__ // __
__ %% __
x * y / 2multiply, divide, remainder
__ + __
__ - __
2 + 2add and subtract numbers
__ as __target as playertype cast for class objects
__ <= __
__ < __
__ = __
__ > __
__ >= __
__ <> __
x <> 3compare two numbers
not __not x > 3boolean NOT
__ and __x < 0 and x > 3boolean AND
__ or __x < 0 or x > 3boolean 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 quotientTruncated remainder
17 / 5 = 317 % 5 = 2
-17 / 5 = -3-17 % 5 = -2
17 / -5 = -317 % -5 = 2
-17 / -5 = 3-17 % -5 = -2
Euclidean quotientEuclidean remainder
17 // 5 = 317 %% 5 = 2
-17 // 5 = -4-17 %% 5 = 3
17 // -5 = -317 %% -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.

ExamplePurpose
new t(...)create a new object with the specified type t
(new t)obtain a function pointer to the constructor for type t
class_id(c)get the class ID of a class type c
unsafe(a)[i]an unsafe operation that accesses index i of array a without performing a bounds check
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 to its memory address as an int value

Important points:

  • Type conversions can cause overflow. For example, to_byte(257) will produce a byte with value 1.
  • To convert between classes types, use the as operator 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.