machdocs
Home GitHub

Expressions

Expressions evaluate to values. They appear on the right of a binding, as conditions, and as call arguments.

Names

A bare identifier references a name in scope. Module-qualified names use the dot path.

counter        # local or module-level binding
core.add       # symbol from module core

Literals

The primitive literal forms are numeric, char, string, and nil.

42         # numeric literal
'a'        # char literal
"hello"    # string literal
nil        # the nil value

Composite literals

A type name followed by a brace-delimited initializer builds a record, array, or union value. For generics, the type arguments appear in brackets before the body.

val p:    Point         = Point{ x: 1, y: 2 };
val a:    [3]i64        = [3]i64{ 10, 20, 30 };
val u:    Number        = Number{ i: 99 };
val pair: Pair[i64, u8] = Pair[i64, u8]{ left: 5, right: 6u8 };
Not yet implemented

Vector literals such as f32x4{ ... } follow the same shape but depend on the SIMD vector types, which are not yet implemented. See Types.

Field and index access

A field is read with the dot, an array element with a bracketed index.

val x:     i64 = p.x;     # record field
val first: i64 = a[0];    # array index

Function calls

A call applies a function to a parenthesized argument list.

add(2, 3)

Generic calls

Type arguments for a generic function appear in brackets before the call parentheses.

identity[i64](42)     # generic call: type args in [ ]

Variadic calls

A variadic call passes extra trailing arguments past the fixed parameters.

sum(3, 10i64, 20i64, 30i64)
Not yet implemented

Variadic call sites parse, but the callee-side va_list machinery is not yet implemented. See Functions. For the compile-time alternative, see Variadic packs.

Comptime arguments

A comptime argument is passed positionally, just like a runtime argument. The function signature decides whether a given argument must be comptime-knowable.

checked_add(MODE_FAST, 1, 2)    # MODE_FAST is comptime-knowable

Operators

Operators combine expressions into larger expressions. Precedence follows the usual C-family conventions.

val n: i64 = a + b * c;    # * binds tighter than +

See also