Zamin: A Scripting Language with a Rust-Based Bytecode VM and GPU-Accelerated ML
Why Build Another Language
Mostly curiosity about how languages work under the hood, rather than just using them. Python was my reference point for the surface syntax - closures, string interpolation, that general feel - but I didn't want to just tree-walk an AST the way a lot of hobby interpreters do, since that's the easy path and I wanted to actually learn something harder. So Zamin compiles source down to bytecode and executes it on a small register-based VM instead.
func fibonacci(n) {
if n <= 1 {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
for i in 0..10 {
print(f"fib({i}) = {fibonacci(i)}");
}
You can paste that directly into the playground and it runs immediately, nothing to install.
How It's Put Together
The pipeline is fairly conventional on paper: lexer, parser, AST, compiler, bytecode, VM. A few parts took more effort than I expected:
- The VM dispatches using raw byte dispatch (computed gotos on GCC/Clang) rather than a function-pointer table. This ended up being a bigger win than I anticipated - roughly 15-25% faster across the board from that change alone.
- A handful of integer operations get their own dedicated opcodes, so common cases like adding a small constant to a register skip boxing and type checks entirely.
- The garbage collector is mark-and-sweep, generational, non-moving, and incremental, mainly because I didn't want noticeable pause times during execution.
- There's a peephole optimizer that does constant folding, dead code elimination, strength reduction, and a few other passes over the compiled bytecode.
How It Compares to Python
I ran some rough benchmarks on the same machine, measured with wall-clock time:
| Benchmark | Zamin | Python 3 | Result |
|---|---|---|---|
| Recursive fib(32) | 1.51s | 0.35s | about 4.3x slower |
| Integer loop (5M ops) | 0.47s | 0.53s | slightly faster, actually |
| String concat (100K) | 3.14s | 0.23s | about 13.4x slower |
| List push (500K) | 0.13s | 0.09s | about 1.5x slower |
So it holds up reasonably well on tight integer loops, and is honestly not great yet on strings and list operations - that's mostly bytecode interpreter overhead I haven't fully optimized away. I'd rather be upfront about that than pretend it doesn't exist; it's a known weak spot I'm still working through.
What's Actually in the Box
- 25+ standard library modules, all available globally without imports -
math,string,fs,json,re,http,csv,datetime,stats,hashlib,logging,subprocess,path,collections,itertools,test,rand,matrix, and a few more - Two GUI toolkits behind feature flags:
lunafor Linux (built on GTK4) andsolfor Windows - OpenCV bindings through a
cvmodule, for basic computer vision work - A GPU-accelerated module called
linum, with a small PyTorch-style API (Sequential,Linear,Adam,CrossEntropyLoss) that runs against CUDA when it's available - A C extension ABI for native modules, and Python interop -
py.import("numpy")with types marshalled automatically between the two languages - An embedding API for calling Zamin from a host Rust application
- A built-in LSP server, plus a companion VS Code extension
- The usual project tooling:
zamin run,zamin repl,zamin fmt,zamin test,zamin build,zamin new - The interpreter also compiles to WebAssembly, which is what powers the browser playground
Trying It Out
The fastest way in is the playground, no install needed:
https://young-developer90.github.io/zamin/playground.html
If you'd rather run it locally:
git clone https://github.com/young-developer90/zamin.git
cd zamin
cargo build --release
./target/release/zamin run examples/hello.zamin
Requires Rust 1.80 or newer.
Full docs, covering the language and standard library in more depth, are here:
https://young-developer90.github.io/zamin/
(also available in Farsi and Japanese, in case that's useful to anyone reading this).
If anyone digs into the VM code, I'd genuinely like to hear where you think the string and list slowdown is coming from - I have a few theories but nothing confirmed yet, and a second pair of eyes would help. Comments are open, and I'll try to respond to whatever comes up. ๐
Comments
No comments yet. Start the discussion.