Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Expressions

Expressions are constructs that produce a value.

Literals

Literals are the most basic type of expression. They represent a fixed value in the source code.

  • Integer literals: 10, _
  • Float literals: 3.14
  • Boolean literals: true, false
  • Character literals: 'a'
  • String literals: "hello"
  • Null literal: null
  • Array literals: [1, 2, 3]
  • Hash Map Literals: #{ "a": 1 , "b": 2 }

Identifiers

An identifier is a name that refers to a variable, constant, or function.

int x = 5;
int y = x; // `x` is an identifier

Prefix Expressions

A prefix expression has the operator before the operand.

  • - (negation): -10
  • ! (logical NOT): !true
  • * (dereference): *ptr
  • & (address of): &value
  • ~ (bitwise NOT): ~10

Infix Expressions

An infix expression has the operator between the operands.

  • Arithmetic: +, -, *, /
  • Comparison: ==, !=, <, >, <=, >=
  • Logical: &&, ||
  • Bitwise: |, ^, &
int x = 10;
int y = -4;

int sum = x + y;
bool are_equal = x == y;
int bit_or = x | y;

Note

Every int and float values in ralix are 64-bits and this cannot be changed. Why? Because I suck

Ralix follow C-style precedence which look like this:

Operator(s)Precedence
Default expr parsing precedenceLowest
||LogicalOr
&&LogicalAnd
|BitwiseOr
^BitwiseXOr
&BitwiseAnd
==, !=Equals
>, <, >=, <=LessGreater
>>, <<Shift
+, -Sum
*, /, %Product
!, -, *, ~Prefix
func(param)FunctionCall
hash_map["key"], Namespace::Item, Class.attributeAccess

if Expressions

An if expression allows for conditional execution. It must have an else block.

str result =
    if x > 5: "greater"
    else: "not greater"
;

Function Calls

A function call expression invokes a function with a list of arguments.

#![allow(unused)]
fn main() {
println("Hello, World!");
}

Index Expressions

An index expression is used to access an element of an array or a hash-map.

arr[int] my_arr = [1, 2, 3];
int first = my_arr[0];

Scope Expressions

A scope expression creates a new scope. The last expression in the scope is the value of the scope expression.

int y = {
    int x = 5;
    x + 1 // This is the return value of the scope
}; // x is dropped, y is 6

typeof Expressions

A typeof expression returns the type of a value.

int x = 10;
type[int] type_of_x = typeof x; // `type_of_x` is `type[int]`

Important

typeof expression only returns the type of the value during runtime. Example:

#![allow(unused)]
fn main() {
arr[int] my_arr = []; // Empty arrays automatically bind `unknown` type generic
typeof my_arr // `arr[unknown]`
}

Function Literals

A function literal is an anonymous function. When you want to bind a function you’d probably want to create a function statement instead

let add = fn(int a, int b) -> int: {
    return a + b;
};