A standalone build (no Emscripten JS runtime, no libc/WASI) lives at docs/standalone.html.
Counter: 0
Application logic: R0 → WebAssembly
Browser plumbing: JavaScript
This application logic is R0 running inside WebAssembly. JavaScript only forwards browser events and performs the requested DOM update.
counter: 0
on-click: [
counter: + counter 1
web-set-int 1 counter
]
RAW is R0’s trapdoor to the tiny Forth-like S1 substrate. Application code normally stays above this layer.
web-set-int: raw 2 [
LIT 16 DIV
>R
LIT 16 DIV
LIT 1000000 MUL
R> ADD
PRINT
ARITY 0 EXIT
]
This glue contains no counter state or increment logic; it only forwards clicks and performs the DOM update R0 requests.
/* web/glue.js -- the JavaScript half of the browser boundary.
*
* JavaScript responsibilities only:
* - capture the host's standard output (the WEB_SET_INT transport);
* - decode handle/value and update the mapped DOM element;
* - forward button clicks to the exported WASM entry `r0_click`.
*
* No counter state or application logic lives here.
*/
/* handle -> DOM element id (numeric DOM handle 1 = the counter display) */
var R0_DOM_HANDLES = { 1: 'counter' };
Module.print = function (line) {
var s = String(line).replace(/^\s+|\s+$/g, '');
if (s === '') return;
var n = parseInt(s, 10);
if (!isNaN(n) && n >= 1000000) {
var handle = Math.floor(n / 1000000);
var value = n % 1000000;
var elId = R0_DOM_HANDLES[handle];
if (elId) {
var el = document.getElementById(elId);
if (el) el.textContent = String(value);
}
} else {
console.log('[R0]', s); /* plain R0 output (e.g. the ready line) */
}
};
Module.printErr = function (line) {
console.log('[R0:err]', line);
};
Module.onRuntimeInitialized = function () {
var btn = document.getElementById('increment');
btn.addEventListener('click', function () {
Module._r0_click();
});
};