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

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

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.