rollinn
v1.0.4
Published
An advanced JavaScript engine inspired by V8 featuring lexer, parser, interpreter, bytecode compiler, and garbage collector
Maintainers
Readme
Rollinn JS Engine ~ by Divyanshu Gupta⚡
An advanced JavaScript engine built from scratch, inspired by Google V8. This engine implements the complete pipeline from source code to execution, featuring a lexer, parser, bytecode compiler, interpreter, and garbage collector.
🏗️ Architecture
Source Code -> Lexer -> Parser -> AST -> Bytecode Compiler -> Interpreter
|
Garbage CollectorEngine Pipeline
| Stage | Component | Description | |---|---|---| | 1 | Lexer | Tokenizes JavaScript source into a stream of tokens | | 2 | Parser | Recursive descent parser producing an Abstract Syntax Tree | | 3 | Bytecode Compiler | Compiles AST to flat bytecode (V8 Ignition simulation) | | 4 | Interpreter | Tree-walking evaluator with closures and scope chains | | 5 | Garbage Collector | Mark-and-sweep with generational collection |
🚀 Features
Language Support
- ✅ Variables (
var,let,constwith proper scoping) - ✅ Functions (declarations, expressions, arrows, default params, rest params)
- ✅ Classes (constructors, methods, inheritance with
extends/super) - ✅ Control Flow (
if/else,for,while,do-while,switch,break,continue) - ✅ Error Handling (
try/catch/finally,throw) - ✅ All Operators (arithmetic, comparison, logical, bitwise, assignment, ternary)
- ✅ Arrays (with built-in methods: map, filter, reduce, forEach, find, sort, etc.)
- ✅ Objects (properties, methods, computed keys, shorthand, spread)
- ✅ String Methods (30+ methods including split, slice, replace, etc.)
- ✅ Closures & Lexical Scoping
- ✅ Template Literals
- ✅ Destructuring-ready architecture
- ✅ Optional Chaining (
?.) - ✅ Nullish Coalescing (
??) - ✅ Spread/Rest operator (
...) - ✅ Async/Await (
asyncfunctions +await)
Built-in Globals
console.log/error/warn/info/time/timeEndpromptMath(30+ methods and constants)Array(isArray, from, at, flatMap, reduceRight, findLast, findLastIndex)Object(keys, values, entries, fromEntries, hasOwn, assign, freeze)Map(get, set, has, delete, clear, keys, values, entries, forEach, size)Set(add, has, delete, clear, values, entries, forEach, size)RegExp(constructor)JSON(parse, stringify)Date.now()parseInt,parseFloat,isNaN,isFinite
Engine Features
- 📊 Pipeline performance metrics at each stage
- 🔍 Token stream inspector
- 🌳 AST visualization
- ⚙️ Bytecode disassembly (V8 Ignition-style)
- 🗑️ Garbage collector with heap visualization
- 🛡️ Infinite loop protection
- 📚 Call stack tracking with max depth limit
📦 Installation
# No external dependencies needed!
cd "JS engine"🎮 Usage
Run Anywhere (Browser or Node Server)
You can use the engine outside the repo with any static server or Node server. Just build once and serve rollinn.js.
npm run buildServe from any folder (examples):
# Any static server (Node)
npx http-server . -p 3000
# Or your own Node/Express server
# Just host rollinn.js and your HTML pageThen include it:
<script src="rollinn.js"></script>
<script>
const engine = new Rollinn.RollinnEngine();
engine.run('console.log("Hello from anywhere");');
</script>Parallel Execution (Optional Workers)
By default the engine runs single-threaded. If you want true parallel execution, use workers.
Node (worker_threads):
import { runInNodeWorker, executeInNodeWorker } from 'rollinn/parallel-node';
const [a, b] = await Promise.all([
runInNodeWorker('console.log(\"A\")'),
executeInNodeWorker('console.log(\"B\")')
]);Browser (Web Workers):
import { runInBrowserWorker } from 'rollinn/parallel-browser';
const result = await runInBrowserWorker('console.log(\"Hello worker\")', {
engineUrl: 'rollinn.js' // path to the UMD bundle
});Node Server Example (No Framework)
// server.js
import http from 'node:http';
import { readFileSync } from 'node:fs';
const indexHtml = readFileSync('./index.html');
const bundle = readFileSync('./rollinn.js');
http.createServer((req, res) => {
if (req.url === '/rollinn.js') {
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.end(bundle);
return;
}
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(indexHtml);
}).listen(3000);Express Server Example
// server.js
import express from 'express';
const app = express();
app.use(express.static('.'));
app.listen(3000);📦 Use As A Package
This published package includes only the execution engine (no playground/editor files).
Node / ESM
npm i rollinnimport { RollinnEngine } from 'rollinn';
const engine = new RollinnEngine();
const output = await engine.execute('console.log("Hello");');
console.log(output);
// Same method also works for async/await
const asyncOutput = await engine.execute('const v = await Promise.resolve(42); console.log(v);');
console.log(asyncOutput);Advanced (full result object):
const result = engine.run('console.log("Hello");');
console.log(result.output.map(o => o.text).join('\n'));Browser (Offline Bundle)
npm run build<script src="rollinn.js"></script>
<script>
const engine = new Rollinn.RollinnEngine();
engine.execute('const v = await Promise.resolve("Hello from Rollinn"); console.log(v);')
.then((out) => console.log(out))
.catch((err) => console.error(err));
</script>Option A: Plug-and-Play Single File
Use rollinn.js for a single-file drop-in bundle. It exposes Rollinn on window, and all engine methods are available (same API as Node/ESM).
🔧 Engine API (Use Methods To Access Data)
new RollinnEngine(options)— Create an engine instance.engine.run(source)— Auto-detects async/await. Returns{ success, result, output, error, pipeline }or a Promise of it.engine.runAsync(source)— Explicit async version ofrun(always returns a Promise).engine.execute(source)— Auto-detects async/await. Returns output string or a Promise of it.engine.executeAsync(source)— Explicit async version ofexecute(always returns a Promise).
Methods With Syntax
// Create engine
const engine = new RollinnEngine({
autoReset: true, // reset after every run (recommended for server isolation)
autoResetKeepLastResult: true, // keep tokens/AST/bytecode for last run
});
// Full result object
const result = await engine.run('console.log("Hi")');
console.log(result.success, result.output);
// Output only (string)
const output = await engine.execute('console.log("Hi")');
console.log(output);
// Tokens / AST / Bytecode
const tokens = engine.tokenize('let x = 1;');
const ast = engine.parse('let x = 1;');
const bytecode = engine.compile('let x = 1;');
const disasm = engine.disassemble('let x = 1;');
// Get last pipeline data
engine.getTokens();
engine.getAST();
engine.getBytecode();
engine.getGCStats();
engine.getOutput();
// Reset engine state
engine.reset();engine.reset()— Reset engine state.engine.tokenize(source)— Return tokens for a source string.engine.parse(source)— Return AST for a source string.engine.compile(source)— Return bytecode for a source string.engine.disassemble(source)— Return bytecode disassembly.engine.getTokens()— Get last token stream.engine.getAST()— Get last AST.engine.getBytecode()— Get last bytecode.engine.getGCStats()— Get garbage collector stats.engine.getOutput()— Get last console output array.options.autoReset— Iftrue, engine resets automatically after each run. Recommended for multi-user servers.options.autoResetKeepLastResult— Iftrue, keep last result/pipeline after auto-reset (sogetTokens()/getAST()still work).
Example: Use Any Editor
const code = editor.getValue(); // from your editor
const result = engine.run(code);
renderOutput(result.output); // show output in your UI🧪 Running Tests
node tests/run.js🔧 How It Works (V8 Comparison)
| V8 Component | Rollinn Equivalent |
|---|---|
| Scanner | lexer.js — Full JS lexical grammar |
| Parser | parser.js — Recursive descent with Pratt precedence |
| Ignition (Bytecode) | compiler.js — Bytecode compilation pipeline |
| Interpreter | interpreter.js — Tree-walking evaluator |
| Orinoco (GC) | gc.js — Mark-and-sweep with generations |
| Context/Scope | environment.js — Lexical scope chain |
📜 License
MIT
💖 Donate
UPI ID: divyanshugupta01@ptyes
🔎 Keywords
Javascript engine R1(Rudra-1) interpreter parser compiler
