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/index.html | |
a
Diffstat (limited to 'src/web/index.html')
| -rw-r--r-- | src/web/index.html | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/web/index.html b/src/web/index.html new file mode 100644 index 0000000..4cf7476 --- /dev/null +++ b/src/web/index.html @@ -0,0 +1,60 @@ +<!doctype html> +<html lang="en"> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>zc in the browser</title> +<style> + :root { --bg: #fafaf7; --fg: #1d1d1b; --mute: #6b6b66; --line: #d9d9d2; --accent: #2f5d50; --box: #fff; } + @media (prefers-color-scheme: dark) { :root { --bg: #161614; --fg: #e8e8e2; --mute: #9a9a92; --line: #33332f; --accent: #7fb5a3; --box: #1d1d1a; } } + * { box-sizing: border-box; } + body { margin: 0; background: var(--bg); color: var(--fg); font: 15px/1.5 system-ui, sans-serif; } + main { max-width: 960px; margin: 0 auto; padding: 24px 16px 48px; } + h1 { font-size: 1.3rem; margin: 0 0 4px; } + p { color: var(--mute); margin: 0 0 16px; } + .bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; } + select, button { font: inherit; padding: 6px 12px; border: 1px solid var(--line); border-radius: 6px; background: var(--box); color: var(--fg); } + button { background: var(--accent); color: var(--bg); border-color: var(--accent); cursor: pointer; } + textarea, pre { width: 100%; font: 13px/1.45 ui-monospace, Menlo, Consolas, monospace; border: 1px solid var(--line); border-radius: 6px; background: var(--box); color: var(--fg); padding: 12px; margin: 0; tab-size: 4; } + textarea { height: 340px; resize: vertical; } + pre { min-height: 120px; white-space: pre-wrap; overflow-wrap: anywhere; margin-top: 12px; } + small { color: var(--mute); } +</style> +<main> + <h1>zc in the browser</h1> + <p>the microcore compiled to webassembly, with the whole compiler inside. the program below is compiled and run by it, the same as <code>zy < file.zc</code>.</p> + <div class="bar"> + <select id="ex"></select> + <button id="run">run</button> + <small id="status">loading</small> + </div> + <textarea id="src" spellcheck="false">fn main() { + put_s("hello from the browser\n"); + return 0; +} +</textarea> + <pre id="out" aria-live="polite"></pre> +</main> +<script src="zc.js"></script> +<script> + const $ = id => document.getElementById(id); + const examples = ['hello', 'fact', 'primes', 'mandel', 'lists', 'typed', 'lang', 'struct_closure_opt', 'opt_test']; + let machine = null; + for (const n of examples) { const o = document.createElement('option'); o.value = n; o.textContent = n + '.zc'; $('ex').appendChild(o); } + $('ex').onchange = async () => { + try { $('src').value = await (await fetch('../examples/' + $('ex').value + '.zc')).text(); } + catch (e) { $('out').textContent = 'the examples folder is not served next to this page'; } + }; + $('run').onclick = async () => { + if (!machine) return; + $('status').textContent = 'running'; + const t = performance.now(); + try { + const r = await machine.run($('src').value); + $('out').textContent = r.output + (r.messages ? '\n' + r.messages : ''); + $('status').textContent = 'done in ' + Math.round(performance.now() - t) + ' ms'; + } catch (e) { $('out').textContent = String(e); $('status').textContent = 'failed'; } + }; + ZC.load('zc.wasm').then(m => { machine = m; $('status').textContent = 'ready'; }) + .catch(e => { $('status').textContent = 'could not load zc.wasm; run src/web/build.sh and serve this folder over http'; }); +</script> +</html> |
