DEV Community

Cover image for Zamin: A Scripting Language with a Rust-Based Bytecode VM and GPU-Accelerated ML
Artin Azadsarv
Artin Azadsarv

Posted on • Originally published at github.com

Zamin: A Scripting Language with a Rust-Based Bytecode VM and GPU-Accelerated ML

If you'd rather not clone anything just to see what this is, there's a playground that runs the whole interpreter in your browser — no install required: https://young-developer90.github.io/zamin/playground.html

I've been working on Zamin for the past several months. It's a scripting language, written in Rust, with its own bytecode virtual machine rather than a tree-walking interpreter. I wanted to actually see a project like this through to a working, reasonably complete state instead of leaving it half-finished, which is admittedly a common failure mode with language projects. So it's grown to include a proper CLI, a formatter, a test runner, two GUI toolkits, and even optional GPU acceleration — more than I originally set out to build, if I'm honest.

Repo: https://github.com/young-developer90/zamin (MIT licensed)
Playground: https://young-developer90.github.io/zamin/playground.html
Docs: https://young-developer90.github.io/zamin/

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)}"); }
Enter fullscreen mode Exit fullscreen mode

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: luna for Linux (built on GTK4) and sol for Windows
  • OpenCV bindings through a cv module, 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
Enter fullscreen mode Exit fullscreen mode

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. 🙂

Top comments (0)