Expressions

An expression computes a value. ik expressions use conventional operator precedence; all binary levels are left-associative and may be chained.

Primary expressions

A primary expression is the smallest unit:

  • a numeric literal (42, 0xF0), a fixed-point literal (3.14), a boolean (true/false), or a character literal ('A');

  • a string literal ("text");

  • a variable, register, or array element ($x, %PORTB, $buf[i]);

  • a function call (@name(args) or indirect @$ptr(args));

  • a parenthesised expression (( ... )).

Operator precedence

From lowest to highest binding. Operators in the same row share a precedence level and associate left to right.

Prec

Operators

Description

1

||

logical OR (short-circuit)

2

&&

logical AND (short-circuit)

3

|

bitwise OR

4

^

bitwise XOR

5

&

bitwise AND

6

== !=

equality

7

< > <= >=

relational

8

+ -

additive

9

* / %

multiplicative

10

! ~ - & * (unary)

unary prefix (right-assoc.)

Use parentheses to make intent explicit; the unary minus in (-$val) -> $res is parenthesised in the standard examples for exactly this reason.

Arithmetic operators

+, -, *, /, % perform integer arithmetic at the operands’ width. Division and modulo are integer operations. On fixed-point r16 values, prefer the std/math — Fixed-point math routines, which rescale correctly.

Integer arithmetic wraps at the type width (modular arithmetic). For example, -$val on a u8 holding 5 yields 0xFB (251), the two’s complement byte; on a u16 it yields 0xFFFB (65531).

Bitwise operators

&, |, ^ are bitwise AND, OR, XOR. ~ is unary bitwise NOT (one’s complement): ~5 on a u8 is 0xFA (250).

Comparison operators

==, !=, <, <=, >, >= compare two values and yield a boolean (1 or 0). They are the conditions you put after ? and inside loop bounds.

Logical operators

&& and || are short-circuiting logical AND and OR over boolean (nonzero = true) operands. ! is logical NOT: !0 is 1, !$x is 1 when $x is zero and 0 otherwise.

Address-of and dereference

In operand (unary, prefix) position:

  • &expr takes the address of a location, producing a pointer. &$value is a pointer to $value; &@func is a function pointer to @func.

  • *expr dereferences a pointer, reading or writing the pointed-to value. *$p reads, and *$p -> $x reads through $p, while $v -> *$p writes through it.

These are syntactically distinct from the infix & (bitwise AND) and * (multiply): the parser decides based on position. & and * between two operands are the binary operators; at the front of an operand they are address-of and dereference.

Array indexing

base[index] selects an element. The index is any expression, so dynamic indexing is allowed, and an indexed element is a valid assignment target:

$buf[0]       # read element 0
$buf[$i]      # read element $i (runtime index)
10 -> $buf[2] # write element 2

Function calls

A direct call names the function with its @ sigil:

@delay_ms(500)
ram imut $n: u16 = @square(7)

An indirect call goes through a function-pointer variable, combining the sigils as @$var:

ram imut $f: fn(u8) -> u8 = &@double
ram imut $r: u8 = @$f(21)

Argument expressions are evaluated and passed in order. See Functions for the calling convention and Compiler intrinsics for the compiler-provided @ operations that look like calls but emit single instructions.