Developing a computer language has been the most fun and challenging software engineering experience I’ve had.
Like other software projects, early development was focused on building modular functionality around scanning, parsing, analysis, emitting code and executing code. Getting the compiler to interface with the VM and the interpreter to work with the memory manager and JIT compiler was a constantly evolving break/fix process.
One memorable milestone was when I was able to implement a balanced binary tree that exercised all stages of the compiler and runtime. The code was compiled, interpreted, translated to machine code at runtime and unused memory was collected. Achieving this milestone gave me the confidence that I might be able to actually implement a general-purpose programming language.