// examples
What tape code looks like
These are real design-target examples. The syntax is settled — the compiler is catching up.
hello world
hello.tape@profile(t1); import io from "io"; pub fn main() -> i32 { io.println("Hello, world!"); return 0; }
$ tape run hello.tape · $ tape build hello.tape -o hello
error handling
math.tape@profile(t1); import io from "io"; enum MathError : u8 { DivByZero = 1: "division by zero"; } fn divide(a: i64, b: i64) -> i64 or MathError { if (b == 0) { return MathError.DivByZero; } return a / b; } pub fn main() -> i32 { let result: i64 = divide(10, 0) or { io.println(MathError.desc(err)); return 1; }; io.print_i64(result); return 0; }
compile-time code generation
collections.tapeimport mem from "mem"; @tape fn gen_vec(T: type) { var elem_sz: i64 = @sizeof(T); @emit const VEC_${T}_SZ: i64 = elem_sz; @emit struct Vec_${T} { data: *${T}; len: i64; cap: i64; } @emit fn vec_${T}_new() -> Vec_${T} { var v: Vec_${T} = Vec_${T} { data: 0 as *${T}, len: 0, cap: 0 }; return v; } @emit fn vec_${T}_push(v: *Vec_${T}, item: ${T}) { if (v.len == v.cap) { var new_cap: i64 = 8; if (v.cap > 0) { new_cap = v.cap * 2; } var buf: *u8 = mem.alloc((new_cap * VEC_${T}_SZ) as u64); if (v.len > 0) { mem.copy(buf, v.data as *u8, (v.len * VEC_${T}_SZ) as u64); mem.free(v.data as *u8, (v.cap * VEC_${T}_SZ) as u64); } v.data = buf as *${T}; v.cap = new_cap; } var dst: *${T} = (v.data as i64 + v.len * VEC_${T}_SZ) as *${T}; *dst = item; v.len = v.len + 1; } } @tape { gen_vec(i64); } @tape { gen_vec(string); }
components with events
todo.tape@profile(t2); import ui from "ui"; import widgets from "widgets"; component TodoItem { prop index: i64; prop text: string = ""; event on_delete(index: i64); fn handle_click() { fire on_delete(index); } view { ui.Row { widgets.Label { text: text; fg: #333333; } widgets.Button { label: "x"; on_click: handle_click; } } } } component App { fn delete_item(index: i64) {} view { ui.Column { TodoItem { text: "Buy milk"; index: 0; on_delete: delete_item; } TodoItem { text: "Write code"; index: 1; on_delete: delete_item; } } } } pub fn main() -> i32 { let app = App {}; ui.run(app as *u8, 400, 300, "Todo"); return 0; }
C interop
sdl.tape@profile(t1); @link("SDL2"); struct Window { handle: i64, } extern fn SDL_Init(flags: u32) -> i32; extern fn SDL_CreateWindow( title: *u8, x: i32, y: i32, w: i32, h: i32, flags: u32 ) -> i64; pub fn create(title: *u8, w: i32, h: i32) -> Window { SDL_Init(0x20 as u32); let h: i64 = SDL_CreateWindow(title, 0 as i32, 0 as i32, w, h, 0 as u32); return Window { handle: h }; } @export pub fn plugin_init() -> i32 { // callable from C return 0; }