I am writing a simple compiler using the interpreter design pattern. My problem is how to handle how variables are stored in the compiler.
The syntax tree is compiled recursively using the method compile
having the compiler
as context to provide registers and spill used registers if necessary.
Let's take an example (the function compile
of the class Add
representing an addition)
def compile(compiler):
this.leftOperand.compile(compiler) #compile left operand
this.rightOperand().compile(compiler) # compile right operand
compiler.add(ADDINSTRUCTION(valueleft,valueright))
The use cases are:
- both the left and right operand are complex instructions thus stored in registers
- left operand is a simple value (float or int) and not saved in register but used directly
- there's not enough registers left for "right operand" so left operand result is spilled and retrieved later for for addition
My question is:
Is there an elegant scheme to apply so that the compiler should know what are valueleft
and valueright
(taking into account those use-cases) ? I am looking for the data structures I must use either in expressions themselves or the compiler.
The solutions I thought about are :
#1
make compile return where (in which register) the computation has been stored. But this doesn't work in case a previously stored computation is spilled to the stack (then unspilled in R0).
#2
Saving the two most recent used registers (it would take into account unspilling) but I doubt this scheme would last.
ex:
valueright = compiler.lastUsedRegister
valueleft = compiler.beforelastUsedRegister
but I doubt this scheme will last.
Is there some elegant solution for this problem ?
Aucun commentaire:
Enregistrer un commentaire