Skip to content

Examples

Felix Schoeller edited this page Sep 9, 2020 · 5 revisions

These examples are taken directly from the test suite. When the language has matured, I will add more usable examples.

test/runnable/undefined.kan:

// Outputs:
// 1 mystruct
// 2 other struct
import "io";

type MyStruct struct {
    id: i32,
    name: string
}

def main() {
    let ms: MyStruct = undefined;
    init(&ms);

    io.printf("%d %s\n", ms.id, ms.name);
    ms = init_ret(undefined);
    io.printf("%d %s\n", ms.id, ms.name);
}

def init(ms: *MyStruct) {
    ms.id = 1;
    ms.name = "mystruct";
}

def init_ret(ms: MyStruct): MyStruct {
    ms = MyStruct { id: 2, name: "other struct" };
    return ms;
}

test/runnable/bintree.kan:

// Outputs:
// Felix is 20 years old
// Jan is 22 years old
// Robin is 23 years old
import "io";

type Person struct {
    name: string,
    age: i32
}

type Node struct {
    data: Person,
    left: *Node,
    right: *Node
}

type Tree struct {
    root: *Node
}

def insert(tree: *Tree, person: Person): void {
    if tree.root == null {
        tree.root = new_node(person);
        return;
    } 

    insert_node(tree.root, person);
}

def new_node(person: Person): *Node {
    return new Node { data: person, left: null, right: null };
}

def insert_node(node: *Node, person: Person): void {
    if person.age < node.data.age {
        if node.left == null {
            node.left = new_node(person);
        } else {
            insert_node(node.left, person);
        }
    } else if person.age > node.data.age {
        if node.right == null {
            node.right = new_node(person);
        } else {
            insert_node(node.right, person);
        }
    }
}

def traverse(tree: *Tree): void {
    if tree.root == null {
        return;
    }

    traverse_node(tree.root);
}

def traverse_node(node: *Node): void {
    if node == null {
        return;
    }

    traverse_node(node.left);
    io.printf("%s is %d years old\n", node.data.name, node.data.age);
    traverse_node(node.right);
}

def delete_tree(tree: *Tree): void {
    if tree.root != null {
        delete_node(tree.root);
    }
}

def delete_node(node: *Node): void {
    if node == null {
        return;
    }

    delete_node(node.left);
    delete_node(node.right);
    delete node;
}

def main(): void {
    let tree = new Tree { root: null };
    insert(tree, Person { name: "Jan", age: 22 });
    insert(tree, Person { name: "Felix", age: 20 });
    insert(tree, Person { name: "Robin", age: 23 });

    traverse(tree);

    delete_tree(tree);
    delete tree;
}

test/runnable/float-add.kan:

// Outputs:
// 2.00
import "io";

def main(): void {
    let s = "asdf";
    let f = 1.5 + 0.5;
    io.printf("%.2f\n", f);
}

test/runnable/chars.kan:

// Outputs:
// h
// a
import "io";

def main(): void {
    let s = "hello";
    let c = *s;

    io.printf("%c\n", c );
    let c: i8 = 'A';
    io.printf("%c\n", c + ' ');
}

test/runnable/simple-func-ptr.kan:

// Outputs:
// 2
import "io";

def add(a: i32, b: i32): i32 {
    return a + b;
}

def sub(a: i32, b: i32): i32 {
    return a - b;
}

def calc(a: i32, b: i32): i32 {
    let f = &add;
    let i = f(a, b);
    f = &sub;
    return f(i, a);
}

def main() {
    let f = &io.printf;
    f("%d\n", calc(1, 2));
    return;
}

test/runnable/simple-malloc.kan:

// Outputs:
// Another Street
import "io";

type Address struct {
    street: string
}

type Person struct {
    age: i32,
    address: *Address
}

extern def malloc(size: i32): *Address;
extern def free(ptr: *Address): void;

def main(): void {
    let a = malloc(8);
    a.street = "One Street";

    let p = Person { age: 20, address: a };
    p.address.street = "Another Street";

    io.printf("%s\n", p.address.street);

    free(a);
}

test/runnable/delegates.kan:

// Outputs:
// HELLO
// hello
// 1
// hello 2
import "io";

extern def strlen(s: string): usize;

def map(s: string, mapper: CharMapper): string {
    let len = strlen(s);
    for let i: usize = 0; i < len; i += 1 {
        *(s + i) = mapper(*(s + i));
    }
    return s;
}

