This post is all about how I’ve written my own programming language that I’ve titled Hyde. It’s based on Robert Nystrom’s excellent book Crafting Interpreters which I highly recommend you read. It’s easily digestible even for intermediate-level developers. You can read it for free online, or you can be awesome and support the author with a purchase of either a physical or e-book copy.
I think a lot of what I’d like to say is better captured in Crafting Interpreters, so I’ll point out some of the great takeaways from what I learned from the book as well as how my implementation differs from Nystrom’s language called Lox.
If you want to check out a demo of Hyde in action (I wrote a webserver in Hyde to serve HTML generated by a custom Hyde template generator!), feel free to check that out here. You can also check out the source code for Hyde here, or the source code for the demo here.
Some Key Takeaways for Me
A Surprising Bit of Java
Even though Hyde is written in Python, I learned quite a bit of Java as well. One of the things I’m a big advocate of is to not blindly follow tutorials from other people, and that includes this book. While I wrote the code in Python, the original Lox interpreter is crafted in Java (ha!), a language I’m only familiar with in passing.
It turns out this is great way to learn Java syntax as it requires reading, understanding, and ultimately translating code from Java to Python. This, predictably, caused issues when I screwed up re-implementation of a feature.
As an example, the
Resolver class in Java uses a
Stack to handle variable scoping, whereas Python doesn’t have this in its standard library (or maybe I missed it). I did re-write some of the original Java that depended on a stack to handle it with Python lists, which worked but proved quite buggy in some edge cases. Great practice nonetheless!
One of the things you don’t get to work on often in higher level languages is core primitives. For me, that’s messing with Ruby
Arrays, as they’re implemented in whatever language the higher level language is built on top of (in Ruby’s case, C on MRI). You can, of course, extend these types of objects with native code, but the point is you rarely mess with the underlying implementation itself.
When you’re building a language, this stuff doesn’t exist, and so you have great flexibility on how things work. I’m particularly proud of extending the base Lox interpreter – it’s one of the reasons I don’t call my language Lox.
Hyde has additional primitives:
One of these things is not like the others…
Okay, barring the fact that the last one is comically more complicated than the others, they are fairly basic but allow for very powerful and complex functionality to be layered on top of them. It’s actually quite surprising how much you can do with just arrays and maps. There’s not a lot going right now in Hyde’s standard library but with these basic constructs it would be easy to extend it.
One day I’ll write a fast sorting algorithm in Hyde.
I do want to point out the last one is simply a wrapper around Python’s
http.server construct, so it’s only purpose for inclusion in Hyde is so that I could get the demo static site off the ground using nothing but Hyde itself. Well, almost… You do have to install Hyde via
Writing Test Runners
I’m a big believer in tests and take them very seriously even for hobby projects, so it should come as no surprise that I wrote tests for Hyde.
What might be interesting is that I wrote a test runner, complete with
assert() functions, that also format color to the terminal. It’s quite pretty when things are all green!
I’m a Ruby dev, so this probably looks similar to RSpec.
Before an actual test runner was written, I did have a simple text file with print statements that printed
False when tests failed. It was absolutely brutal to maintain, so I’m really glad I was able to take it a step further and implement a test runner.
There’s really only one in this project, which is the visitor pattern. It’s not something I’ve used before, so it was nice to see it in action and get to hack on it a bit. I also got to review some of the alternatives.
This isn’t something I have much background in so it was very valuable to me. If you’re like me, it’s worth checking out (even if you don’t make your own language!).
That’s all for now. Thanks for reading!