Skip to content

Operators

Overview

Larol provides a set of unary and binary operators.

Syntax

someFunction()
someStructCapability.someField
someStructCapability.someFunction()
someSliceCapability[someIndexValue]
(1 + 1)
!someBool
~someInt
-someInt
#someSliceCapability
move someLocalVariable
read someHandle
write someHandle
alloc SomeStructType
alloc SomeType[SomeLength]
someFunctionPointer == anotherFunctionPointer
2 * 3
9 / 3
7 % 3
2 + 3
9 - 3
10 << 2
32 >> 1
2 < 3
2 <= 3
4 > 5
4 >= 5
1 == 1
2 != 3
3 | 2
3 & 2
true || false
true && true

Rules

Precedence and Associativity

Precedence Operator Associativity
1 (), ., [], f() Left-to-right
2 !, ~, - (unary), #, alloc, move, read, write Right-to-left
3 *, /, % Left-to-right
4 +, - Left-to-right
5 <<, >> Left-to-right
6 <, <=, >, >= Left-to-right
7 ==, != Left-to-right
8 & Left-to-right
9 \| Left-to-right
10 && Left-to-right
11 \|\| Left-to-right

Grouping

Parenthesised expressions MUST override default precedence and evaluate the enclosed expression first.

Integer Overflow

Runtime integer overflow on arithmetic operators (+, -, *) MUST wrap according to two's complement arithmetic. Division by zero MUST cause a fatal error.

Function Call

The function call operator MUST invoke the target function with the supplied arguments. The function call operator MUST be usable on member functions via the capability.functionName() syntax. When calling a member function, the capability expression serves as the implicit this argument. A read capability for a struct type MAY call member functions whose implicit this resolves to read StructType. A read capability MUST NOT call member functions whose implicit this resolves to write StructType. A write capability MAY call member functions whose implicit this resolves to either read StructType or write StructType. The function call operator MUST be usable on function pointer values via the pointerName(args) syntax.

When a handle-typed expression is passed as a function argument, move MUST be used: foo(move h). After the call, the source variable MUST be invalidated. move MUST NOT be used on non-handle argument types.

Field Access

The field access operator MUST access the named field of the operand (a struct capability). The field access operator MUST NOT be used on handle types (&T).

Index

The index operator MUST index into a slice capability or slice handle using the supplied value and produce the element at that position.

Logical NOT

The logical NOT operator MUST logically negate a boolean value, producing false if the operand is true and true if the operand is false.

Bitwise NOT

The bitwise NOT operator MUST apply a bitwise NOT to any integer type, flipping every bit.

Arithmetic Negation

The arithmetic negation operator MUST negate a numeric value arithmetically. Arithmetic negation MUST be supported for all integer and floating-point types.

Length Of (#)

The length of operator MUST produce the number of elements in a slice capability or slice handle.

Move

The move operator MUST only be applied to an lvalue. The move operator MUST invalidate the source lvalue and produce its value as an rvalue.

Read

The read operator MUST only be applied to a handle type. The read operator MUST produce a read capability for the handle's owned object/memory. The read operator MUST be applicable to expressions that evaluate to a handle value, including handle-typed variable references and handle member field access results. Applying the read operator to a handle-valued expression MUST NOT constitute a handle copy; the compiler MUST access the underlying object directly to produce the capability.

Multithreading may be supported in future versions; additional rules may apply at that time.

Write

The write operator MUST only be applied to a handle type. The write operator MUST produce a write capability for the handle's owned object/memory. A write capability for a struct handle MUST provide read-write access to the struct's fields. A write capability for a slice handle MUST provide read-write access to the slice's elements. The write operator MUST be applicable to expressions that evaluate to a handle value, including handle-typed variable references and handle member field access results. Applying the write operator to a handle-valued expression MUST NOT constitute a handle copy; the compiler MUST access the underlying object directly to produce the capability.

Multithreading may be supported in future versions; additional rules may apply at that time.

Alloc

Use of alloc MUST only be permitted within a region scope.

alloc SomeStructType MUST allocate a struct of the given type within the current region by calling larol_alloc; this MUST produce a struct handle for the given type.

alloc SomeType[SomeLength] MUST allocate a slice of the given element type and length within the current region by calling larol_alloc_slice; this MUST produce a slice handle for the given element type. The provided length MUST NOT be negative. A length of zero MUST be permitted, the larol_alloc_slice function SHOULD NOT be called for slice allocations with length of zero.

Multiply

The multiply operator MUST multiply two numeric values and produce their product.

Divide

The divide operator MUST divide the left operand by the right operand and produce the quotient. For integer division, the quotient MUST be truncated toward zero (i.e., the fractional part is discarded).

Remainder

The remainder operator MUST divide the left operand by the right operand and produce the remainder. For integer operands, the sign of the remainder MUST match the sign of the left operand (the dividend). Truncation toward zero MUST be used.

Add

The add operator MUST add two numeric values and produce their sum.

Subtract

The subtract operator MUST subtract the right operand from the left operand and produce the difference.

Left Shift

The left shift operator MUST shift the bits of the left operand to the left by the number of positions given by the right operand. Vacated bits MUST be filled with zero.

Right Shift

The right shift operator MUST shift the bits of the left operand to the right by the number of positions given by the right operand. If the left operand is a signed type, the shift MUST be arithmetic (sign-extending). If the left operand is an unsigned type, the shift MUST be logical (zero-filling).

Less Than

The less than operator MUST produce true if the left operand is strictly less than the right operand, otherwise false.

Less Than or Equal

The less than or equal operator MUST produce true if the left operand is less than or equal to the right operand, otherwise false.

Greater Than

The greater than operator MUST produce true if the left operand is strictly greater than the right operand, otherwise false.

Greater Than or Equal

The greater than or equal operator MUST produce true if the left operand is greater than or equal to the right operand, otherwise false.

Equal

The equal operator MUST produce true if both operands are equal, otherwise false. The equal operator MUST be permitted on primitive types, function pointer types, and struct handle types. Two struct handles are equal if and only if they reference the same allocation or are both null.

Not Equal

The not equal operator MUST produce true if the operands are not equal, otherwise false. The not equal operator MUST be permitted on primitive types, function pointer types, and struct handle types.

Bitwise AND

The bitwise AND operator MUST apply a bitwise AND to two integer values, producing a value where each bit is set only if the corresponding bit is set in both operands.

Bitwise OR

The bitwise OR operator MUST apply a bitwise OR to two integer values, producing a value where each bit is set if the corresponding bit is set in either operand.

Logical AND

The logical AND operator MUST produce true only if both operands are true. The logical AND operator MUST short-circuit and not evaluate the right operand if the left operand is false.

Logical OR

The logical OR operator MUST produce true if either operand is true. The logical OR operator MUST short-circuit and not evaluate the right operand if the left operand is true.