Compiler Internals & Design

Architecture & Compiler Internals

Pratt parser pipeline, AST compilation, Bytecode VM instruction set, intelligent compiler diagnostics, and contributor guidelines.

Chapter 14

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:

Stage 1: Embedded Standard Library (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.

Stage 2: Relative Local Filesystem Resolution Local Project

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:

  1. Inspect bmdpkg.json and resolve its declared "entry" file.
  2. Check for main.bmd in the target directory.
  3. Check for index.bmd in the target directory.
Stage 3: Centralized Package Registry ($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.

Stage 4: In-Memory Module Singleton Table with 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.

bmd — Module Import & Immutability
// 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 install processes 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 atomic os.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:

graph — Diamond Dependency Resolution Model
        ┌──────────────────────┐
        │     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.

Zero-Redundancy Cache Sharing

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.

Chapter 16

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

terminal — diagnostic report
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")
     |
Chapter 17

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:

architecture 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.Hash and object.Channel) are protected by Go standard library sync.RWMutex, eliminating race conditions across concurrent spawn tasks.

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.

VM Introspection & Hotspots

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 & REPL Disassembly
# 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:

Profiler Hotspot Output
✦ 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
Chapter 18

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: Run bmd-task list or bramand run tools/task.bmd list to inspect active weekly tasks.
Run Full Test Suite

Verify all subsystems locally before submitting pull requests:

go test ./... -v
Chapter 19

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 Architecture Enterprise Engine Subsystems

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.

AST (ComptimeExpression) ──▶ Sub-Compiler (Bytecode) ──▶ Sandbox VM (Execute) ──▶ OpConstant (Inlined)

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.

Stream Producer ──▶ sync.Cond Wait (Backpressure) ──▶ Transform (Map/Filter/Window) ──▶ Subscriber Next

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.

SQL String ──▶ Tokenizer ──▶ SQLQueryPlan ──▶ Scan ──▶ Join ──▶ Filter ──▶ GroupBy/Agg ──▶ Project/Limit

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.

VM Loop Step ──▶ RecordStep (IP, Opcode, Stack, Locals) ──▶ trace.json ──▶ ReplayDebugger (Step / StepBack)
Week 6 Architecture Decoupled Engine

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):

Runtime Architectural Hierarchy — Host Go Primitives vs Pure BramandScript Standard Library
┌────────────────────────────────────────────────────────────────────────────────────────┐
│                        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).