def to_upper(c: i8): i8 {
    return c - 32 * ((c >= 'a' && c <= 'z') as i8);
}

type Kek struct {
}

def (k: Kek) k1() {}
def k2(k: Kek) {}

def main() {
    let mptr = &Kek.k1;
    mptr = &k2;

    let s: [6]i8 = "hello";
    io.printf("%s\n", map(&s[0], &to_upper));

    let s: [6]i8 = "HELLO";
    io.printf("%s\n", map(&s[0], &to_lower));

    let cb1 = CallbackData { id: 1, cb: &CallbackData.print };
    let cb2 = CallbackData { id: 2, cb: &CallbackData.print_with_hello };

    cb1.cb(&cb1);
    cb2.cb(&cb2);
}

def to_lower(c: i8): i8 {
    return c + 32 * ((c >= 'A' && c <= 'Z') as i8);
}

delegate def CharMapper(c: i8): i8;

def (cb: *CallbackData) print() {
    io.printf("%d\n", cb.id);
}

def (cb: *CallbackData) print_with_hello() {
    io.printf("hello %d\n", cb.id);
}

delegate def Callback(data: *CallbackData);

type CallbackData struct {
    id: i32,
    cb: Callback
}

test/runnable/dispatch-table.kan:

// Outputs:
// My favorite toy is a ball
// My favorite food are mice
import "io";

type AnimalKind enum {
    Dog, Cat
}

type Animal struct {
    kind: AnimalKind
}

def (a: *Animal) greet(table: [2]Greeter) {
    table[a.kind as i32](a);
}

delegate def Greeter(a: *Animal);


type Dog struct {
    animal: Animal,
    fav_toy: string
}

def dog(): Dog {
    return Dog { animal: Animal { kind: AnimalKind.Dog }, fav_toy: "ball" };
}

def (d: *Dog) greet() {
    io.printf("My favorite toy is a %s\n", d.fav_toy);
}

type Cat struct {
    animal: Animal,
    fav_food: string
}

def cat(): Cat {
    return Cat { animal: Animal { kind: AnimalKind.Cat }, fav_food: "mice" };
}

def (c: *Cat) greet() {
    io.printf("My favorite food are %s\n", c.fav_food);
}

def main() {
    let dispatch_table: [2]Greeter = undefined;
    dispatch_table[0] = &Dog.greet as Greeter;
    dispatch_table[1] = &Cat.greet as Greeter;

    let dog = dog();
    let cat = cat();

    let dog = &dog as *Animal;
    let cat = &cat as *Animal;

    dog.greet(dispatch_table);
    cat.greet(dispatch_table);
}

test/runnable/for-scope.kan:

// Outputs:
// 4
// 4
// 4
import "io";

def main() {
    for let i = 0; i < 3; i += 1 {
        let i = 4;
        io.printf("%d\n", i);
    }
}

test/runnable/array-field-access.kan:

// Outputs:
// 4
// 5
// 6
// 4
// 1
// 1
// 4
// 5
// 6
import "io";

type Type struct {
    i: i32
}

type Other struct {
    t: Type
}

def main() {
    let a: [2]Type = undefined;
    a[0] = Type { i: 42 };
    a[1].i = (a[0].i = 4) + 1;
    io.printf("%d\n", a[0].i);
    io.printf("%d\n", a[1].i);
    a[1].i += 1;
    io.printf("%d\n", a[1].i);

    let o: [2]Other = undefined;
    o[0].t = a[0];
    io.printf("%d\n", o[0].t.i);
    o[1].t.i = o[0].t.i = 1;
    io.printf("%d\n", o[0].t.i);
    io.printf("%d\n", o[1].t.i);

    let a: [2][2]Type = undefined;
    a[0][0] = Type { i: 42 };
    a[0][1].i = (a[0][0].i = 4) + 1;
    io.printf("%d\n", a[0][0].i);
    io.printf("%d\n", a[0][1].i);
    a[0][1].i += 1;
    io.printf("%d\n", a[0][1].i);
}

test/runnable/continue.kan:

// Outputs:
// 0 1
// 1 0
// 1 2
import "io";

def main() {
    for let j = 0; j < 3; j += 1 {
        continue;
        io.printf("test\n");
    }

    for let i = 0; i < 3; i += 1 {
        if i == 2 {
            continue;
        }

        for let j = 0; j < 3; j += 1 {
            if (i + j) % 2 == 0 {
                continue;
            }

            io.printf("%d %d\n", i, j);
        }

        let k = 0;
        while k < 3 {
            k += 1;
            continue;
            io.printf("test\n");
        }
    }
}

