High-Level Language Examples
C
Here is an example of a simple freestanding C program which can be compiled into Glulx using clang and Wasm2Glulx, which will print "Hello, sailor!" and then exit.
#define NULL ((void*)0)
typedef unsigned int glui32;
typedef struct glk_window_struct *winid_t;
typedef struct glk_stream_struct *strid_t;
extern winid_t glk_window_open(winid_t split, glui32 method, glui32 size,
glui32 wintype, glui32 rock)
__attribute__((import_module("glk"), import_name("window_open")));
extern void glk_stream_set_current(strid_t str)
__attribute__((import_module("glk"), import_name("stream_set_current")));
extern void glk_put_string(const char *s)
__attribute__((import_module("glk"), import_name("put_string")));
extern strid_t glk_window_get_stream(winid_t win)
__attribute__((import_module("glk"), import_name("window_get_stream")));
#define wintype_TextBuffer 3
void glulx_main() {
winid_t root_window = glk_window_open(NULL, 0, 0, wintype_TextBuffer, 0);
glk_stream_set_current(glk_window_get_stream(root_window));
glk_put_string("Hello, sailor!\n");
}
This can be compiled by running
clang --target=wasm32-unknown-unknown -ffreestanding -nostdinc -nostdlib \
-Wl,--no-entry -Wl,--import-undefined -Wl,--export,glulx_main \
-o hello_sailor.wasm hello_sailor.c
wasm2glulx hello_sailor.wasm
and the resulting hello_sailor.ulx
will run in any Glulx interpreter.
Rust
A similar program in Rust:
#![no_std]
#![no_main]
use core::ffi::{c_char, c_void, CStr};
use core::panic::PanicInfo;
#[derive(Copy, Clone)]
#[repr(transparent)]
struct Strid(*const c_void);
#[derive(Copy, Clone)]
#[repr(transparent)]
struct Winid(*const c_void);
const WINTYPE_TEXT_BUFFER: u32 = 3;
#[link(wasm_import_module = "glk")]
extern "C" {
#[link_name = "exit"]
fn glk_exit() -> !;
#[link_name = "window_open"]
fn glk_window_open(
split: Winid,
method: u32,
size: u32,
wintype: u32,
rock: u32
) -> Winid;
#[link_name = "stream_set_current"]
fn glk_stream_set_current(stream: Strid);
#[link_name = "put_string"]
fn glk_put_string(s: *const c_char);
#[link_name = "window_get_stream"]
fn glk_window_get_stream(window: Winid) -> Strid;
}
#[panic_handler]
fn panic(_: &PanicInfo) -> ! {
unsafe {
glk_exit();
}
}
#[no_mangle]
extern "C" fn glulx_main() {
unsafe {
let root_window = glk_window_open(
Winid(core::ptr::null()),
0,
0,
WINTYPE_TEXT_BUFFER,
0);
glk_stream_set_current(glk_window_get_stream(root_window));
glk_put_string(
CStr::from_bytes_with_nul(b"Hello, sailor!\n\0")
.unwrap()
.as_ptr(),
);
}
}
This can be compiled by running
rustc --target=wasm32-unknown-unknown -o hello_sailor.wasm hello_sailor.rs
wasm2glulx hello_sailor.wasm