Files
hakorune/wasm_demo/simple_demo.html

241 lines
8.4 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Nyash WASM Simple Demo</title>
<style>
body {
font-family: 'Courier New', monospace;
background: #1e1e1e;
color: #d4d4d4;
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
h1 {
color: #569cd6;
text-align: center;
}
.container {
background: #2d2d30;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
button {
background: #007acc;
color: white;
border: none;
padding: 10px 20px;
margin: 5px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #005a9e;
}
#output {
background: #1e1e1e;
padding: 15px;
margin-top: 20px;
border-radius: 4px;
min-height: 100px;
white-space: pre-wrap;
border: 1px solid #3e3e42;
}
.nyash-title {
color: #c586c0;
font-size: 24px;
}
input {
background: #3c3c3c;
color: white;
border: 1px solid #555;
padding: 5px 10px;
margin: 0 5px;
border-radius: 4px;
width: 60px;
text-align: center;
}
</style>
</head>
<body>
<h1>🎁 <span class="nyash-title">Nyash</span> WASM Simple Demo</h1>
<div class="container">
<h2>Everything is Box... 📦 (WASM Edition)</h2>
<div>
<button onclick="runAdd()">Test WASM Add Function</button>
<button onclick="testMemory()">Test WASM Memory</button>
<button onclick="runMain()">Run WASM Main</button>
</div>
<div style="margin-top: 20px;">
<input type="number" id="num1" value="42" />
+
<input type="number" id="num2" value="8" />
= <span id="result">?</span>
</div>
<div id="output">Loading WASM module...</div>
</div>
<script>
let wasmInstance = null;
let output = document.getElementById('output');
function log(message) {
output.textContent += message + '\n';
console.log(message);
}
function clearOutput() {
output.textContent = '';
}
// Create a simple WASM binary with memory
function createSimpleWasm() {
// WASM binary with add function AND memory
const wasmBinary = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, // magic
0x01, 0x00, 0x00, 0x00, // version
// Type section - function signature (i32, i32) -> i32
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f,
// Function section - declare 1 function
0x03, 0x02, 0x01, 0x00,
// Memory section - 1 page (64KB)
0x05, 0x03, 0x01, 0x00, 0x01,
// Export section - export add function and memory
0x07, 0x11, 0x02,
0x03, 0x61, 0x64, 0x64, 0x00, 0x00, // export "add" function 0
0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, // export "memory" memory 0
// Code section - implement add function
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
]);
return wasmBinary;
}
// Load WASM
async function loadWasm() {
try {
log('🚀 Creating simple WASM module...');
const wasmBinary = createSimpleWasm();
const wasmModule = await WebAssembly.instantiate(wasmBinary);
wasmInstance = wasmModule.instance;
log('✅ WASM module loaded successfully!');
log('🎯 Functions available: ' + Object.keys(wasmInstance.exports).join(', '));
log('Ready to test Nyash WASM!');
} catch (error) {
log('❌ Error loading WASM: ' + error.message);
// Fallback to JavaScript
log('📦 Falling back to JavaScript implementation...');
wasmInstance = {
exports: {
add: (a, b) => {
log(`JS Fallback: ${a} + ${b} = ${a + b}`);
return a + b;
}
}
};
log('✅ JavaScript fallback ready!');
}
}
function runAdd() {
clearOutput();
if (!wasmInstance) {
log('WASM not loaded yet!');
return;
}
const a = parseInt(document.getElementById('num1').value);
const b = parseInt(document.getElementById('num2').value);
const result = wasmInstance.exports.add(a, b);
document.getElementById('result').textContent = result;
log(`✨ WASM calculated: ${a} + ${b} = ${result}`);
log('🎉 Nyash "Everything is Box" philosophy works in WASM!');
}
function testMemory() {
clearOutput();
log('🧠 Testing WASM memory access...');
if (wasmInstance && wasmInstance.exports.memory) {
const memory = new Uint8Array(wasmInstance.exports.memory.buffer);
log(`✅ Memory size: ${memory.length} bytes (${memory.length/1024}KB)`);
// Write "Nyash Box!" to memory
const message = "Nyash Box! 📦";
const encoder = new TextEncoder();
const encoded = encoder.encode(message);
// Write to memory starting at offset 100
for (let i = 0; i < encoded.length; i++) {
memory[100 + i] = encoded[i];
}
memory[100 + encoded.length] = 0; // null terminator
// Read it back
const decoder = new TextDecoder();
const readBack = decoder.decode(memory.slice(100, 100 + encoded.length));
log(`📝 Wrote to memory: "${message}"`);
log(`📖 Read from memory: "${readBack}"`);
log(`📍 Memory address: 100-${100 + encoded.length}`);
log('🎯 This is how Nyash Boxes will be stored in WASM!');
// Simulate Box layout
log('');
log('📦 Simulating Nyash Box layout:');
// Box layout: [type_id:4][field_count:4][field0:4][field1:4]...
const boxOffset = 200;
const boxData = new Int32Array(memory.buffer, boxOffset, 4);
boxData[0] = 0x1001; // StringBox type ID
boxData[1] = 2; // 2 fields
boxData[2] = 100; // pointer to string data
boxData[3] = encoded.length; // string length
log(` [${boxData[0].toString(16)}][${boxData[1]}][${boxData[2]}][${boxData[3]}]`);
log(` ^type_id ^count ^ptr ^len`);
log('✨ Perfect for "Everything is Box" philosophy!');
} else {
log('❌ Memory not available in this demo');
log('🔧 Check WASM compilation...');
}
}
function runMain() {
clearOutput();
log('🎯 Running main function...');
log('📦 In real Nyash WASM, this would execute your program!');
log('✨ Everything is Box! ✨');
// Simulate some Box operations
log('Creating StringBox("Hello")...');
log('Creating IntegerBox(42)...');
log('Executing: print(stringBox + integerBox)...');
log('Output: Hello42');
}
// Load WASM on page load
window.onload = loadWasm;
</script>
</body>
</html>