test/runnable/array-index.kan:

// Outputs:
// a
// b
// 0
// 1
// 2
// 3
// 20
// 10
// 1
// 2
// 3
// 4
import "io";

extern def malloc(size: usize): *void;

def main() {
    let arr = malloc(5 * 5 * sizeof string) as **string;
    defer delete arr;

    let a: [2][2]i8 = undefined;
    a[0][0] = 'a';
    io.printf("%c\n", a[0][0]);

    let b: [2]i8 = undefined;
    b[0] = 'b';
    io.printf("%c\n", b[0]);

    for let i = 0; i < 2; i += 1 {
        for let j = 0; j < 2; j += 1 {
            a[i][j] = (i * 2 + j) as i8;
        }
    }
    for let i = 0; i < 2; i += 1 {
        for let j = 0; j < 2; j += 1 {
            io.printf("%d\n", a[i][j] as i32);
        }
    }

    let test = Test { i: undefined };
    test.i[0] = 10;
    test.i[1] = 20;

    let p = &test;
    io.printf("%d\n", (*p).i[1]);

    let arr: [2]*Test = undefined;
    arr[0] = arr[1] = p;

    io.printf("%d\n", (*arr[0]).i[0]);

    let nums: [1][1]i32 = undefined;
    nums[0][0] = 1;
    io.printf("%d\n", nums[0][0]);

    let i = &nums[0][0];
    *i = 2;
    io.printf("%d\n", nums[0][0]);

    let p: *[1]i32 = &nums[0];
    p[0][0] = 3;
    io.printf("%d\n", nums[0][0]);

    let p = &nums;
    p[0][0][0] = 4;
    io.printf("%d\n", nums[0][0]);
}

type Test struct {
    i: [2]i32
}

test/runnable/defer-correct-var-scope.kan:

// Outputs:
// 1
// 2
// 3
import "io";

def first() {
    defer io.printf("1\n");
    let run = true;
    return;
}

def second() {
    defer io.printf("3\n");
    let x = 3;
    defer io.printf("2\n");
    let x = 2;
}

def main() {
    first();
    second();
}

test/runnable/shift.kan:

// Outputs:
// 388
// 194
// 8
import "io";

def main() {
    let i: i32 = 'a' << 2;
    io.printf("%d\n", i);
    io.printf("%d\n", i >> 1);

    io.printf("%d\n", 1 << 3);
}

test/runnable/builder.kan:

// Outputs:
// { (null), 2, 3, (null) }
// { 1, (null), (null), 4 }
import "io";

type MyComplexType struct {
    field1: string,
    field2: string,
    field3: string,
    field4: string
}

def (c: *MyComplexType) print() {
    io.printf("{ %s, %s, %s, %s }\n", c.field1, c.field2, c.field3, c.field4);
}

type Builder struct {
    inner: MyComplexType
}

def builder(): Builder {
    return Builder {
        inner: MyComplexType {
            field1: null,
            field2: null,
            field3: null,
            field4: null
        }
    };
}

def (b: *Builder) field1(value: string): *Builder {
    b.inner.field1 = value;
    return b;
}

def (b: *Builder) field2(value: string): *Builder {
    b.inner.field2 = value;
    return b;
}

def (b: *Builder) field3(value: string): *Builder {
    b.inner.field3 = value;
    return b;
}

def (b: *Builder) field4(value: string): *Builder {
    b.inner.field4 = value;
    return b;
}

type CopyBuilder struct {
    inner: MyComplexType
}

def copy_builder(): CopyBuilder {
    return CopyBuilder {
        inner: MyComplexType {
            field1: null,
            field2: null,
            field3: null,
            field4: null
        }
    };
}

def (b: CopyBuilder) field1(value: string): CopyBuilder {
    b.inner.field1 = value;
    return b;
}

def (b: CopyBuilder) field2(value: string): CopyBuilder {
    b.inner.field2 = value;
    return b;
}

def (b: CopyBuilder) field3(value: string): CopyBuilder {
    b.inner.field3 = value;
    return b;
}

def (b: CopyBuilder) field4(value: string): CopyBuilder {
    b.inner.field4 = value;
    return b;
}

def main() {
    builder().field3("3").field2("2").inner.print();
    copy_builder().field1("1").field4("4").inner.print();
}

