Architecture & Compiler Internals
Pratt parser pipeline, AST compilation, Bytecode VM instruction set, intelligent compiler diagnostics, and contributor guidelines.
Import Resolution Pipeline & Centralized Package Architecture
BramandScript implements an enterprise-grade module architecture designed for zero disk duplication, offline determinism, and immutability. Module imports follow a deterministic 4-stage pipeline that transparently coordinates embedded binaries, local files, and the centralized package registry.
The 4-Stage Runtime Import Resolution Pipeline
Whenever the compiler encounters an import "path" [as alias] statement, the compiler's resolution engine (compiler/compile_statements.go) executes four sequential stages:
embed:stdlib/)
Fastest Resolution
Imports starting with "std/" (e.g., import "std/math", import "std/json") or matching bare standard library module names are resolved directly against Go's embedded virtual filesystem (embed.FS).
✦ 100% offline and standalone. No filesystem access or external paths are queried.
Paths beginning with "./" or "../", or pointing to local project files, are resolved relative to the directory of the current file being compiled. If the target is a directory, the compiler invokes the Three-Tier Fallback Engine:
- Inspect
bmdpkg.jsonand resolve its declared"entry"file. - Check for
main.bmdin the target directory. - Check for
index.bmdin the target directory.
$HOME/.bmd_libs/registry/)
System Cache
Non-relative, third-party package specifiers (such as import "github.com/alice/json-tools" or import "local/utils@dev") are resolved against the centralized registry. The compiler scans version subdirectories, selects the highest compatible SemVer release, inspects transitive dependencies from enclosing package manifests, and falls back gracefully to legacy cache roots.
OpModule & Immutability
Runtime VM Engine
When a module completes execution, the compiler emits an OpModule opcode. The VM pops the exported Hash map from the operand stack, marks the instance as immutable (ReadOnly = true), and stores it in the global moduleTable.
✦ Any subsequent import of the same module in any file reuses the identical singleton hash, preventing redundant execution and state desynchronization.
// Stage 1: Embedded Standard Library (embed:stdlib/math/index.bmd)
import "std/math" as math
// Stage 2: Relative local file
import "./config.bmd" as cfg
// Stage 3: Centralized Registry ($HOME/.bmd_libs/registry/github.com/alice/json-tools/1.2.0/)
import "github.com/alice/json-tools" as jsonTools
// Stage 4: Module exports are strictly read-only
println(math.PI)
// Attempting to mutate throws ReadOnlyHash error:
// math.PI = 3.14 -> [ERROR] cannot mutate read-only module export
Inter-Process Atomic Locking & Integrity Transactions
To ensure strict data integrity across concurrent terminal sessions, multi-threaded worker pools, and automated CI runners, BramandScript's package subsystem (pkg/lock.go and pkg/integrity.go) implements dual-tier atomic locking and transaction semantics:
Dual-Tier File Lock Architecture (pkg/lock.go)
- Tier 1 (In-Process Channel Lock): Synchronizes concurrent goroutines within the same VM process using Go channel locks with timeout protection.
- Tier 2 (Inter-Process OS Lock): Acquires exclusive kernel-level file locks (
syscall.Flock) on POSIX systems, falling back to PID-based lease files with 30-second stale detection. - Guarantees zero archive extraction collisions or registry corruption when multiple
bmd installprocesses execute concurrently.
Atomic Transactions on integrity.db
- Stores cryptographic SHA-256 digests, file sizes, and verification timestamps for all packages and tarballs.
- Updates are never written directly in-place. The engine writes records to an isolated temporary file (
integrity.db.tmp.<pid>) and commits via atomicos.Rename. - Ensures zero-byte database corruption or partial state failures even if the process is killed abruptly.
SemVer Diamond Dependency Resolution & Zero Redundancy
Dependency graphs frequently encounter the classic Diamond Dependency Problem, where two intermediate libraries depend on different version constraints of the same underlying package:
┌──────────────────────┐
│ Root Project │
└──────────┬───────────┘
│
┌─────────┴─────────┐
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ LibA (^1.0.0) │ │ LibB (^1.2.0) │
└────────┬────────┘ └────────┬────────┘
│ │
└─────────┬─────────┘
▼
┌─────────────────────────────────────┐
│ Resolved: LibC (v1.2.0) [UNIFIED] │
│ Single shared registry installation │
└─────────────────────────────────────┘
Highest Compatible SemVer Unification
When multiple packages depend on compatible SemVer releases (e.g. ^1.0.0 and ^1.2.0), the resolver unifies the dependency request to the highest compatible SemVer (1.2.0), avoiding duplicate downloads and runtime conflicts.
Side-by-Side Major Isolation
When conflicting major versions are required (e.g. 1.x.x vs 2.x.x), both versions are stored side-by-side in distinct registry directories (registry/.../1.0.0/ and registry/.../2.0.0/) without collision.
Unlike per-project dependency models that replicate identical packages across every project on disk, BramandScript's centralized registry installs each version exactly once. Every project on the host links directly against the centralized registry, conserving gigabytes of flash storage and minimizing internet bandwidth consumption.
Intelligent Diagnostic Engine (Rust/Clang-Style with Context Window)
BramandScript features a world-class diagnostics engine inspired by Rust and modern Clang. When an error occurs (syntax error, compile-time symbol resolution failure, or runtime error), the diagnostics engine renders:
- 10 Lines of Code Context: 5 context lines above and 5 context lines below the incident line.
- Dynamic Caret Pointer: Precise column caret (
^~~~) highlighting the exact offensive token. - Zero Box Borders: High-readability minimalist gutters without noisy borders.
- Intelligent Hints: Actionable suggestions analyzing the identifier name or error condition.
Sample Diagnostic Output
error[CompileError]: undefined variable 'userScore'
--> test.bmd:8:11
|
3 | let baseBonus = 50
4 | fn calculateRank(points) {
5 | let multiplier = 2
6 | return points * multiplier
7 | }
8 | let final = userScore + baseBonus
| ^~~~~~~~~ [Hint: Declare variable using 'let userScore = ...' or check spelling]
9 | print("Final:", final)
10 | print("Done")
|
Virtual Machine & Architecture (Lexer -> Pratt Parser -> Bytecode -> Stack VM)
BramandScript does NOT use slow tree-walk evaluation. Every source file travels through a four-stage Bytecode VM pipeline:
Source Code (.bmd)
│
▼
1. Lexer (tokenizes into typed Token structs with Line & Col tracking)
│
▼
2. Pratt Parser (Top-down operator precedence Abstract Syntax Tree)
│
▼
3. Bytecode Compiler (Symbol Scoping, Constants Pool, Emits Opcodes)
│
▼
4. Virtual Machine (Stack loop, 2048 stack cells, Frame call-stack)
Instruction Set & Opcode Reference
Instructions are encoded as 1-byte opcodes followed by optional 1-byte, 2-byte, or 8-byte (64-bit) BigEndian operands to support unbounded 64-bit bytecode programs with millions of instructions, constants, and globals.
| Opcode | Operands | Stack Effect | Description |
|---|---|---|---|
OpConstant |
[uint64] index |
--> [val] |
Loads constant from 64-bit constant table and pushes to stack |
OpPop |
none | [val] --> |
Pops top element off stack |
OpAdd, OpSub, OpMul, OpDiv, OpMod, OpPow |
none | [a, b] --> [result] |
Binary arithmetic operations on integers or floats |
OpEqual, OpNotEqual, OpGreaterThan, OpGreaterThanEqual |
none | [a, b] --> [bool] |
Comparison operations pushing canonical True or False |
OpJump |
[uint64] offset |
none | Unconditional 64-bit jump setting instruction pointer |
OpJumpNotTruthy |
[uint64] offset |
[cond] --> |
Pops condition; jumps to 64-bit offset if falsy (false or null) |
OpJumpTruthy |
[uint64] offset |
[cond] --> |
Pops condition; jumps to 64-bit offset if truthy |
OpSetGlobal / OpGetGlobal |
[uint64] globalIndex |
[v] --> / --> [v] |
Sets or retrieves variable from 64-bit dynamically scalable globals table |
OpSetLocal / OpGetLocal |
[uint16] localIndex |
[v] --> / --> [v] |
Sets or retrieves variable offset from frame base pointer |
OpClosure |
[uint64] const, [uint8] free |
[free...] --> [closure] |
Creates closure wrapping compiled fn from 64-bit constant pool and free cells |
OpPushHandler |
[uint64] catchOffset |
none | Pushes exception handler entry with current SP and target catch IP |
OpPopHandler |
none | none | Pops top exception handler upon successful try-block completion |
OpThrow |
none | [val] --> |
Pops value and triggers call stack unwinding to nearest catch handler |
OpCall |
[uint8] numArgs |
[fn, args...] --> [frame] |
Allocates new Frame on call stack, transfers execution |
OpReturnValue / OpReturn |
none | [frame] --> [returnVal] |
Restores caller frame and pushes return value |
OpJumpNotNull |
[uint64] offset |
[val] --> [val] |
Inspects top of stack; jumps to 64-bit offset if value is NOT null (null-coalescing ?? short-circuit) |
OpJumpNull |
[uint64] offset |
[val] --> [val] |
Inspects top of stack; jumps to 64-bit offset if value IS null (optional chaining ?. short-circuit) |
OpDefer |
[uint8] numArgs |
[fn, args...] --> |
Registers deferred LIFO cleanup closure hook on active call frame |
OpSpread |
none | [container] --> [unpacked...] |
Unpacks iterable elements (Array or Hash) inline into enclosing literal |
OpDup |
none | [val] --> [val, val] |
Duplicates the top element on the evaluation stack |
OpBitAnd / OpBitOr / OpBitXor |
none | [a, b] --> [res] |
Performs 64-bit bitwise AND, OR, and XOR operations |
OpShiftLeft / OpShiftRight / OpBitNot |
none | [a, n] --> [res] / [a] --> [res] |
Performs bitwise left shift, arithmetic right shift, and bitwise inversion (~) |
OpArray / OpHash |
[uint16] count |
[elements...] --> [container] |
Constructs dynamically-sized Array or Hash map from stack values |
OpIndex / OpSetIndex |
none | [col, key] --> [v] / [col, key, v] --> |
Indexed read or mutation with negative indexing and bounds checks |
OpSpawn / OpSend / OpReceive |
[uint8] args / none |
[fn] --> / [ch, v] --> / [ch] --> [v] |
Lightweight concurrent task spawning and synchronized channel streaming |
OpGetBuiltin |
[uint8] builtinIndex |
--> [builtin] |
Retrieves Go standard library builtin function from immutable host registry |
OpGetFree / OpSetFree |
[uint8] freeIndex |
--> [v] / [v] --> |
Reads or mutates lexical free-variable closure captured cell |
OpCurrentClosure |
none | --> [closure] |
Pushes reference to active closure on the stack for self-recursion |
OpGetLocalCell / OpGetFreeCell |
[uint16] / [uint8] |
--> [cell] |
Allocates or extracts mutable shared reference cell for closures |
OpModule / OpEnterPackage / OpLeavePackage |
[uint64] pathIndex / none |
none | Module singleton management and package boundary permission isolation |
OpTrue / OpFalse / OpNull |
none | --> [bool/null] |
Pushes singleton immutable boolean or null runtime object |
OpBang / OpMinus |
none | [val] --> [res] |
Logical negation (!) and arithmetic negation (-) operations |
Dynamic Stack Allocation & Configurable Call Frames
Unlike primitive bytecode engines with fixed stack arrays that crash on deep recursive traversals, the Bramand Virtual Machine dynamically expands its call frame slice (vm.frames) and operand stack on demand. Developers can configure max stack depth limits via CLI flag --max-frames <N> to bound recursion or enable deep scientific computation safely.
OOP Struct State Synchronization & Thread Safety
Structs instantiate as hash tables encapsulating method closures. To prevent state desynchronization between property mutation and closure state, BramandScript enforces bidirectional state synchronization:
- Pre-Call Synchronization: Instance properties are copied into method closure free variables before execution.
- Post-Return Synchronization: Modified free variables are written back to the instance hash on method exit (
OpReturnValue/OpReturn). - Thread-Safe Memory Primitives: Shared runtime collections (
object.Hashandobject.Channel) are protected by Go standard librarysync.RWMutex, eliminating race conditions across concurrentspawntasks.
Garbage Collection Model & Embedded Standard Library (embed.FS)
BramandScript delegates heap memory reclamation directly to Go's concurrent tri-color mark-and-sweep garbage collector, ensuring sub-millisecond pause times and zero manual memory leaks. Circular references are protected with depth barriers across equality and inspection routines. Furthermore, all 21 modular standard library packages are embedded directly inside the binary using pure Go standard library //go:embed *, enabling standalone execution anywhere on any operating system without filesystem dependencies.
Bytecode Disassembler & Execution Profiler
BramandScript provides production-grade bytecode introspection and profiling primitives directly within the CLI and interactive REPL. Developers can disassemble compiled functions into assembly instructions and profile opcode execution hotspots with zero external tools.
1. Interactive Bytecode Disassembler (:disasm)
The disassembler traverses raw bytecode byte streams, decodes opcodes using the opcode definitions table, resolves big-endian operands, and annotates constants and symbols:
# CLI command
bramand disasm program.bmd
# Interactive REPL command
:disasm let x = 40 + 2
2. Runtime Execution Profiler (:profile)
When profiling is active, the Virtual Machine measures per-instruction execution duration with high-resolution CPU clocks into a fixed [256] duration array. After execution, it outputs a formatted hotspot analysis table displaying opcode counts, total execution time, average latency per operation, and relative percentage:
✦ BramandScript Execution Profiler
────────────────────────────────────────────────────────────────────────────
OPCODE COUNT TOTAL TIME AVG/OP HOTSPOT PROFILE
────────────────────────────────────────────────────────────────────────────
OpGetGlobal 402 125.58 µs 312 ns ███░░░░░░░░░ 27.2%
OpAdd 200 112.17 µs 560 ns ██░░░░░░░░░░ 24.3%
OpSetGlobal 202 87.57 µs 433 ns ██░░░░░░░░░░ 19.0%
OpConstant 203 73.00 µs 359 ns █░░░░░░░░░░░ 15.8%
OpGreaterThan 101 30.70 µs 303 ns █░░░░░░░░░░░ 6.6%
────────────────────────────────────────────────────────────────────────────
Total Instructions: 1310 | Execution Time: 855.69 µs | Speed: 1530.9 KIPS
Contributing & Community Guide
BramandScript welcomes contributions from software architects, compiler enthusiasts, and open source developers worldwide.
Contribution Mandates
- Standard Library Exclusivity: Never introduce third-party Go modules or run
go get. - Comprehensive Unit Tests: Every new feature must include automated test coverage in its corresponding package test file (
*_test.go). - No Emojis Rule: Uphold clean Unicode typography across documentation, code, CLI, and error handlers.
- Track Roadmap with
bmd-task: Runbmd-task listorbramand run tools/task.bmd listto inspect active weekly tasks.
Verify all subsystems locally before submitting pull requests:
go test ./... -v
Ahead-of-Time Optimization & Scientific Engine Pipeline
BramandScript features an advanced AOT compiler optimization pipeline and first-class modern language primitives engineered for zero-overhead scientific execution:
Compiler Constant Folding & Peephole Optimizer
The compiler optimizer (compiler/optimizer.go) operates directly on the Abstract Syntax Tree prior to bytecode emission. Constant arithmetic expressions (e.g. 2 * 3 + 4 * 5, 2 ** 10, string concatenations, and logical comparisons) are evaluated at compile time into single constants. Subsequent peephole analysis eliminates redundant stack operations such as consecutive OpDup and OpPop pairs.
Pipeline Operator (|>) Zero-Overhead Lowering
The pipeline operator (|>) provides elegant functional composition: data |> filter(fn) |> map(fn) is lowered at compile time directly into standard nested call chains map(filter(data, fn), fn), incurring zero intermediate stack overhead or heap variable allocation.
Pattern Destructuring
Modern pattern destructuring is supported natively in variable declarations and function signatures:
let [head, next, ...rest] = data_series;
let { host, port, timeout } = server_config;
fn process_point({ x, y }) { return sqrt(x*x + y*y); }
Stateful Coroutine Generators & High-Resolution Braille TUI
Generator functions using yield produce lazy, stateful iterators backed by lightweight coroutine tasks. Scientific plots and function curves are rendered with 8x resolution per terminal cell using pure Unicode Braille matrix patterns (std/tui/plot).
Week 5 Advanced Engine Architecture & Execution Subsystems
Week 5 introduces four major architectural subsystems into the BramandScript VM and compiler core:
1. Compile-Time Metaprogramming Sandbox (comptime { ... })
During compilation, when the Pratt parser encounters comptime, it produces an ast.ComptimeExpression. The compiler instantiates an isolated sub-compiler and triggers the Go VM sandbox (compiler.ComptimeEvaluator). The sandbox executes bytecode independently in an isolated frame and captures the top-of-stack result. The returned runtime object is placed directly into the outer bytecode constant pool and inlined via OpConstant with zero runtime compute cost.
2. Thread-Safe Reactive Stream Pipelines & Backpressure Control
Streams implement a dual push/pull contract. In unconstrained push mode, items flow down the pipeline through functional combinators. When consumer backpressure is active (sub.request(n)), the producer thread coordinates with a condition variable (sync.Cond) bound to a mutex. Downstream operators like debounce, throttle, and window batch and pace event emission safely across goroutines without data races.
3. In-Memory Relational SQL AST Parser, Planner & Execution Engine
The SQL subsystem converts raw SQL queries into an SQLQueryPlan representing selections, joins, predicates, groups, and sorts. The relational engine executes the plan against in-memory datasets or DataFrame tables through structured pipeline stages: Table Scan → Relational Join (INNER, LEFT) → Predicate Evaluation (WHERE) → Group Hash Partitioning → Aggregate Computation (COUNT, SUM, AVG, MIN, MAX) → Having Filter → Order By Sorting → Column Projection → Limit/Offset Slicing.
4. Time-Travel Reversible Execution Checkpoint Architecture
When running with bmd record, the VM wraps its inner execution loop with an ExecutionRecorder. At each bytecode instruction step, the recorder captures a StepCheckpoint storing step count, instruction pointer (IP), opcode name, operand stack snapshot, active locals, current function name, and source line. The resulting ExecutionTrace is serialized to JSON, enabling the interactive ReplayDebugger to step backward (step_back), forward, and jump to arbitrary historical execution checkpoints.
Week 6 Decoupled Standard Library & Runtime Separation
Week 6 establishes the fundamental architectural decoupling of BramandScript into a Two-Tier Runtime Model, strictly adhering to the Lean VM Principle (Rule 12):
┌────────────────────────────────────────────────────────────────────────────────────────┐
│ USER APPLICATION CODE (.bmd) / EXAMPLES │
└───────────────────────────────────────────┬────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────────────────────────┐
│ TIER 2: 100% PURE BRAMANDSCRIPT STANDARD LIBRARY (stdlib/bmd_std/) │
│ • std/http : RFC 7230 Wire Parser, Server, Client, Radix-Trie Router │
│ • std/ws : RFC 6455 Handshake, Frame Codec, Masking, Server, Client, Broadcast │
│ • std/dns : RFC 1035 UDP DNS Codec, 0xC0 Pointer Compression, In-Memory TTL Cache │
│ • std/https : TLS HTTP/1.1 Client & Server with SNI Certificate Verification │
│ • std/process : ChildProcess Class, Unix IPC Stream Piping (proc1.pipe(proc2)) │
│ • std/buffer : High-Level Buffer Struct, BE/LE Numeric Codecs, IEEE 754 Floats │
│ • std/io : Stream Combinators, BufferReader, BufferWriter, io.pipe │
└───────────────────────────────────────────┬────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────────────────────────┐
│ TIER 1: LOW-LEVEL HOST PRIMITIVES IN PURE GO (stdlib/go_std/) │
│ • go_std/net.go : Raw TCP listeners, dials, UDP sockets, TLS with SNI │
│ • go_std/os.go : Subprocess spawn, wait, kill, stdin/stdout/stderr pipes, env │
│ • go_std/buffer.go : Fast slice allocation, bulk memory copy, binary read/write │
└───────────────────────────────────────────┬────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────────────────────────┐
│ STACK-BASED BYTECODE VM ENGINE & UNIFIED TRUTHINESS (vm/vm.go) │
│ • Unified isTruthy(): Standardizes falsy evaluation across all opcodes │
│ Canonical Falsy Matrix: false, null, 0, 0.0, "", bytes(0) │
│ • 100% Self-Contained Binary Bundling via pure Go embed.FS (Rule 21) │
└────────────────────────────────────────────────────────────────────────────────────────┘
✦ Lean VM Principle (Rule 12)
High-level protocols (HTTP, WebSockets, DNS) and data processing utilities are not hardcoded inside the Go VM execution loop. Instead, the Go engine exposes minimal, fast system primitives (raw TCP sockets, subprocess stream handles, raw byte slices), while the entire application protocol logic is authored in clean, self-hosted BramandScript code.
✦ Embedded Standalone Binary (Rule 21)
The entire standard library (stdlib/) is embedded directly inside the compiled binary using Go's standard embed.FS. Running the bramand binary from any directory on Linux, Android Termux, macOS, or Windows resolves import "std/<module>" seamlessly without external file dependencies.
Released under the MIT License · Copyright (c) 2026 Codeleafly <ziprecovery2024@gmail.com> (Codeleafly).