Vexon: What Building a Small Bytecode Language Taught Me About Runtime Design
Vexon is an experimental programming language I’ve been building to better understand how languages work end to end — from parsing and compilation to execution on a virtual machine.
Rather than focusing on features or syntax novelty, Vexon is designed as a learning-driven language: small, readable, and complete enough to run real programs without hiding behind host-language abstractions.
This post explains what Vexon is, how it’s built, and what kinds of design lessons have come from actually using it.
What Is Vexon?
Vexon is a lightweight scripting language with:
a custom lexer
a hand-written parser
a compiler that emits bytecode
a stack-based virtual machine t…
Vexon: What Building a Small Bytecode Language Taught Me About Runtime Design
Vexon is an experimental programming language I’ve been building to better understand how languages work end to end — from parsing and compilation to execution on a virtual machine.
Rather than focusing on features or syntax novelty, Vexon is designed as a learning-driven language: small, readable, and complete enough to run real programs without hiding behind host-language abstractions.
This post explains what Vexon is, how it’s built, and what kinds of design lessons have come from actually using it.
What Is Vexon?
Vexon is a lightweight scripting language with:
a custom lexer
a hand-written parser
a compiler that emits bytecode
a stack-based virtual machine that executes that bytecode
Everything is implemented from scratch. There is no transpilation to another language’s AST or runtime.
At a high level, the pipeline looks like this:
The goal is not performance parity with production languages, but clarity of behavior and control over execution.
Why a Custom VM?
Building a VM forces you to answer questions that are easy to ignore when embedding into an existing runtime:
How are stack frames created and destroyed?
What invariants must hold before and after each instruction?
How are errors propagated without corrupting state?
What happens when a program doesn’t exit?
Vexon’s VM is intentionally simple:
stack-based execution
explicit call frames
predictable instruction flow
no hidden background behavior
This simplicity makes bugs visible instead of mysterious.
Long-Running Programs Expose Real Problems
Early Vexon programs were short scripts — arithmetic, conditionals, functions. Everything appeared correct.
That changed once I started writing programs that run continuously, such as:
simulation loops
timer-driven logic
simple game-style updates (e.g. Pong-like logic)
These programs exposed issues that never appeared in short scripts:
stack growth due to missed cleanup paths
state not being restored correctly after errors
instruction pointer drift across iterations
This was a key lesson: programs that don’t exit are a better test of a runtime than programs that do.
Debugging at the VM Level
Traditional source-level debugging wasn’t very helpful. The real problems lived below the language syntax.
What worked instead:
dumping VM state (stack, frames, instruction pointer)
logging execution at instruction boundaries
comparing dumps across iterations to detect drift
Seeing what the VM thought was happening made bugs obvious — especially mismatched push/pop paths and incorrect frame teardown.
This led directly to improvements in Vexon’s runtime consistency.
Tooling Before Features
One of the most important outcomes of Vexon so far is a shift in priorities.
Instead of adding more language features, the focus moved to:
better internal visibility
structured runtime dumps
deterministic error handling
tooling that explains why something broke
These improvements made the language easier to extend safely later.
Where Vexon Is Headed
Vexon is still experimental, but it’s already useful as:
a language design playground
a VM and compiler learning project
a testbed for tooling ideas (dump formats, debuggers, GUIs)
Future work is focused on:
better introspection tooling
optional GUI frontends
richer diagnostics
more real programs to stress-test the design
Closing Thoughts
Vexon exists because building a language forces you to confront details most programmers never need to think about — and that’s exactly the point.
If you’re interested in:
how languages are built
how bytecode VMs behave
or why tooling matters as much as syntax
then following Vexon’s development might be useful.