Overview Source Code Bug Tracker Language Reference
Primitive Type | Equivalent C Type | Description |
---|---|---|
i8 |
int8_t |
8-bit signed integer |
i16 |
int16_t |
16-bit signed integer |
i32 |
int32_t |
32-bit signed integer |
i64 |
int64_t |
64-bit signed integer |
u8 |
uint8_t |
8-bit unsigned integer |
u16 |
uint16_t |
16-bit unsigned integer |
u32 |
uint32_t |
32-bit unsigned integer |
u64 |
uint64_t |
64-bit unsigned integer |
f32 |
float |
32-bit floating point value |
f64 |
double |
64-bit floating point value |
bool |
bool |
Boolean value |
void |
void |
Void type |
Given arbitrary types a
, b
, c
and non-negative integer n
:
Derived Type | Equivalent C Type | Description |
---|---|---|
*a |
const a* |
Immutable pointer to a |
mut*a |
a* |
Mutable pointer to a |
func (a, b) c |
const c (*foo)(a, b) |
Immutable pointer to a function |
[n]a |
a[n] |
Array of a of size n |
struct(a, b) |
N/A | Unlabeled struct |
struct(foo a, bar b) |
struct { a foo; b bar; } |
Labeled struct |
packed(a, b) |
N/A | Packed unlabeled struct |
packed(foo a, bar b) |
struct { a foo; b bar; } __attribute__((packed)) |
Packed labeled struct |
i32
literals expressed in decimal, hexadecimal, octal and binary:
12, 0xff, 0o127, 0b10101
i8
, i16
, i64
literals:
100c, 128h, 55l
u8
, u16
, u32
, u64
literals:
123uc, 85uh, 10u, 15ul
i8
literals expressed as characters:
'a', 'b', '\n', '\\'
bool
literals:
true, false
*i8
(“string”) literals:
"hello\n", "asdf", nil
The special nil
literal is the same value as 0
but is of type *i8
. It is useful for setting immutable pointers to zero since they cannot be cast to or from integers or mutable pointers.
var a = nil; // a is of type *i8
var b = *i32(nil); // b is of type *i32
var c = *my_type(nil); // c is of type *my_type
Arrays are constructed with curly braces:
val i32array = { 12, 13, 14 };
i32array[0]; i32array[1]; i32array[i32array[1]]; // elements accessed by index
Zero-initialized arrays can be constructed with the following syntax:
val zero_array = [i32; 3]; // equivalent to { 0, 0, 0 }
Packed and non-packed unlabeled structs:
val a = (1, 'a', 3ul); // struct with members of type i32, i8 and u64
val b = (: nil, 0xff :) // packed struct with members of type *i8 and i32
a.0; a.1; a.2; // members are accessed by index
Packed and non-packed labeled structs:
val a = struct(foo i32, bar i8)(12, 'a'); // struct with members foo and bar
val b = packed(asdf u64, qwer i32)(3ul, 12); // packed struct with members asdf and qwer
a.foo; a.bar; // members are accessed by name
type my_type = struct(one i32, two i32);
val c = my_type(1, 2);
c.one; c.two;
Variables and constants are declared with var
and val
respectively. The mutability of variables and constants applies to their members/elements as well.
var a = 1;
a = 2; // mutable
val b = 0; // immutable
var c = (1, 2, 3);
c.0 = 12; // mutable
val d = (3, 4, 5); // immutable
var b = [2; i32];
b[0] = 1; // mutable
val c = { 0xae, 0xbeef, 0xc0ffee }; // immutable
Types can be specified explicity:
var a i32 = 0;
val b struct(i8, struct(i32, i32)) = ('a', (0, 1));
Function declarations:
func f(a i32, b i32) void; // forward declaration
func main(argc i32, argv **i8) i32 {
f();
return 0;
}
func f(a i32, b i32) void {}
Functions are public by default but can be made private with the private
keyword:
private func secret() void {}
Functions declared with extern
are assumed to be defined in a different object file:
extern func printf(s *i8) void;
func main(argc i32, argv **i8) i32 {
printf("hello\n");
return 0;
}
Pointers can be mutable (read + write) or immutable (read-only).