Skip to content

Blog

A journey through software engineering. Appreciating abstraction and discovering what lies beneath.

Building a Minimal Yet Extensible Language: Acorn

When embarking on the journey of creating a programming language, it is (very) tempting to start with the simplest possible feature set. For Acorn, that meant supporting just one statement: print <int>.

At first glance, this seems extremely trivial - and honestly, it is. But somehow I managed to turn "print a number" into a full-blown C++ architectural odyssey, complete with smart pointers, visitor pattern and an excessive number of header files.

As soon as you aim for extensibility and modularity, even this basic goal becomes a surprisingly complex engineering challenge.

Illusions of Simplicity

Obviously, a language that only prints an integer could be implemented in about five lines of Python. In fact, print(42) already exists and works perfectly fine. But where's the fun - or the learning opportunity - in that?

If you want to:

  • Compile to Java bytecode (using C++)
  • Implement your own flavour of the JVM spec (yes, really)
  • Support future language features
  • Build both a compiler AND an interpreter
  • Maintain clean separation of concerns

...then you need to design a system with clear abstractions and modular components right out of the gate.

Acorn's Architecture: Designed for Growth

Being somewhat serious for a moment, Acorn is structured with extensibility in mind:

  • AST (Abstract Syntax Tree): Even for a single statement, it uses an AST to represent the program. This makes it easy to add new statement types later.
  • Compiler and Interpreter: The codebase supports both compiling to .class files and executing the code directly. This dual approach is possible thanks to a well-defined visitor pattern.
  • Separation of Concerns: Scanning, bytecode generation, and interpretation are all handled by separate modules. This modularity will (fingers crossed) pay off as the language grows.

Why Not Just Hardcode Everything?

It's tempting to write a single function that parses and prints an integer. It would be about ten lines, work perfectly, and I could have finished this project in an afternoon.

But that approach quickly becomes unmanageable as soon as you want to add features. By investing in a modular design early, you avoid painful rewrites later. At least, that's the theory. In practice, you just get to rewrite things in a more architecturally sound way.

Key Takeaways

  • Even the simplest language benefits from a solid architecture
  • Design for extensibility from day one
  • Separation of concerns makes future changes easier and safer
  • Modularity enables both compilation and interpretation

Try It Yourself

Check out the project README for build and usage instructions.

Fair warning: the setup process is probably more complex than the language itself. Explore the codebase to see how even a minimal language can be a playground for software architecture best practices - or a masterclass in enthusiastic over-engineering, depending on your perspective.


Acorn is open source (MIT) and welcomes contributions! Especially if you want to help me figure out why I thought this was a good idea.

Getting Hands-On with HotSpot

Rediscovering My Java Roots

Recently, I found myself revisiting Bill Venners' classic book Inside the Java Virtual Machine. I started my programming journey as a Java developer in the late 90s and spent about 15 years deeply immersed in the Java ecosystem. Those were fascinating times - watching Java evolve from its early versions through the enterprise boom, and seeing how the JVM became a platform for multiple programming languages.

The book sparked something in me. Despite having moved on to other technologies, platforms and roles over the years, I felt drawn back to the intricate world of Java - not just to write Java code again, but to look under the bonnet at the very engine that powers it: the HotSpot VM.

I decided to embark on a hands-on journey with OpenJDK, the open-source implementation of the Java Platform. This post documents my setup process using CLion as my IDE of choice. If you're considering exploring OpenJDK's internals yourself, hopefully this guide will save you some time and frustration.