6. Expressions

Syntax

Expression ::=
    Declaration
    | NonDeclarativeExpression

DeclarativeExpression ::=
    Declaration
    | ContinueExpression
    | BreakExpression
    | ReturnExpression
    | AssignExpression
    | ImportExpression

NonDeclarativeExpression ::=
    SingleExpression
    | DefinitionExpression
    | UnaryExpression
    | BinaryExpression
    | ExpressionWithBlock

ExpressionWithBlock ::=
    BlockExpression
    | ModuleDefinition

DefinitionExpression ::=
    FunctionDefinition
    | StructDefinition
    | EnumDefinition
    | ImplicitFunctionDefinition


SingleExpression ::=
    VariableExpression
    | AccessExpression
    | IndexExpression
    | LiteralExpression
    | ArrayExpression
    | TupleExpression
    | CallExpression
    | ImplicitCallExpression
    | RangeExpression
    | TypeExpression
    | ExpressionMacroInvocation
    | TokenMacroInvocation

ExpressionList ::=
    NonDeclarativeExpression (, NonDeclarativeExpression)* ,?

ExpressionArgument ::=
    Name (= NonDeclarativeExpression)?
    | NonDeclarativeExpression

6.1. Declaration

Syntax

Declaration ::=
    SingularPattern : Type? = NonDeclarativeExpression

Examples

mut k := 0
foo := 1
bar: f32 = 1.0
pub baz := 1
(a, b) := (1, 2)
User(mut name, ...) := user

6.2. Literal Expressions

Syntax

LiteralExpression ::=
    Literal

Examples

"a"
3.2
'ø'
7

6.3. Array Expressions

Syntax

ArrayExpression ::=
    [ ArrayElementExpression? ]

ArrayElementExpression ::=
    ArrayElementConstructor
    | ArrayRepetitionConstructor

ArrayElementConstructor ::=
    ExpressionList

ArrayRepetitionConstructor ::=
    NonDeclarativeExpression ; NonDeclarativeExpression

Examples

[1, 2, 3, 4]

6.3:1 Two dimensional arrays:

[[1, 2, 3], [4, 5, 6]]

6.3:2 An array of four hundred and twenty 69s:

[69; 420]

6.4. Variable Expressions

Syntax

VariableExpression ::=
    Name

Examples

var
foo

6.5. Unary Expressions

Syntax

UnaryExpression ::=
    DerefExpression
    RefExpression
    NotExpression
    BitNotExpression
    NegationExpression

6.5.1. Dereferencing Expressions

Syntax

DerefExpression ::=
    * NonDeclarativeExpression

Examples

foo := (value: &i32) => {
    deref_value := *value
}

6.5.2. Reference Expressions

Syntax

RefExpression ::=
    & ReferenceModifier? mut? NonDeclarativeExpression

Examples

bar := (value: &mut i32) => {
}

foo := () => {
    mut value := 7
    bar(&mut value)
}

6.5.3. Not Expressions

Syntax

NotExpression ::=
    ! NonDeclarativeExpression

Examples

has_errors: bool := check_errors()

if !has_errors {
    ...
}

6.5.4. Bit Not Expressions

Syntax

BitNotExpression ::=
    ~ NonDeclarativeExpression

Examples

~0b1010

6.5.5. Negation Expressions

Syntax

NegationExpression ::=
    - NonDeclarativeExpression

Examples

-42

6.6. Binary Expressions

Syntax

BinaryExpression ::=
    ArithmeticExpression
    | BitExpression
    | ComparisonExpression
    | LazyBooleanExpression

6.6.1. Arithmetic Expressions

Syntax

ArithmeticExpression ::=
    AddExpression
    | SubtractionExpression
    | MultiplicationExpression
    | DivisionExpression
    | ModuloExpression
    | ExponentiationExpression

AddExpression ::=
    NonDeclarativeExpression + NonDeclarativeExpression

SubtractionExpression ::=
    NonDeclarativeExpression - NonDeclarativeExpression