test/runnable/float_int_cast.kan:

// Outputs:
// 1
// 1
// 1
// 3
import "io";

def main() {
    let f = 3.14;
    let i = f as i32;
    io.printf("%d\n", i == 3);

    let x = i as f32 + 0.14;
    io.printf("%d\n", (x - f) < 0.001);

    let x = x as f64;
    io.printf("%d\n", x - (f as f64) < 0.001);
    io.printf("%d\n", x as i16);
}

test/runnable/struct-assign.kan:

// Outputs:
// 21
// 1
import "io";

type Struct struct {
    i: i32
}

def main() {
    let s = Struct { i: 42 };
    io.printf("%d\n", s.i /= 2);
    io.printf("%d\n", s.i %= 2);
}

test/runnable/union-struct.kan:

// Outputs:
// 42
// hello
import "io";

type Union union {
    one: Struct1, two: Struct2
}

type Tag enum {
    One, Two
}

type Struct1 struct {
    i: i32
}

type Struct2 struct {
    s: string
}

type Data struct {
    tag: Tag,
    inner: Union
}

def one(i: i32): Data {
    return Data {
        tag: Tag.One,
        inner: Union { one: Struct1 { i: i } }
    };
}

def main() {
    let first = one(42);
    io.printf("%d\n", first.inner.one.i);

    first.tag = Tag.Two;
    first.inner.two = Struct2 { s: "hello" };
    io.printf("%s\n", first.inner.two.s);
}

test/runnable/euler1.kan:

// Outputs:
// 233168
import "io";

def main() {
    let lim = 1000;
    let sum = 0;
    for let i = 0; i < lim; i = i + 1{
        if i % 3 == 0 || i % 5 == 0 {
            sum = sum + i;
        }
    }

    io.printf("%d\n", sum);
}

test/runnable/void-ptr-cast.kan:

// Outputs:
// 42
import "io";

type Person struct {
    age: i32
}

def main(): void {
    let p = Person { age: 42 };
    print_as_int(&p as *void);
}

def print_as_int(ptr: *void): void {
    io.printf("%d\n", *(ptr as *i32));
}

test/runnable/string-format.kan:

// Outputs:
// My name is: Felix
import "io";

extern def snprintf(fmt: string, size: i32, ...): i32;
extern def malloc(size: i32): string;

def main(): void {
    let s = malloc(100);
    let n = snprintf(s, 100, "My name is: %s", "Felix");

    if n >= 0 && n < 100 {
        io.printf("%s\n", s);
    }

    delete s;
}

test/runnable/enums.kan:

// Outputs:
// 1
// 1
// 0
// 1
// 1
// 1
// 2
// 3
// 4
// 1
// 3 3
import "io";

type MyEnum enum {
    First, Second, Third
}

type WithInit enum {
    First = 2, Second, Third
}

def main() {
    let x = MyEnum.First;
    let y: MyEnum = MyEnum.Second;

    if x == y {
        io.printf("failed\n");
    }

    y = MyEnum.First;
    io.printf("%d\n", x == y);
    io.printf("%d\n", x == MyEnum.First);
    io.printf("%d\n", x < MyEnum.First);
    io.printf("%d\n", x <= MyEnum.Second);
    io.printf("%d\n", x <= MyEnum.Third);
    io.printf("%d\n", x != MyEnum.Third);

    io.printf("%d\n", WithInit.First);
    io.printf("%d\n", WithInit.Second);
    io.printf("%d\n", WithInit.Third);
    io.printf("%d\n", WithInit.First == WithInit.First);

    io.printf("%d %d\n", MyEnum.len, WithInit.len);
}

test/runnable/simple-array.kan:

// Outputs:
// 1
// 2
// 3
import "io";

extern def malloc(size: usize): *i32;
extern def free(arr: *i32): void;

def main(): void {
    let arr = malloc(3 * sizeof i32);
    *arr = 1;
    *(arr + 1) = 2;
    *(arr + 2) = 3;

    let i = 0;
    while i < 3 {
        io.printf("%d\n", *(arr + i));
        i = i + 1;
    }

    free(arr);
}

test/runnable/break.kan:

// Outputs:
// 0
// 1
import "io";

def main() {
    for let i = 0; i < 4; i += 1 {
        if i == 2 {
            break;
        }

        io.printf("%d\n", i);
    }
}

test/runnable/euler3.kan:

// Outputs:
// 6857
import "io";

