Logo for ammarahmed.ca

I built my own programming language because I wanted to understand how programming languages actually work.

Not “I watched a YouTube video about compilers” understand.

I mean really understand.

Before you go any further, try out Qalam on the web playground.

For a long time, interpreters and compilers felt like magic. You type code. Computer runs it. Sure. But what actually happens between those two steps?

At some point I realized the only way to answer that properly was to build one myself.

So I did.

I followed Robert Nystrom’s Crafting Interpreters, but instead of writing it in Java like the book, I rewrote everything in Rust. Partly because I like Rust. Partly because Rust doesn’t let you get away with anything. If you misunderstand ownership or lifetimes, it reminds you immediately, aggresively.

That friction was useful. It forced me to understand every moving piece instead of blindly translating examples.

And since I was already going through the pain, I decided to make it more interesting.

Instead of standard keywords, I replaced everything with Roman-Urdu. So if became agar, else became warna, return became wapis, and so on.

Was that necessary? Absolutely not.

Did it make it more fun? Yes.

And when you’re building something that nobody will use, fun matters.

What Qalam Actually Is

Qalam is a tree-walk interpreter. Nothing fancy. No JIT. No optimization passes. Just clean fundamentals.

It has three main components:

Scanner

Takes raw source code and converts it into tokens, the basic building blocks of identifiers, numbers and keywords.

Parser

Turns those tokens into an Abstract Syntax Tree (AST) that represents the structure of the program.

Interpreter

Walks the tree and evaluates it.

That’s it

If something goes wrong, it falls into one of three buckets:

  • Scanner error (bad characters)
    • Parser error (bad syntax)
      • Runtime error (your logic betrayed you)

        Here’s a small example:

        1kaam factorial(n) { 2 agar (n == 0) { 3 wapis 1; 4 } 5 wapis n * factorial(n - 1); 6} 7 8bolo(factorial(5)); // outputs: 120

        Same logic you’d write anywhere else. Just with slightly different vocabulary.

        Why Bother?

        Because writing a language removes the illusion.

        Once you build a scanner, you stop thinking of code as “text”.

        Once you build a parser, you stop thinking of syntax as magic.

        Once you build an interpreter, you realize most languages aren’t mystical, they’re structured systems layered on top of each other.

        It’s one of those projects that permanently changes how you think about programming.

        Qalam isn’t mean to replace anything. It’s not optimized. It’s not production-ready. It’s not the next big language.

        It’s a learning project.

        But it’s the kind of project that upgrades how you see everything else.