diff options
| author | 2026-10-12 08:46:23 +0330 | |
|---|---|---|
| committer | 2026-10-12 08:46:23 +0330 | |
| commit | ecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch) | |
| tree | 70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /src/web/zc.js | |
a
Diffstat (limited to 'src/web/zc.js')
| -rw-r--r-- | src/web/zc.js | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/web/zc.js b/src/web/zc.js new file mode 100644 index 0000000..4f14d3c --- /dev/null +++ b/src/web/zc.js @@ -0,0 +1,28 @@ +// runs zc in a browser or in node: the microcore compiled to webassembly, +// with the compiler genome inside. ZC.load(bytes) gives a machine, and +// machine.run(source) compiles and runs a program the way `zy < file.zc` does, +// returning what it printed. every run starts from a fresh instance. +(function (root) { + async function load(wasm) { + if (typeof wasm === 'string') wasm = await (await fetch(wasm)).arrayBuffer(); + const mod = await WebAssembly.compile(wasm); + return { + async run(source) { + let out = [], msg = [], mem; + const inst = await WebAssembly.instantiate(mod, { + env: { js_putc: c => { out.push(c); }, js_msg: c => { msg.push(c); } } + }); + const x = inst.exports; + const bytes = new TextEncoder().encode(source); + if (bytes.length > x.wasm_input_cap()) throw new Error('program too long for the input buffer'); + new Uint8Array(x.memory.buffer).set(bytes, x.wasm_input()); + x.wasm_set_input(bytes.length); + const status = x.wasm_run(); + const dec = new TextDecoder(); + return { output: dec.decode(new Uint8Array(out)), messages: dec.decode(new Uint8Array(msg)), status }; + } + }; + } + const ZC = { load }; + if (typeof module !== 'undefined' && module.exports) module.exports = ZC; else root.ZC = ZC; +})(typeof self !== 'undefined' ? self : this); |
