Types

Primitive Types

TypeSizeDescription
i648 bytes64-bit signed integer (default)
i324 bytes32-bit signed integer
i81 byte8-bit signed integer (byte)
f648 bytes64-bit floating point
bool8 bytesBoolean (true = 1, false = 0)

i64 is the default integer type. Booleans are syntactic sugar for i64 values.

Pointers

let p: &i64      // pointer to i64
let s: &i8       // pointer to bytes (string)
let pp: &&i64    // pointer to pointer

Dereference with *:

let x: i64 = 42
let p: &i64 = &x
print_i64(*p)    // prints 42

Strings in Jda are &i8 — pointers to null-terminated byte arrays.

Arrays

let arr: i64[10]    // fixed-size array of 10 i64s
arr[0] = 42
print_i64(arr[0])

Arrays in structs:

struct Buffer {
    data: i64[256]
    len: i64
}

For dynamic arrays, use the vec stdlib package:

import "vec"

let v = vec_new()
vec_push(v, 10)
vec_push(v, 20)
vec_push(v, 30)
print_i64(vec_len(v))    // 3
print_i64(vec_get(v, 0)) // 10

Structs

struct Point {
    x: i64
    y: i64
}

let p = Point{}
p.x = 10
p.y = 20

Structs can be nested, contain arrays, and be generic. See Structs & OOP for the full guide.

Generics

Functions and structs can be generic:

fn max<T>(a: T, b: T) -> T {
    if a > b { ret a }
    ret b
}

struct Pair<T> {
    first: T
    second: T
}

The compiler monomorphizes generics — max<i64> becomes max_i64, Pair<i64> becomes Pair_i64.

Const Generics

Compile-time integer parameters:

fn zeros<const N>() -> [i64; N] {
    let arr: [i64; N]
    for i in range(N) { arr[i] = 0 }
    ret arr
}

let a = zeros<10>()  // array of 10 zeros

Enums

enum Color {
    Red,
    Green,
    Blue,
}

Enum values are integers starting from 0.

Type Conversions

Use the conv stdlib package for string/integer conversions:

import "conv"

let s = itoa(42)        // i64 -> string
let n = atoi("42")      // string -> i64
let h = itoa_hex(255)   // i64 -> hex string "ff"

Use as for type casts between numeric types:

let x: i64 = 256
let b: i8 = x as i8