Directives
Directives are compiler attributes that declare runtime functions. They appear at the top of a file, before any machine.
§@rt — runtime function
@rt(name) binds a name to a built-in runtime function. After the directive, name is callable from any branch. Runtime calls are inlined — they execute synchronously in the current process and do not consume reductions on their own.
@rt(rt_write)
@rt(rt_exit)Each runtime function gets its own @rt(...).
§Available runtime functions
These are wired in the current native compiler. Others may be parsed but will not produce useful behaviour at link time.
| Function | Arguments | Behaviour |
|---|---|---|
rt_write | fd str size | write(fd, ptr, size) — direct syscall, no buffering |
rt_read | fd buf size | read(fd, ptr, size) |
rt_allocate | size | allocate size bytes on the heap, returns a fat pointer |
rt_exit | code | terminate the process with status code |
rt_mmap | addr size prot flags fd off | raw mmap syscall |
rt_write takes the size in bytes, not characters or codepoints. "hello\n" is six bytes; "привет" is twelve.
§Writing to stdout
@rt(rt_write)
main is {
_ -> {
rt_write(1 "hello, lake!\n" 13)
}
}The first argument is a file descriptor (1 is stdout, 2 is stderr).
§Exiting with a status
@rt(rt_write)
@rt(rt_exit)
main is {
_ -> {
rt_write(1 "bye\n" 4)
rt_exit(7)
}
}The wrapping _start would normally exit with 0. rt_exit overrides this, so the OS sees the value you pass.
§Allocating a buffer
@rt(rt_write)
@rt(rt_allocate)
main is {
_ -> {
let buf i64 = rt_allocate(64)
rt_write(1 "allocated 64 bytes\n" 19)
}
}rt_allocate takes a size in bytes and returns a fat pointer to a fresh region of heap memory. Use rt_store and rt_load_u64 to read and write into it.
§Placement
Directives precede any machine:
@rt(rt_write)
main is {
_ -> {
rt_write(1 "ok\n" 3)
}
}Empty lines between directives and the first machine are optional but conventional.