MultiplicationExpression ::=
    NonDeclarativeExpression * NonDeclarativeExpression

DivisionExpression ::=
    NonDeclarativeExpression / NonDeclarativeExpression

ModuloExpression ::=
    NonDeclarativeExpression % NonDeclarativeExpression

ExponentiationExpression ::=
    NonDeclarativeExpression ^^ NonDeclarativeExpression

Examples

1 + 2
4.0 / 3.29
8.4 * 5.3
10 % 4
3 - 2
4 ^^ 2

6.6.2. Bit Expressions

Syntax

BitExpression ::=
    BitAndExpression
    | BitOrExpression
    | BitXorExpression
    | BitShiftLeftExpression
    | BitShiftRightExpression

BitAndExpression ::=
    NonDeclarativeExpression & NonDeclarativeExpression

BitOrExpression ::=
    NonDeclarativeExpression | NonDeclarativeExpression

BitXorExpression ::=
    NonDeclarativeExpression ^ NonDeclarativeExpression

BitShiftLeftExpression ::=
    NonDeclarativeExpression << NonDeclarativeExpression

BitShiftRightExpression ::=
    NonDeclarativeExpression >> NonDeclarativeExpression

Examples

0b1010 & 0b1100
0b1010 | 0b0011
0b1010 ^ 0b1001
13 << 3
-10 >> 2

6.6.3. Comparison Expressions

Syntax

ComparisonExpression ::=
    LessThanExpression
    | LessThanOrEqualExpression
    | GreaterThanExpression
    | GreaterThanOrEqualExpression
    | EqualExpression
    | NotEqualExpression

LessThanExpression ::=
    NonDeclarativeExpression < NonDeclarativeExpression

LessThanOrEqualExpression ::=
    NonDeclarativeExpression <= NonDeclarativeExpression

GreaterThanExpression ::=
    NonDeclarativeExpression > NonDeclarativeExpression

GreaterThanOrEqualExpression ::=
    NonDeclarativeExpression >= NonDeclarativeExpression

EqualExpression ::=
    NonDeclarativeExpression == NonDeclarativeExpression

NotEqualExpression ::=
    NonDeclarativeExpression != NonDeclarativeExpression

Examples

12 == 12
42 > 12
42 >= 35
42 < 109
42 <= 42
12 != 42

6.6.4. Lazy Boolean Expressions

Syntax

LazyBooleanExpression ::=
    LazyAndExpression
    | LazyOrExpression

LazyAndExpression ::=
    NonDeclarativeExpression && NonDeclarativeExpression

LazyOrExpression ::=
    NonDeclarativeExpression || NonDeclarativeExpression

Examples

true && abort()
false || true

6.7. Assignment Expressions

Syntax

AssignExpression ::=
    Assignment
    | CompoundAssignment

Assignment ::=
    NonDeclarativeExpression = NonDeclarativeExpression

Examples

b = 2
(four, two) = (4, 2)

6.7.1. Compound Assignment

Syntax

CompoundAssignment ::=
    ArithmeticCompoundAssignment
    | BitCompoundAssignment
    | LazyCompoundAssignment

6.7.1.1. Arithmetic Compound Assignments

Syntax

ArithmeticCompoundAssignment ::=
    AddCompoundAssignment
    | SubtractionCompoundAssignment
    | MultiplicationCompoundAssignment
    | DivisionCompoundAssignment
    | ModuloCompoundAssignment
    | ExponentiationCompoundAssignment

AddCompoundAssignment ::=
    NonDeclarativeExpression += NonDeclarativeExpression

SubtractionCompoundAssignment ::=
    NonDeclarativeExpression -= NonDeclarativeExpression

MultiplicationCompoundAssignment ::=
    NonDeclarativeExpression *= NonDeclarativeExpression

DivisionCompoundAssignment ::=
    NonDeclarativeExpression /= NonDeclarativeExpression

ModuloCompoundAssignment ::=
    NonDeclarativeExpression %= NonDeclarativeExpression