def isqrt(n: i64): i64 {
    let res: i64 = 0;
    let bit: i64 = 4611686018427387904; // 1 << 62

    while bit > n {
        bit = bit / 4;
    }

    while bit != 0 {
        let rb = res + bit;

        if n >= rb {
            n = n - rb;
            res = (res / 2) + bit;
        } else {
            res = res / 2;
        }

        bit = bit / 4;
    }

    return res;
}

def is_prime(n: i64): bool {
    if n < 2 {
        return false;
    }

    if n < 4 {
        return false;
    }

    if n % 2 == 0 {
        return false;
    }

    let end = isqrt(n);
    for let i: i64 = 3; i <= end; i = i + 2 {
        if n % i == 0 {
            return false;
        }
    }

    return true;
}

def main() {
    let n: i64 = 600851475143;
    let start = isqrt(n);

    for let i: i64 = start; i > 1; i = i - 1 {
        if n % i == 0 && is_prime(i) {
            io.printf("%d\n", i);
            return;
        }
    }
}

test/runnable/bit-xor-not.kan:

// Outputs:
// -2
// 1
// 2
// 0
// 0
// 1
// 0
// 1
import "io";

def main() {
    io.printf("%d\n", ~1); // -2
    io.printf("%d\n", ~-2); // 1
    io.printf("%d\n", 3 ^ 1); // 2
    io.printf("%d\n", 3 ^ 3); // 0
    io.printf("%hhx\n", true ^ true); // 0
    io.printf("%hhx\n", true ^ false); // 1
    io.printf("%hhx\n", false ^ false); // 0

    let i = 5;
    i ^= 4;
    io.printf("%d\n", 1); // 1
}

test/runnable/int-cast.kan:

// Outputs:
// 2 42
// 4 42
// 8 42
// 2 65
import "io";

def main() {
    let i: i64 = 42;
    let i = i as i32;
    let i = i as i16;

    io.printf("%d %d\n", sizeof i16, i);
    io.printf("%d %d\n", sizeof i32, i as i32);
    io.printf("%d %d\n", sizeof i64, i as i64);

    i = 'A';
    io.printf("%d %d\n", sizeof i16, i);
}

test/runnable/methods.kan:

// Outputs:
// hello
// 1
// ...
// constructed
// 2
// ...
// constructed
// 3
// 4
import "io";

type Struct struct {
    name: string
}

def (s: Struct) method(i: i32) {
    io.printf("%s\n", s.name);
    io.printf("%d\n", i);
}

type Other struct {}

def (s: *Other) method(i: i32) {
    io.printf("%d\n", i);
}

def constructor(): Struct {
    io.printf("...\n");
    return Struct {name: "constructed"};
}

def main() {
    Struct{name: "hello"}.method(1);
    constructor().method(2);
    let s = constructor();
    s.method(3);

    Other{}.method(4);
}

test/runnable/float_operations.kan:

// Outputs:
// 1
// 1
// 1
import "io";

def f32_eq(first: f32, second: f32, offset: f32): bool {
    let diff = first - second;
    return diff < offset && diff > -offset;
}

def main() {
    // 1)
    let i: i64 = 5;
    let f = i as f32;
    io.printf("%d\n", f32_eq(f, 5.0, 0.00001));

    // 2)
    let f = 0.1;
    f *= -1.0;
    io.printf("%d\n", f32_eq(f, -0.1, 0.00001));

    // 3)
    f = -f;
    io.printf("%d\n", f32_eq(f, 0.1, 0.00001));
}

test/runnable/euler2.kan:

// Outputs:
// 4613732
import "io";

def main() {
    let a = 0;
    let b = 1;
    let sum = 0;
    while b <= 4000000 {
        let tmp = b;
        b = a + b;
        a = tmp;

        if b % 2 == 0 {
            sum = sum + b;
        }
    }

    io.printf("%d\n", sum);
}

test/runnable/void-ptr2ptr-deref.kan:

// Outputs:
// 1
import "io";

extern def calloc(num: usize, size: usize): *void;

def main(): void {
    let p: **void = calloc(1, sizeof *void) as **void;
    io.printf("%d\n", *p == null);

    delete p;
}

test/runnable/defer-loop.kan:

// Outputs:
// 0
// uneven 1
// 1
// 2
// uneven 3
// 3
// 4
// uneven 5
// 5
// end
import "io";

