Examples

These are real design-target examples. The syntax is settled — the compiler is catching up.

Hello World

tape
@profile(t1);
import io from "io";

pub fn main() -> i32 {
    io.println("Hello, world!");
    return 0;
}
bash
tape run hello.tape
tape build hello.tape -o hello

Variables and Types

tape
@profile(t1);
import io from "io";

pub fn main() -> i32 {
    let x: i64 = 42;
    var y: i64 = 0;
    y = y + x;
    io.print_i64(y);
    io.print("\n");
    return 0;
}

Control Flow

tape
@profile(t1);
import io from "io";

pub fn main() -> i32 {
    var x: i64 = 10;
    if (x > 5) {
        io.println("big");
    } else {
        io.println("small");
    }
    return 0;
}
tape
@profile(t1);
import io from "io";

pub fn main() -> i32 {
    var sum: i64 = 0;
    for (i in 0..5) {
        sum = sum + i;
    }
    io.print_i64(sum);
    io.print("\n");
    return 0;
}

Functions

tape
@profile(t1);
import io from "io";

fn add(a: i64, b: i64) -> i64 {
    return a + b;
}

pub fn main() -> i32 {
    io.print_i64(add(20, 22));
    io.print("\n");
    return 0;
}

Structs

tape
@profile(t1);
import io from "io";

struct Point {
    x: i64;
    y: i64;
}

pub fn main() -> i32 {
    var p: Point = Point { x: 10; y: 20; };
    io.print_i64(p.x + p.y);
    io.print("\n");
    return 0;
}

Enums

tape
@profile(t1);
import io from "io";

enum Direction : u8 {
    North = 0;
    South = 1;
    East = 2;
    West = 3;
}

pub fn main() -> i32 {
    var d: Direction = Direction.North;
    if (d == Direction.North) {
        io.println("going north");
    }
    return 0;
}

Error Handling

tape
@profile(t1);
import io from "io";

enum ParseErr : u8 {
    BadInput = 1;
    Overflow = 2;
}

fn parse_positive(val: i64) -> i64 or ParseErr {
    if (val < 0) { return ParseErr.BadInput; }
    if (val > 1000000) { return ParseErr.Overflow; }
    return val * 2;
}

fn process(val: i64) -> i64 or ParseErr {
    var doubled: i64 = parse_positive(val) or return;
    return doubled + 1;
}

pub fn main() -> i32 {
    var result: i64 = process(21) or return 1;
    io.print_i64(result);
    io.print("\n");
    return 0;
}

Components

tape
@profile(t2);

import io from "io";
import ui from "ui";
import str from "str";
import widgets from "widgets";

component Counter {
    var count: i64 = 0;
    var count_text: *u8 = "0";

    fn increment() {
        count = count + 1;
        count_text = str.i64_to_cstr(count);
    }

    fn decrement() {
        count = count - 1;
        count_text = str.i64_to_cstr(count);
    }

    view {
        ui.Column {
            widgets.Label { text: count_text; fg: #333333; size: 24; }
            ui.Row {
                widgets.Button { label: "+"; on_click: increment; }
                widgets.Button { label: "-"; on_click: decrement; }
            }
        }
    }
}

pub fn main() -> i32 {
    let app = Counter {};
    ui.run(app as *u8, 400, 200, "Counter");
    return 0;
}

Defer

tape
@profile(t1);
import io from "io";
import mem from "mem";

fn process() -> i32 {
    var buf: *u8 = mem.alloc(1024 as u64);
    if (buf as i64 == 0) { return 1; }
    defer mem.free(buf, 1024 as u64);

    *buf = 42 as u8;
    io.print("allocated, used, and auto-freed\n");
    return 0;
}

pub fn main() -> i32 {
    var rc: i32 = process();
    io.print("done\n");
    return rc;
}

Tagged Unions

tape
@profile(t1);
import io from "io";

tagged Shape {
    Circle { radius: i64; }
    Rect { width: i64; height: i64; }
}

pub fn main() -> i32 {
    var s: Shape = Shape.Circle { radius: 5; };
    match (s) {
        Shape.Circle { radius } => {
            io.print("circle r=");
            io.print_i64(radius);
            io.print("\n");
        }
        Shape.Rect { width; height } => {
            io.print("rect ");
            io.print_i64(width * height);
            io.print("\n");
        }
    }
    return 0;
}

Last modified: