Some notes about BADNOP, the forth compiler. The point of a compiler is to do optimization. This is true I guess, especially if you look at the code size per feature in any compiler's source code. One of the main reasons I choose forth as a language, apart from its inherent coolness as a language on itself, is that it is easy to build a compiler for. In its purest form, forth is a very basic language, and does not need a very smart compiler. This fact is reflected in a feature of almost any classic forth system: smal AND able to compile itself from forth to machine code or interpreted byte code. Once the simple job of getting it to work is done, the only thing that remains is "How can i make it generate more efficient code?" For BADNOP this is the same. Hence BADNOP is really my journey on the path of rising complexity in the world of program translation. A facinating world I've found it to be. Mostly because it seems so very boring from the outside. A compiler is (and should be) treated as a black box, which has a certain smartness to translate a piece of highlevel code to reasonably efficient machine code, so the manual processing of machine code can be minimized. This 'smartness' has to come from somewhere, and i'm amazed by the number of tricks people have devised to perform this translation from high level to low level. It's a rich world, with lots of beautiful mathematics. However, BADNOP is not really advanced in that respect, yet. Mostly because the language it translates is not extremely high level. This choice is an important one, considering the applications at hand: programming very small computers, some low level control needs to be retained by the programmer. I've moved the building of a higher level language to the 'META' level. Build your own compiler! And this actually makes sense. Using CAT, it is trivially easy to generate forth code on the fly, trusting on BADNOP to map this code to machine language as efficient as possible. So what should BADNOP be? (A) a forth -> machine code compiler with integrated peephole optimizer (B) a collection of loosely knit highlevel code generation tools Here (A) behaves as a black box, taking the most tedious and most easily optimized task of mapping code to assembly language using knowledge about the machine itself. It is the final step you see in any old optimizing compiler. Part (B), which is a black box in most other language compilers, is actually a white box here: the default is to use low level construct, but it is possible to explicitly use high level constructs to generate low level code. This approach allows me to keep BADNOP simple, so the core can stay a one man project, but allows me to 'grow' a higher level language bottom up as something emerging out of a collection of tricks, without having to define everything before hand, which in my case would mean to never get it done. Currently, (A) is mostly about mapping forth to register architectures in general (which includes a C code target), which in practice means to reduce the overhead of the parameter stack, and implementing machine specific optimizations for the PIC microcontrollers in addition to that, which in practice means the exploitation of machine specific ideoms. The optimizer (A) is implemented in a simple (but suboptimal) one-pass way, where a collection of forth words (macros) know how they can recombine with previously generated symbolic (pseudo) assembly code. At this moment, there are no fancy data flow and control flow analysis phases which might do a more global optimization, but there is no reason for these features not to be implemented on top of the peephole optimizer in the future.