Oberon-0 Example¶
This example builds a simple WebAssembly module that reads two integers, adds them, and prints the result.
examples/example_oberon_0.py¶
# SPDX-FileCopyrightText: 2026 Jacques Supcik <jacques.supcik@hefr.ch>
#
# SPDX-License-Identifier: MIT
"""
This is an example of how to use the WASM Generator to generate a simple
WebAssembly module that adds two numbers and prints the result. The
generated module imports some functions from the host environment (e.g.,
for reading input and writing output) and defines a function that
performs the addition and prints the result.
"""
from wasm_gen import (
BaseFunction,
BaseGlobal,
BaseMemory,
Export,
Function,
FunctionType,
GlobalType,
Import,
MemoryType,
Module,
)
from wasm_gen import instructions as I # noqa
from wasm_gen.type import i32_t
m = Module()
open_input = BaseFunction(type=FunctionType(params=[], results=[]))
read_int = BaseFunction(type=FunctionType(params=[i32_t], results=[]))
eot = BaseFunction(type=FunctionType(params=[], results=[i32_t]))
write_char = BaseFunction(type=FunctionType(params=[i32_t], results=[]))
write_int = BaseFunction(type=FunctionType(params=[i32_t, i32_t], results=[]))
write_ln = BaseFunction(type=FunctionType(params=[], results=[]))
m.imports.extend(
[
Import(node=open_input, module="sys", name="OpenInput"),
Import(node=read_int, module="sys", name="ReadInt"),
Import(node=eot, module="sys", name="eot"),
Import(node=write_char, module="sys", name="WriteChar"),
Import(node=write_int, module="sys", name="WriteInt"),
Import(node=write_ln, module="sys", name="WriteLn"),
]
)
m1 = BaseMemory(type=MemoryType(min_pages=1))
m.imports.append(Import(node=m1, module="env", name="memory"))
sp = BaseGlobal(type=GlobalType(type=i32_t, mutable=True))
m.imports.append(Import(node=sp, module="env", name="__stack_pointer"))
add = Function(type=FunctionType(params=[], results=[]))
# Substract 12 from the stack pointer
add.body.extend(
[
I.GlobalGet(global_=sp),
I.I32Const(value=12),
I.I32Sub(),
I.GlobalSet(global_=sp),
]
)
# Open the input stream
add.body.extend(
[
I.Call(function=open_input),
]
)
# Push the address of z (the result of the addition) onto the stack
add.body.extend(
[
I.GlobalGet(global_=sp),
I.I32Const(value=8),
I.I32Add(),
]
)
# Read x and y
add.body.extend(
[
I.GlobalGet(global_=sp),
I.I32Const(value=0),
I.I32Add(),
I.Call(function=read_int),
I.GlobalGet(global_=sp),
I.I32Const(value=4),
I.I32Add(),
I.Call(function=read_int),
]
)
# Do the addition of two numbers
add.body.extend(
[
I.GlobalGet(global_=sp),
I.I32Const(value=0),
I.I32Add(),
I.I32Load(),
I.GlobalGet(global_=sp),
I.I32Const(value=4),
I.I32Add(),
I.I32Load(),
I.I32Add(),
]
)
# Save the result of the addition in z
add.body.extend(
[
I.I32Store(),
]
)
# Write the result of the addition
add.body.extend(
[
I.GlobalGet(global_=sp),
I.I32Const(value=8),
I.I32Add(),
I.I32Load(),
I.I32Const(value=5),
I.Call(function=write_int),
I.Call(function=write_ln),
]
)
# Restore the stack pointer
add.body.extend(
[
I.GlobalGet(global_=sp),
I.I32Const(value=12),
I.I32Add(),
I.GlobalSet(global_=sp),
]
)
add.body.append(I.End())
m.funcs.append(add)
m.exports.extend(
[
Export(node=add, name="add"),
]
)
with open("add.wasm", "wb") as f:
f.write(bytes(m))