> I assumed you were relying on an existing compiler.
Fair assumption, actually I was. Originally I wanted to port Bellard's TCC, but run into roadblocks: no real architecture abstraction layer as it generates machine code directly, so hard to port to a new CPU. Also it would be nearly impossible to add new languages like BASIC to that compiler.
> Very impressive!
Thank you very much, but I'm not so sure. C89 is a very simple language (the best ever in terms of provided expressivity and required compiler complexity IMHO).
TL;DR Problem only starts when you try to generate efficient code for an actual real hardware (which part I elegantly avoided entirely by designing the CPU myself), and when you start adding features from the later, increasingly more insane standards (C99, C11 etc.). K&R were geniuses, most of the restrictions they designed and were put in the basic ANSI C89 language makes it extremely easy to implement a C compiler.
And a little rant about integrating a 3rd party compiler, if you don't mind: it was much harder to integrate Lua. That's because Lua is a security nightmare, poorly documented and does not work the way as the doc says. For example:
- Lua might call abort() on your host application (seriously, not joking! And "lua_pcall" dares to throw an "isn't protected" error, resulting in calling that abort. I had to come up with an ugly continuity function and "lua_resume" workaround);
- lack of parameter verification, calling functions like "lua_getinfo" might segfault without any apparent reason;
- unless patched, execution of user provided strings as system commands is allowed;
- unless patched, provides full file system access outside of the sandboxed environment;
- ...and I still couldn't figure out how to get the faulting source line from an error event (which one might think to be obvious and trivial, but it really isn't).
So yeah, integrating Lua definitely took longer than implementing my own compiler :-)