When you're building a language, it doesn't live in a vacuum. There's not only the "host" language, the language the compiler is initially written in – there's also the eventual execution platform to consider.
If you have a transpiler, you might even have multiple execution environments to worry about! For example, the language you compile to might be compiled to something else...and so on.
You have to ask yourself, which platform does your language target? Is it a desktop app programming language? Does it have to run on embedded systems? What's the use case?
- Numbers are a mess (everything's a float, even ints).
- Support for types has been bolted on after the fact – it would be more work.
- The module system is still solidifying.
- Some APIs like the Date object are completely backwards
And that's just scratching the surface. This post isn't bashing JS – it's how I make my living – but it is saying it's not suitable for this particular compiler project.
Even though we're targeting the web for this project, we don't have to write the compiler itself in JS, nor do we need to compile to JS. Instead, let's write the compiler in my (current) favorite language, Rust!
As for the target: we'll generate Web Assembly code that runs alongside the engine, hooking into pre-defined parts.
I'm still figuring out the WASM-related stuff at this point, and how WASM is generated in Rust, but I'm getting there. More importantly, I'm studying how to implement our parser in Rust using "nom", which looks to be an excellent library for parser combinators.
I suppose I should get back to it. For now, a classic 90s song about keeping your git upstream up to date.