def f() {
    defer io.printf("end\n");
    let i = 0;
    while i < 10 {
        defer i += 1;
        defer io.printf("%d\n", i);
        if i % 2 == 0 {
            continue;
        }

        defer io.printf("uneven %d\n", i);
        if i > 4 {
            break;
        }
    }
}

def main() {
    f();
}

test/runnable/float-cmp.kan:

// Outputs:
// 11001
import "io";

def main(): void {
    io.printf("%d", 1.0 > 0.0);
    io.printf("%d", 1.0 >= 0.0);
    io.printf("%d", 1.0 < 0.0);
    io.printf("%d", 1.0 <= 0.0);
    io.printf("%d\n", 1.0 == 1.0);
}

test/runnable/char-sub.kan:

// Outputs:
// 9
// 0
import "io";

def main() {
    let num = '9' - '0';
    io.printf("%d\n", num);

    let num: i8 = '0' - '0';
    io.printf("%d\n", num);
}

test/runnable/empty-struct.kan:

// Outputs:

type Struct struct {
}

def main(): void {
    Struct { };

    let empty = Struct { };
}

test/runnable/defer-multiple-return.kan:

// Outputs:
// 0
// >0
// >1
// >0
// >2
// >1
// >0
// 4
// >1
// >0
// 
// 0
// 1
// 0
// 2
// 1
// 0
// 3
// 2
// 1
// 0
import "io";

def f(i: i32) {
    if i > 0 {
        defer io.printf(">0\n");
        if i > 1 {
            defer io.printf(">1\n");
            if i > 2 {
                if i == 4 {
                    io.printf("4\n");
                    return;
                }
                defer io.printf(">2\n");
                return;
            }
            return;
        }
        return;
    }
    io.printf("0\n");
}

def g(i: i32) {
    if i > 4 {
        return;
    }

    if i == 0 {
        return;
    }
    defer io.printf("%d\n", 0);
    if i == 1 {
        return;
    }
    defer io.printf("%d\n", 1);
    if i == 2 {
        return;
    }
    defer io.printf("%d\n", 2);
    if i == 3 {
        return;
    }
    defer io.printf("%d\n", 3);
}

def main() {
    for let i = 0; i < 5; i += 1 {
        f(i);
    }
    io.printf("\n");
    for let i = 0; i < 5; i += 1 {
        g(i);
    }
}

test/runnable/func-ptr-comp.kan:

// Outputs:
// 1
// 0
// 1
// 0
import "io";

def f() {

}

def g() {

}

def main() {
    io.printf("%d\n", &f == &f);
    io.printf("%d\n", &f == &g);
    let f2 = &f;
    io.printf("%d\n", &f == f2);
    let g2 = &g;
    io.printf("%d\n", f2 == g2);
}

test/runnable/assign-assign.kan:

// Outputs:
// 4 4
import "io";

def main(): void {
    let i = 0;
    let j = 0;
    i = j = 4;
    io.printf("%d %d\n", i, j);
}

test/runnable/if-statements.kan:

// Outputs:
// correct
// correct
// correct
import "io";

def f(i: i32): i32 {
    let x = 20;
    let x = x + 2;
    let x = x + 20 + 2;
    let z = x;
    let v = -i;
    return z + v;
}

def main(): i32 {
    let s = "correct";
    let x = 0;
    if f(2) == 44 {
        s = "Hello World";
        let x = 5;
    } else if f(2) == 43 {
        s = "Wrong result";
    }
    io.puts(s);

    if f(3) == 41 {
        s = "correct";
        let x = 42;
    } else {
        s = "test";
        let x = "test";
    }
    let y = x;
    while x < 2 {
        io.puts(s);
        x = x + 1;
    }
    return 0;
}

test/runnable/defer-return.kan:

// Outputs:
// end
// 1
// even
// 2
import "io";

def f(i: i32) {
    defer io.printf("%d\n", i);
    if i % 2 == 0 {
        defer io.printf("even\n");
        return;
    }

    io.printf("end\n");
}

def main() {
    f(1);
    f(2);
}

test/runnable/ptr-arith.kan:

// Outputs:
// Hello
// World
import "io";

def main(): void {
    let s = new "World Hello";
    let s2 = "Hello World";

    let str = 6 + *s;
    io.printf("%s\n", str);

    str = 7 + s2;
    str = str - 1;
    io.printf("%s\n", str);

    delete s;
}

test/runnable/for-loop.kan:

// Outputs:
// 123
// 321
// 100
import "io";

