feat: add fullscreen TUI and project updates
- New TUI screens: Main Menu, Compile, Run, REPL, AI Generator, AI Settings, Help - AI configuration persisted in ~/.config/cljnim/config.json - Added illwill dependency for terminal UI - Updated experiments, examples, docs, and core modules
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
# Clojure/Nim → WASM (via Emscripten)
|
||||
|
||||
Compile Clojure code to WebAssembly using Nim's Emscripten backend.
|
||||
|
||||
## Why?
|
||||
|
||||
- **Native speed in browser** — no JS interpreter overhead
|
||||
- **Smaller than JVM** — WASM module is ~100KB vs 50MB+ JVM
|
||||
- **Secure sandbox** — WASM runs in browser's security model
|
||||
|
||||
## Requirements
|
||||
|
||||
```bash
|
||||
git clone https://github.com/emscripten-core/emsdk.git
|
||||
cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
source ./emsdk_env.sh
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
Then open `www/index.html` in a browser.
|
||||
|
||||
## How it works
|
||||
|
||||
1. `cljnim compile-lib` — generates Nim with exported functions
|
||||
2. `nim c -d:emscripten` — compiles Nim to WASM + JS glue
|
||||
3. Browser loads `math.js` (glue) + `math.wasm` (WASM module)
|
||||
4. JS calls `_wasmSquare(7)` → WASM executes native Clojure code
|
||||
|
||||
## Future
|
||||
|
||||
- WASI target (server-side WASM)
|
||||
- wasm32-wasi-musl via Zig (no Emscripten needed)
|
||||
- DOM interop through Emscripten bindings
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CLJNIM="${SCRIPT_DIR}/../../cljnim"
|
||||
LIB_PATH="${SCRIPT_DIR}/../../lib"
|
||||
|
||||
mkdir -p "${SCRIPT_DIR}/build"
|
||||
|
||||
echo "=== Step 1: Clojure → Nim ==="
|
||||
"$CLJNIM" compile-lib \
|
||||
"${SCRIPT_DIR}/examples/math.clj" \
|
||||
"${SCRIPT_DIR}/build/math.nim"
|
||||
|
||||
echo "=== Step 2: Nim → WASM (via Emscripten) ==="
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
if ! command -v emcc &> /dev/null; then
|
||||
echo "ERROR: Emscripten not found."
|
||||
echo "Install: git clone https://github.com/emscripten-core/emsdk.git"
|
||||
echo " ./emsdk install latest && ./emsdk activate latest"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
emcc nim c --cc:clang \
|
||||
--path:"$LIB_PATH" \
|
||||
-d:emscripten -d:release \
|
||||
--noMain \
|
||||
-o:"build/math.js" \
|
||||
"wasm_wrappers.nim"
|
||||
|
||||
echo "=== Step 3: Generated files ==="
|
||||
ls -la "${SCRIPT_DIR}/build/"
|
||||
echo ""
|
||||
echo "Open ${SCRIPT_DIR}/www/index.html in a browser to test"
|
||||
@@ -0,0 +1,9 @@
|
||||
(ns math)
|
||||
|
||||
(defn square [x]
|
||||
(* x x))
|
||||
|
||||
(defn factorial [n]
|
||||
(if (= n 0)
|
||||
1
|
||||
(* n (factorial (- n 1)))))
|
||||
@@ -0,0 +1,14 @@
|
||||
# WASM-friendly wrappers around Clojure-generated code
|
||||
# Uses Emscripten FFI: cint → JS number, cstring → JS string
|
||||
|
||||
import cljnim_runtime
|
||||
|
||||
include build/math
|
||||
|
||||
proc wasmSquare*(x: cint): cint {.exportc.} =
|
||||
let r = square(cljInt(x.int64))
|
||||
return r.intVal.cint
|
||||
|
||||
proc wasmFactorial*(n: cint): cint {.exportc.} =
|
||||
let r = factorial(cljInt(n.int64))
|
||||
return r.intVal.cint
|
||||
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Clojure/Nim → WASM Demo</title>
|
||||
<style>
|
||||
body { font-family: monospace; max-width: 800px; margin: 40px auto; padding: 20px; background: #1a1a2e; color: #eee; }
|
||||
h1 { color: #e94560; }
|
||||
.result { background: #16213e; padding: 15px; margin: 10px 0; border-radius: 5px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>⚡ Clojure/Nim → WASM (Emscripten)</h1>
|
||||
<p>Clojure compiled to Nim, then to WebAssembly via Emscripten.</p>
|
||||
|
||||
<div class="result">
|
||||
<div id="output">Loading WASM module...</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var Module = {
|
||||
onRuntimeInitialized: function() {
|
||||
const out = document.getElementById('output');
|
||||
out.innerHTML = `
|
||||
<b>wasmSquare(7)</b> = ${Module._wasmSquare(7)}<br>
|
||||
<b>wasmFactorial(5)</b> = ${Module._wasmFactorial(5)}<br>
|
||||
<br>
|
||||
<i>Clojure running at native speed in your browser!</i>
|
||||
`;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="../build/math.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user