ExponentiationCompoundAssignment ::=
    NonDeclarativeExpression ^^= NonDeclarativeExpression

Examples

mut result := 0
result += 1
result /= 3
result ^= 2
result *= 81
result %= 7
result -= 0
result ^^= 6

6.7.1.2. Bit Compound Assignments

Syntax

BitCompoundAssignment ::=
    BitAndCompoundAssignment
    | BitOrCompoundAssignment
    | BitXorCompoundAssignment
    | BitShiftLeftCompoundAssignment
    | BitShiftRightCompoundAssignment

BitAndCompoundAssignment ::=
    NonDeclarativeExpression &= NonDeclarativeExpression

BitOrCompoundAssignment ::=
    NonDeclarativeExpression |= NonDeclarativeExpression

BitXorCompoundAssignment ::=
    NonDeclarativeExpression ^= NonDeclarativeExpression


BitShiftLeftCompoundAssignment ::=
    NonDeclarativeExpression <<= NonDeclarativeExpression

BitShiftRightCompoundAssignment ::=
    NonDeclarativeExpression >>= NonDeclarativeExpression

Examples

mut result := 0
result |= 9402
result &= 59
result <<= 2
result >>= 3

6.7.1.3. Lazy Compound Assignments

Syntax

LazyCompoundAssignment ::=
    LazyCompoundAndAssignment
    | LazyCompoundOrAssignment

LazyCompoundAndAssignment ::=
    NonDeclarativeExpression &&= NonDeclarativeExpression

LazyCompoundOrAssignment ::=
    NonDeclarativeExpression ||= NonDeclarativeExpression

Examples

value &&= true
value ||= false

6.8. Index Expressions

Syntax

IndexExpression ::=
    NonDeclarativeExpression [ NonDeclarativeExpression ]

Examples

 a := [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
a[1][2]

6.9. Access Expressions

Syntax

AccessExpression ::=
    FieldAccessExpression
    | NamespaceAccessExpression

FieldAccessExpression ::=
    NonDeclarativeExpression . FieldSelector

FieldSelector ::=
    IndexedFieldSelector
    | NamedFieldSelector

IndexedFieldSelector ::=
    DecimalLiteral

NamedFieldSelector ::=
    Name

NamespaceAccessExpression ::=
    NonDeclarativeExpression :: Name

Examples

foo.bar.1
foo::bar

6.10. Call Expressions

Syntax

CallExpression ::=
    NonDeclarativeExpression ( ParameterList? )


ParameterList ::=
    Parameter (, Parameter)* ,?


Parameter ::=
    Name
    | Name = NonDeclarativeExpression

Examples

bar := foo(1, 2, 3, should_cache=true, should_log=false)

6.11. Implicit Call Expressions

Syntax

ImplicitCallExpression ::=
    NonDeclarativeExpression < TypeArgumentList? >

Examples

value := foo<i32, i32>()
SizedPointer(data, len) := transmute<_, SizedPointer>(value)

6.12. Tuple Expressions

Syntax

TupleExpression ::=
    ( ParameterList? )

Examples

(1, 'c', [1, 2])
(i = 1, am = 'c', named = [1, 2])

6.13. Control Flow Expressions

6.13.1. Return Expressions

Syntax

ReturnExpression ::=
    return NonDeclarativeExpression?

Examples

return
return 52

6.13.2. Break Expressions

Syntax

BreakExpression ::=
    break

Examples

loop {
    x := get_number()

    if x > 2 {
        break
    }
}

6.13.3. Continue Expressions

Syntax

ContinueExpression ::=
    continue

Examples

loop {
    x := get_number()

    if x > 2 {
        continue
    }
}

6.14. Block Expressions

Syntax

BlockExpression ::=
    | BodyBlockExpression
    | LoopExpression
    | IfExpression
    | MatchExpression
    | UnsafeBlockExpression

6.14.1. Body Blocks

Syntax

BodyBlockExpression ::=
    { Statement* Expression? }

Examples

foo := () => {
    mut t := {
        x := 1
        y := 2
        x + y
    }

    {
        t = do(t)
        t = something(t)
        t = crazy(t)
        t = with(t)
        t
    }
}

6.14.2. Unsafe Blocks

Warning

This specification is not finalised.

Syntax

UnsafeBlockExpression ::=
    unsafe BlockExpression

Examples

#unsafe launch_rocket := () => {
    Intrinsics::write(0x1234, 0x5678)
    ...
}