def main(): void {
    let i = 100;
    for let i = 0; i < 3; i += 1 {
        io.printf("%d", i+1);
    }
    io.printf("\n");
    for let i = 3; i > 0; i -= 1 {
        io.printf("%d", i);
    }
    io.printf("\n");
    for ;i < 101; {
        io.printf("%d\n", i);
        i = i + 1;
    }
}

test/runnable/linked-list.kan:

// Outputs:
// 1
// 2
// 3
import "io";

type Node struct {
    data: i32,
    next: *Node
}

def make_node(data: i32, next: *Node): *Node {
    return new Node { data: data, next: next };
}

def traverse(node: *Node): void {
    let n = node;
    while n != null {
        io.printf("%d\n", n.data);
        n = n.next;
    }
}

def main(): void {
    let third = make_node(42, null);
    let second = make_node(0, third);
    let first = make_node(1, second);

    // overwrite 42 with 3
    *second.next = Node { data: 3, next: null };
    *second = Node { data: 2, next: second.next };

    traverse(first);

    delete first.next.next;
    delete second;
    delete first;
}

test/runnable/inner-struct-assign.kan:

// Outputs:
// Peter, lives in Berlin in house number 100
// Hans, lives in Neuss in house number 200
import "io";

type Person struct {
    name: string,
    age: i32,
    address: Address
}

type Address struct {
    city: City,
    hnr: string // number of the house
}

type City struct {
    name: string
}

def make_peter(age: i32): Person {
    return Person { 
        name: "Peter", 
        age: age, 
        address: Address {
            city: City { name: "Berlin" },
            hnr: "100"
        } 
    };
}

def main(): i32 {
    let p = make_peter(20);
    let hans = p;
    hans.address.city.name = "Neuss";
    hans.address.hnr = "200";
    hans.name = "Hans";
    io.printf(
        "%s, lives in %s in house number %s\n", 
        p.name, p.address.city, p.address.hnr
    );
    io.printf(
        "%s, lives in %s in house number %s\n", 
        hans.name, hans.address.city, hans.address.hnr
    );
    p.age = 0;
    return p.age;
}

test/runnable/loops.kan:

// Outputs:
// 3
// 1
import "io";

def main() {
    let j = 0;
    while j < 3 {
        j += 1;
        continue;
        break;
        io.printf("test\n");
    }
    io.printf("%d\n", j);

    j = 0;
    while j < 3 {
        j += 1;
        break;
        continue;
        io.printf("test\n");
    }
    io.printf("%d\n", j);
}

test/runnable/enum-to-base-cast.kan:

// Outputs:
// 1
// 2
import "io";

type Test enum { One = 1, Two }

def main() {
    let test = Test.One;
    io.printf("%d\n", test as i32);
    io.printf("%d\n", Test.Two as i32);
    let test: i32 = Test.One as i32;
}

test/runnable/ref-op-operator.kan:

// Outputs:
// 42
import "io";

type Int struct {
    value: i32
}

def f(ptr: *i32): void {
    *ptr = 42;
}

def main(): void {
    let i = Int { value: 0 };
    f(&i.value);
    io.printf("%d\n", i);
}

test/runnable/pointer_param.kan:

// Outputs:

def test(ptr: **i32): void {

}

def main(): void {

}

test/runnable/deref-call-return.kan:

// Outputs:
// 5
import "io";

def main(): void {
    let i = 5;
    io.printf("%i\n", *test(&i));
}

def test(i: *i32): *i32 {
    return i;
}

test/runnable/defer-simple.kan:

// Outputs:
// 0
// 1
// 2
import "io";

def main() {
    io.printf("%d\n", 0);
    defer io.printf("%d\n", 2);
    io.printf("%d\n", 1);
}

test/runnable/helloworld.kan:

// Outputs:
// Hello World
import "io";

def main(): void {
    io.printf("Hello World\n");
}

test/runnable/bit-assign.kan:

// Outputs:
// 1
// 3
// 0
// 2
import "io";

def main() {
    let i = 1 & 3;
    io.printf("%d\n", i);
    let i = 1 | 3;
    io.printf("%d\n", i);
    i &= 8;
    io.printf("%d\n", i);
    i |= 2;
    io.printf("%d\n", i);
}

test/runnable/union.kan:

// Outputs:
// 42
// hello
// 33
// 2
// 42
import "io";

type Test union {
    i: i8,
    s: string
}

type Same union {
    i: i32,
    j: i32
}

