Fibra is a zero-dependency, configuration-driven language parser and interpreter sandbox implemented in pure JavaScript.
Instead of compiling guest languages into machine instructions or executing them directly via host eval, Fibra treats language specifications as data. By loading a declarative JSON syntax profile alongside a companion JavaScript runtime file, the engine configures its scanner, parser, and interpreter to run and schedule customized, simulated subsets of languages like Python, JavaScript, C, Go, Ruby, and Java.
Fibra consists of three core components designed to run directly in single-threaded environments like standard web browsers:
To parse highly diverse languages using a unified code path, Fibra separates structural syntax from mathematical expressions:
-
Structural Parsing (Packrat PEG): High-level blocks, loops, function signatures, and control flows are parsed using a recursive-descent Packrat parser. Parse state is memoized to guarantee linear
$O(N)$ parsing time, protecting the engine from exponential backtracking. - Expression Parsing (Pratt): Math operations, ternary conditions, variable assignments, and pointer resolutions are handed off to an implementation of Vaughan Pratt’s top-down operator precedence parser. Precedence values and associativity are loaded dynamically from the language profile.
To simulate multi-threading models (like Go's goroutines or Java's threads) in single-threaded browser environments:
- The core AST tree-walker is written entirely using JavaScript Generator functions (
function*). - During execution, the interpreter yields control back to a central
Schedulerat statement boundaries, or when executing commands likesleep(),join(), or blockinginput()requests. - The Scheduler queues these active generators (fibers) and handles context switching, pausing, and resuming without locking up the browser tab's UI thread.
Language definitions are split cleanly to avoid the complex debugging of raw code strings inside JSON:
- The
.jsonProfile: Declares only metadata, lexical tokens, EBNF syntax rules, precedence tables, and scope paradigms (e.g., lexical block-scoping vs. indentation-scoping). - The
.jsCompanion File: Implements standard libraries, custom wrappers, and system APIs (such as mock implementations of Java'sArrayList, C's simulated pointer references, or Python'sMROmechanics) in a lintable and testable format.
graph TD
Source[Guest Source Code] --> Lexer[Universal Lexer]
Config[JSON Profile Schema] --> Lexer
Config --> Parser[Packrat & Pratt Parser]
Lexer -->|Token Stream| Parser
Parser -->|AST Node Tree| Interpreter[Generator-Based Interpreter]
Config -->|Semantics & Scoping Rules| Interpreter
Interpreter -->|YIELD / SLEEP / SPAWN| Scheduler[Cooperative Scheduler]
Scheduler -->|Controls Task Queue| Interpreter
Interpreter -->|Terminal Output| UI[Browser Console UI]
Fibra does not implement full, production-scale specifications. Instead, it supports specific subsets designed to show how different semantic features map to the same virtual machine:
| Profile | Indentation Model | Scoping Paradigm | Simulated Guest Mechanics |
|---|---|---|---|
| Python | Virtual Layout (INDENT/DEDENT) |
Function-Scoped | Multiple inheritance resolution (MRO), exceptions (try-except-finally), and cooperative multitasking via spawn. |
| JavaScript | Braces ({ }) |
Lexical Block-Scoped | Hoisting variations (var vs let), lexical closures, and mapping setTimeout to fiber yield checkpoints. |
| C Standard | Braces ({ }) |
Lexical Block-Scoped | Struct definition mappings, printf/scanf parsing, and explicit pointer dereferencing and address-of simulations (*, &, ->). |
| Go | Braces ({ }) |
Lexical Block-Scoped | Shorthand variable assignment (:=) and concurrent goroutines (go func()) mapped directly to background fibers. |
| Java | Braces ({ }) |
Lexical Block-Scoped | Entry-point routing (public static void main), generics erasure, and JS-backed libraries (StringBuilder, ArrayList, HashMap). |
The project separates visual presentation, parsing mechanisms, and language runtime implementations:
├── index.html # Interactive Sandbox Entry Point
├── styles.css # Custom UI stylesheet
└── js/
├── main.js # Event wiring & engine bootsrap
├── lexer.js # Layout-aware Regex Lexer (tracks pythonic indents)
├── parser/
│ ├── index.js # Parser initialization
│ └── declarative_parser.js# Packrat PEG + Pratt engine
├── interpreter/
│ ├── index.js # Generator-driven tree-walker
│ ├── environment.js # Lexical Environment & scoping bounds
│ ├── scheduler.js # Fiber task queue controller
│ └── evaluators/
│ ├── declarations.js # Class, function, and variable evaluations
│ ├── expressions.js # Calculations, assignments, and pointers
│ └── statements.js # Loops, conditions, and control signals
└── profiles/
├── index.js # Profile registry loader
├── java.json # Syntax profile for Java simulation
└── java_builtins.js # Companion standard library implementations
To configure a new custom language, you only need to supply its grammar config and runtime built-ins.
{
"name": "MyLanguage",
"config": {
"semantics": {
"scoping": {
"type": "lexical",
"requiresDeclaration": true
}
},
"lexer": {
"tokens": [
{ "type": "LET", "pattern": "let\\b" },
{ "type": "OP", "pattern": "\\+|-|\\*|/" },
{ "type": "ASSIGN", "pattern": "=" }
]
},
"grammar": {
"start": "Program",
"operators": {
"=": { "precedence": 1, "assoc": "right" },
"+": { "precedence": 5, "assoc": "left" }
},
"rules": {
"Program": {
"type": "sequence",
"elements": [
{ "type": "zeroOrMore", "expression": { "type": "rule", "name": "Statement" }, "capture": "body" }
],
"ast": { "type": "Program", "body": "$body" }
}
}
}
}
}export const MyLanguageBuiltins = {
print: (args) => {
return (interpreter) => {
interpreter.write(args.join(" ") + "\n");
return null;
};
}
};When working with or reviewing Fibra, please keep the following design constraints in mind:
- Tree-Walker Execution: Fibra uses an AST-walking interpreter for maximum introspection and step-by-step debugging. It does not compile code to native machine instructions or bytecode, making it highly flexible but slower than a production engine.
- Semantic Simulations: Highly specific features—like C pointers—are simulated via host-level JavaScript reference abstractions (such as assigning key-value indices to mock environments). True memory layouts (like byte arrays and pointer math) are not managed at the hardware level.
- Standard Libraries are FFI Mocks: Standard libraries (e.g., Java's
HashMap) are mock classes mapped to optimized JavaScript arrays and maps through our FFI. They do not run the original source code of those classes.