I'm trying to write a compiler for a self-designed CPU with accompanying instruction set. The CPU has 3 registers, 2 input registers (B and C) and one output register (D). When for example an ADD instruction is executed the sum of B and C is calculated and stored in D.
I'm trying to write the compiler with the visitor design pattern: I have a bunch of language tree classes like "IfStatement", "Addition", "Integer" and a visitor "Compiler". The visitor would look at each node of the tree and append bytecode to the end of the bytecode list. I can't figure out how to cleanly handle register overrides: when evaluating the expression
2*(7+3)
the generated bytecode is
PUTb 2
PUTb 7
PUTc 3
ADD
MOVE D C
MUL
As you can see the 2 is overridden by the 7. I want the compiler to realize it can reverse the order to
(7+3)*2
or that it can store temporary result is RAM, using some other instructions, this will certainly be necessary for more complex expressions like
(7-5)*(8+3)
Is there a clean/object-oriented way to handle this? Is the Visitor pattern not appropriate here? Do I need to look at some advanced techniques like register coloring? The compiler will be written in Java, bu I don't think that really matters.