main := () => {
    unsafe {
        launch_rocket()
    }
}

6.15. Loop Expressions

Syntax

LoopExpression ::=
    WhileLoopExpression
    | ForLoopExpression
    | InfiniteLoopExpression

LoopBody ::=
    BlockExpression

6.15.1. While Loops

Syntax

WhileLoopExpression ::=
    while NonDeclarativeExpression LoopBody

Examples

mut x := initial_x()
mut y := initial_y()


while x < 2 && y > 3 {
    x = next_x_step(x)

    if x < 0 || y < 0 {
        break
    }

    if x > 2 {
        y = next_y_step(y)
    } else {
        y = previous_y_step(y)
    }
}

6.15.2. For Loops

Syntax

ForLoopExpression ::=
    for Pattern in NonDeclarativeExpression LoopBody

Examples

ChessBoard := type [[Cell; 8]; 8]

initialise_chess_board := () -> ChessBoard => {
    mut chess_board := [[Cell::Empty; 8]; 8]

    for row in 0..8 {
        for cell in 0..8 {
            chess_board[row][cell] = match (row, cell) {
                ...
            }
        }
    }

    chess_board
}

6.15.3. Infinite Loops

Syntax

InfiniteLoopExpression ::=
    loop LoopBody

Examples

loop {
    print("zoom!")
}

6.16. If Expressions

Syntax

IfExpression ::=
    if NonDeclarativeExpression BlockExpression ElseExpression?

ElseExpression ::=
    else (IfExpression | BodyBlockExpression)

Examples

if b == 2 {
    print("b is 2")
} else if b == 3 {
    print("b is 3")
} else {
    print("b isn't 2 or 3 ")
}

6.17. Match Expressions

Syntax

MatchExpression ::=
    match NonDeclarativeExpression { MatchArmList? }

MatchArmList ::=
    MatchArm (, MatchArm)* ,?

MatchArm ::=
    MacroInvocationHeader?
    Pattern => NonDeclarativeExpression

Examples

match foo() {
    0 | 1 => print("Got zero or one"),
    2 => print("Got two"),
    3 => print("Got three"),
    4 if the_sun_is_right() => print("Got 4 when the sun is right!"),
    4..10 => print("Got 4 to 10"),
    _ => print("Got something else")
}

6.18. Imports

Syntax

ImportExpression ::=
    import ( StringLiteral )

Examples

a := import("lib/a");
b := import("lib/b");
c := import("lib/sub/c");

6.19. Range Expressions

Syntax

RangeExpression ::=
    InclusiveRangeExpression
    | ExclusiveRangeExpression

InclusiveRangeExpression ::=
    .. NonDeclarativeExpression
    | NonDeclarativeExpression ..

ExclusiveRangeExpression ::=
    ..< NonDeclarativeExpression
    | NonDeclarativeExpression ..<

Examples

1..
42..<86
dawn..dusk
..< 5

6.20. Types in Expressions

Syntax

TypeExpression ::=
    type Type

Examples

ChessBoard := type [[Cell; 8]; 8]
NumberTypeAlias := type i32

6.21. Macro Invocations as Expressions

syntax

ExpressionMacroInvocation ::=
    MacroInvocationHeader NonDeclarativeExpression

Examples

#dump_ast
foo := () => {
    ...
}

#non_exhaustive
Bar := enum(
    Foo,
    Bar,
    Baz,
)

#[repr("C")]
SizedPointer := struct(&raw u8, usize)