bf-vm
v1.0.0
Published
A WebAssembly-based lightweight Brainfuck VM for Node.js
Maintainers
Readme
Brainfuck VM (Wasm Powered)
A high-performance Brainfuck interpreter for Node.js, leveraging the speed of C compiled to WebAssembly (Wasm). Execute Brainfuck code efficiently with customizable memory limits and get performance metrics.
Features
- 🚀 Fast Execution: Core interpreter written in C and compiled to Wasm for near-native speed.
- 🔧 Customizable Memory: Set the Brainfuck memory tape size per execution.
- 📊 Performance Metrics: Get execution duration and basic Wasm heap stats.
- 📦 Simple API: Easy-to-use asynchronous
executefunction. - ⚡ Lightweight: Minimal dependencies.
Installation
npm install bf-vm
# or
yarn add bf-vm(Make sure you have a C compiler compatible with Emscripten, like GCC or Clang, and the Emscripten SDK installed if you intend to build from source. The pre-compiled Wasm module should work out-of-the-box for standard Node.js environments.)
Usage
The primary way to use the VM is through the execute function.
const { execute, DEFAULT_MEMORY_SIZE } = require('bf-vm');
// Example 1: Hello World!
const helloWorldCode = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
async function runHelloWorld() {
console.log("Running Hello World...");
try {
const result = await execute(helloWorldCode);
console.log("Output:", result.output); // Output: Hello World!
console.log(`Execution Time: ${result.duration.toFixed(3)} ms`);
console.log(`Wasm Heap: ${result.memoryStats.wasmHeapBefore} -> ${result.memoryStats.wasmHeapAfter} bytes`);
} catch (error) {
console.error("VM Error:", error.message);
}
}
runHelloWorld();
// Example 2: Echo input with custom memory
const echoCode = "+[,.]";
const inputString = "Testing 123";
async function runEcho() {
console.log("\nRunning Echo Test...");
try {
const result = await execute(
echoCode, // Code to execute
inputString, // Input string for ',' command
{ // Options object
memorySize: 5000, // Use a smaller tape size
// maxOutputSize: 1024 // Optionally limit output buffer
}
);
console.log(`Input: "${inputString}"`);
console.log(`Output: "${result.output}"`); // Output: Testing 123
console.log(`Execution Time: ${result.duration.toFixed(3)} ms`);
console.log(`Options Used: memorySize=5000`);
} catch (error) {
console.error("VM Error:", error.message);
}
}
runEcho();
// Example 3: Handling Errors
const badCode = "+++[>++"; // Unmatched bracket
async function runErrorTest() {
console.log("\nRunning Error Test...");
try {
await execute(badCode);
} catch (error) {
// Catches errors from the VM (syntax, runtime) or initialization
console.error("Caught Expected Error:", error.message);
// Expected: Brainfuck VM Error: Syntax Error: Unmatched opening bracket '['. (Code: -5)
}
}
runErrorTest();
API Reference
execute(code, [input], [options])
Executes the given Brainfuck code asynchronously.
code:string(Required) - The Brainfuck source code to execute.input:string(Optional) - The input string provided to the Brainfuck program via the,command. Each character is read sequentially. If input runs out,,reads a null byte (0). Defaults to"".options:object(Optional) - Configuration for the execution.memorySize:number- The size of the Brainfuck memory tape (number of cells/bytes). Defaults toDEFAULT_MEMORY_SIZE(30000). Must be positive.maxOutputSize:number- The maximum number of bytes allowed for the output buffer generated by the.command. Defaults toDEFAULT_MAX_OUTPUT_SIZE(65536). Must be positive.
Returns:
Promise<object>- A Promise that resolves to an object containing the execution results:output:string- The string output generated by the.command during execution.duration:number- The execution time of the core Wasm function call in milliseconds (measured usingperf_hooks).memoryStats:object- Basic stats about the Wasm linear memory heap size:wasmHeapBefore:number- Heap size in bytes before execution.wasmHeapAfter:number- Heap size in bytes after execution. (Note: This reflects the total heap, not just the BF tape allocation).
Throws:
Error- Rejects the promise if:- The Wasm module fails to initialize.
- Invalid options are provided (e.g.,
memorySize <= 0). - Wasm memory allocation for internal buffers fails.
- A runtime error occurs within the Brainfuck VM (e.g., memory out of bounds, unmatched brackets, output buffer overflow). Error messages are prefixed with
Brainfuck VM Error:.
Constants
DEFAULT_MEMORY_SIZE:number(30000) - The default memory tape size used ifoptions.memorySizeis not provided.DEFAULT_MAX_OUTPUT_SIZE:number(65536) - The default maximum output buffer size used ifoptions.maxOutputSizeis not provided.
You can import these if needed:
const { DEFAULT_MEMORY_SIZE, DEFAULT_MAX_OUTPUT_SIZE } = require('brainfuck-vm');
console.log("Default Tape Size:", DEFAULT_MEMORY_SIZE);License
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