def main() {
    let t = Test { i: 42 };
    io.printf("%d\n", t.i);
    t = Test { s: "hello" };
    io.printf("%s\n", t.s);

    t.i = 33;
    io.printf("%d\n", t.i);

    let p = &t.i;
    *p = 2;
    io.printf("%d\n", *p);

    let same = Same { i: 42 };
    io.printf("%d\n", same.j);
}

test/runnable/ptr-plus-eq.kan:

// Outputs:
// est
import "io";

def main() {
    let test = "test";
    test += 1;
    io.printf("%s\n", test);
}

test/runnable/short-circuit.kan:

// Outputs:
// first
// second
// third
// all
// first
// first
// second
// first
// at least one
// first
// second
// third
// at least one
// first
// second
// third
// 1
import "io";

def first(ret: bool): bool {
    io.printf("first\n");
    return ret;
}

def second(ret: bool): bool {
    io.printf("second\n");
    return ret;
}

def third(ret: bool): bool {
    io.printf("third\n");
    return ret;
}

def main() {
    if first(true) && second(true) && third(true) {
        io.printf("all\n");
    }

    if first(false) && second(true) && third(true) {
        io.printf("all\n");
    }

    if first(true) && second(false) && third(true) {
        io.printf("all\n");
    }

    if first(true) || second(false) || third(true) {
        io.printf("at least one\n");
    }

    if first(false) || second(false) || third(true) {
        io.printf("at least one\n");
    }

    let b = first(true) && (second(false) || third(true));
    io.printf("%d\n", b);
}

test/runnable/assign.kan:

// Outputs:
// 6
// 12
// 6
// 3
// 1
// 2 2
import "io";

def main() {
    let x = 5;

    io.printf("%d\n", x += 1);
    io.printf("%d\n", x *= 2);
    io.printf("%d\n", x /= 2);
    io.printf("%d\n", x -= 3);
    io.printf("%d\n", x %= 2);

    let y = x += 1;
    io.printf("%d %d\n", y, x);
}

test/runnable/string-i8-convert.kan:

// Outputs:
// tes
import "io";

def cut_end(s: string): *i8 {
    s[3] = '\0';
    return s;
}

def main() {
    let s: [5]i8 = "test";
    let s: string = &s[0];
    let s: *i8 = s;

    io.printf("%s\n", cut_end(s));
}

test/runnable/escape-seq.kan:

// Outputs:
// \\\
// 0
// abc
// 	t	t"
import "io";

def main(): void {
    // "\\"
    // "\\0"
    // "\\n"
    // "\\r"
    // "\\t"
    let n = "\0";
    io.printf("\\\\\\\n");
    io.printf("%d\n", *n);
    io.printf("abc\n");
    io.printf("\tt");
    io.printf("\tt\"\n");
}

test/runnable/fib.kan:

// Outputs:
// 144
import "io";

def fib(n: i32): i32 {
    if n <= 1 {
        return n;
    }

    return fib(n - 2) + fib(n - 1);
}

def main() {
    io.printf("%d\n", fib(12));
}

test/runnable/branchless.kan:

// Outputs:
// HELLO WORLD
import "io";

def to_upper(s: string, len: usize): string {
    for let i: usize = 0; i < len; i += 1 {
        let c = *(s + i);
        *(s + i) = c - 32 * ((c >= 'a' && c <= 'z') as i8);
    }
    return s;
}

def main() {
    let s: [12]i8 = "hello WORLD";
    io.printf("%s\n", to_upper(&s[0], 11));
}

test/runnable/param-assign.kan:

// Outputs:
// 42
// 2
import "io";

def f(i: i32): void {
    i = 42;
    io.printf("%d\n", i);
}

def main(): void {
    let i = 2;
    f(i);
    io.printf("%d\n", i);
}

test/runnable/return.kan:

// Outputs:

def main(argc: i32, argv: *string): i32 {
    if argc % 2 == 0 {
        return 0;
    } else {
        return 1;
    }
}

test/runnable/array-size.kan:

// Outputs:
// 8
// 24
// 16
// 96
// 48
import "io";

def main() {
    io.printf("%ld\n", sizeof *[3]*[4]**Struct);
    io.printf("%ld\n", sizeof [3]*[4]**Struct);
    io.printf("%ld\n", sizeof [2]*[4]**Struct);
    io.printf("%ld\n", sizeof [3][4]**Struct);
    io.printf("%ld\n", sizeof [3][4]Struct);
}

type Struct struct {
    i: i32
}

Clone this wiki locally