This repository contains source code for Riff's standalone online playground. The playground is 100% client-side, using a special Riff interpreter compiled to WebAssembly to execute Riff programs directly in the browser.
To run the playground locally, you'll need to to spin up a local web
server to serve index.html
. Otherwise, the Riff interpreter
(WebAssembly module) cannot be invoked via the file://
protocol.
Start a local server on port 8000 using Python:
$ python3 -m http.server 8000
You can then open localhost:8000
in a new browser tab/window.
Emscripten is used to compile the Riff interpreter to WebAssembly. Emscripten is used since it takes care of linking any required headers/libraries to the WASM module.
The following command is used to compile the C source code:
$ emcc -O3 *.c -s EXPORTED_FUNCTIONS='["_wasm_main"]' -s EXPORTED_RUNTIME_METHODS='["ccall"]' -o riff.js
Emscripten outputs a JavaScript file along with the WASM module, which is used to drive the WASM module.
wasm_main()
is a special entry
point
which simply skips any command-line argument parsing. Note that this
was done to simplify invocation from JavaScript and isn't really
necessary.
The Riff interpreter is invoked via JavaScript via Emscripten's
provided Module
interface:
// Grab the input program from the CodeMirror "input" area
var inputProgram = cmInput.getValue();
// Invoke Riff with the input program
// 0 = Disassemble
// 1 = Execute
Module.ccall('wasm_main', 'number', ['number', 'string'], [1, inputProgram]);
Printing to stdout
and stderr
is defined through Emscripten's
Module
object. In this example, both stdout
and stderr
are
appended to an HTML <textarea>
with the ID #output
:
var Module = {
// stdout
print: function(text) {
console.log(text);
document.getElementById('output').value += text + "\n";
},
// stderr
printErr: function(text) {
console.error(text);
document.getElementById('output').value += text + "\n";
},
};