Personal Log »

WIP: Micro Programming Language

I have always been very interested in compilers/interpreters and operating system development. Back in Uni, those were my favourite topics, together with programming –of course–.

In the late 90s and early 2000s I had a lot of side projects working on both, although I never got too far in any of them –at some point I wrote an interpreter using flex/bison that could qualify as programming language, but back in DOS days, the source got lost on a broken diskette–, and I conceded that I would never get anywhere and focused on other things.

But the itch comes every now and then.

The last time I released something was my JTC –names are hard!–, and I took the toy part seriously because it is certainly useless. But it was fun, even if I had the feeling PLY was doing most of the work for me.

For the last few weeks I’ve been re-reading the very excellent Crafting Interpreters, and because I’m refreshing my Go, I started implementing an interpreter using that language. And I’m having a lot of fun!

def fib(n number, acc1 number, acc2 number) number {
    if n == 0 {
        return acc1;
    } else {
        if n == 1 {
            return acc2;
        } else {
            return fib(n - 1, acc2, acc1 + acc2);
        }
    }
}

println("fib 90: ", fib(90, 0, 1));
// output:
//   fib 90: 2880067194370816120
// in 0.002429 secs thanks to the tail-call optimization

At this point I think I have fully understood the tree-walk interpreter part of the book, and I’m finishing what could be a small statically-typed programming language.

Although it is still a toy, I’m proud of the features:

  • Statically typed, types are checked when parsing the code.
  • Variables, constants and functions.
  • Conditionals and loops (with break and continue).
  • Lexical scopes.
  • Functions are higher-order, support closures, and recursive tail-call optimization.

All with some test coverage, and a design that I hope will allow me to write also a compiler targeting the Z80 –initially, and I’m not sure how some of the current features will look like; e.g. closures–.

What I’m missing at this point is arrays, structures and some types –e.g. for now there’s an int64 that I call number, but I need types for 8 and 16 bit numeric values and conversions between them–.

The idea is that by making the language small with some restrictions, it should be easier to generate Z80 code. Also, by making a interpreter first, I can learn and it will be useful as well to write tests on the interpreter to validate the code that then will be compiled and run on a Z80 CPU.

I was waiting to have something to release before talking about it, but I thought: why not?

Considering my limited time, and that I’m in the middle of some professional changes –I may talk about it later on–, this means other projects are on hold. Which doesn’t mean abandoned, but there’s always some risk of that!

Would you like to discuss the post? You can send me an email!