Operators
Operators
Operator | Description |
---|---|
^ |
Dereference raw pointer |
== , != |
Equal to and Not Equal to |
< , <= , > , >= |
Comparison operators |
@const |
Address Of immutable addressable expression |
@mut |
Address Of mutable addressable expression |
@ |
Raw pointer offset |
==
& !=
Equality Operations
==
checks if the value on the left and the value on the right are equal.
!=
checks if the value on the left and the value on the right are not equal.
For raw pointers, this compares the memory addresses stored in the pointers rather than the values stored at the memory address.
Syntax
EQUAL := EXPRESSION == EXPRESSION
NOT_EQUAL := EXPRESSION != EXPRESSION
Semantics
x, y: T, T: Primitive :- x == y -> bool
x, y: T, T: Primitive :- x != y -> bool
<
, <=
, >
, & >=
Comparison Operations
These are the ordering operations and compare two values to see what relative order they are too each other.
For raw pointers, these compare the memory addresses stored in the pointer rather than the values stored at the memory address.
Syntax
LT := EXPRESSION < EXPRESSION
LTE := EXPRESSION <= EXPRESSION
GT := EXPRESSION > EXPRESSION
GTE := EXPRESSION >= EXPRESSION
Semantics
x, y: T, T: Primitive :- x < y -> bool
x, y: T, T: Primitive :- x <= y -> bool
x, y: T, T: Primitive :- x > y -> bool
x, y: T, T: Primitive :- x >= y -> bool
@const
& @mut
Raw Pointer Creation
The Address Of operators return a raw pointer to the location in memory
where the value of the operand is stored. The operand for @const
and @mut
must be an addressable expression.
An addressable expression is any expression which is logically tied to a location in memory and is not a temporary variable used for transferring data between calls. An example of an addressable expression is a named variable, or the element of an array which is bound to a variable. An addressable expression may be stored in the stack or in the heap.
An example of a non-addressable expression, which may have a location
in memory is the temporary value of a structure expression:
MyStruct{ x: 1, y: 2, z: 3}
.
This may be allocated to the stack to because it is too big to fit in
a register, but that location is considered strictly temporary and may get
used for later structure expressions, or, for small structures, be optimized
into a physical register or integer literal. Therefore, there can be no
guarantee that it can be safely addressed and it is considered non-addressable.
Note about Mutability
It’s important to remember that there are two different concepts of
mutability for a value of type pointer. The first, and most important,
is the mut
in *mut T
: this means that the location the pointer points
to can be mutated through the pointer. The second is the mut
that
refers to a variable of type *(const|mut) T
(let mut p: *const i64 ...
),
this means that the pointer variable can be mutated (not the location it points to);
in other words, that the pointer can be changed to point do a different address.
Example
let i: i64 := 10;
let mut pi: *const i64 := @const i;
let mut j: i64 := 15;
let pj: *mut i64 := @mut j;
mut pi := @const j; // Here, `pi` is mutated to point to `j`.
// Note, that it still _cannot_ be used to mutate `j`
Syntax Rules
ADDRESS_OF := @(const|mut) EXPRESSION
The @
operator must be followed by either const
or mut
. This indicates
whether to pointer can be used to write to the memory location or only
to read from the memory location.
Semantic Rules
// x is an addressable value, T is a type
x: T :- @const x -> *const T
mut x: T :- @const x -> *const T, @mut x -> *mut T
@const
can take any addressable value, whether it is mutable or immutable
and will always return a value of *const T
, where T
is the type of the
operand.
@mut
can only be applied to an addressable value that is declared as mutable.
And will return a value of type *mut T
, where T
is the type of the operand.
This pointer can be used to write to the memory location as well as read from
the memory location.
^
Raw Pointer Dereference operator
Taking a *const T
or *mut T
value as an operand, the ^
operator accesses
the value stored in the location pointed to by the operand.
If the location is mutable (operand is of type *mut T
), then the
dereference expression can be used on the left of a mutation expression.
If T
is an array or a structure, then the result of the dereference
operation can be used as the left of element access or field access operators.
Example
// Dereference a primitive value
let i: i64 := 5;
let p: *const i64 := @const i;
project::std::io::writei64ln(^p); // Prints 5
// Using the dereference in a mutation expression
let mut j: i64 := 10;
let pj: *mut i64 := @mut j;
mut ^pj := ^pj + 1; // Adds 1 to j
// Using with an array
let arr: [i32; 2] := [1i32, 2i32];
let p: *const [i32; 2] := @const arr;
^p[0]; // Will resolve to 1i32
Syntax Rules
DEREFERENCE := ^EXPRESSION
Semantic Rules
x: *const T :- ^x -> T
x: *mut T :- ^x -> mut T
@
Raw Pointer Offset
The @
operator is a binary operator and is used for computing address
offsets from a raw pointer value. Given a pointer to a memory location,
you can use @
to move to the left or the right of that memory location.
The offsets are computed in increments of the size of the underlying type.
So, if p
is pointer to an i64
, then p@1
would increment the address
by 1*size_of(i64)
or 8
bytes and p@-3
would decrement the address by
-3*size_of(i64)
or -24
bytes.
The left operand must be of type *(const|mut) T
and the resulting type
will be the same as the left operand. The right operand must be an integer
type (either signed or unsigned).
Example:
let mut arr: [i64; 3] := [1, 2, 3];
let mut p: *const i64 := @const arr[1];
project::std::io::writei64ln(^(p@-1)); // Will print 1
let p2: *const i64 := p@1;
project::std::io::writei64ln(^p2); // Will print 3
Syntax Rules
RAW_POINTER_OFFSET := EXPRESSION @ EXPRESSION
Semantic Rules
x: *const T, o: i8|i16|i32|i64|u8|u16|u32|u64 :- x@o -> *const T
x: *mut T, o: i8|i16|i32|i64|u8|u16|u32|u64 :- x@o -> *mut T
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.