The bootstrap.
Here's the moment everything has been building toward. Four commands:
# Step 1: Compile the compiler with our Zig implementation
zig build-exe minizig.zig && ./minizig < compiler.lang > compiler.wat
# Step 2: Assemble to WASM
wat2wasm compiler.wat -o compiler.wasm
# Step 3: Run the WASM compiler on its own source
node run.js compiler.wasm < compiler.lang > compiler2.wat
# Step 4: Compare
diff compiler.wat compiler2.wat
run.js is a small Node.js script that loads the WASM module with I/O imports:
const fs = require('fs');
const wasm = fs.readFileSync(process.argv[2]);
const input = fs.readFileSync('/dev/stdin');
WebAssembly.instantiate(wasm, {
env: {
read_input: () => {
for (let i = 0; i < input.length; i++)
mem[i] = input[i];
return input.length;
},
print_char: (c) => process.stdout.write(Buffer.from([Number(c)])),
}
}).then(({ instance }) => {
mem = new Uint8Array(instance.exports.memory.buffer);
instance.exports.main();
});