For code generation in my programming language I am using the visitor pattern and I'd like to find a better way to handle assignment statements.
My virtual machine is registered based and each expression node visited just PUSH a register number into a global stack so when I visit the binary expression node I perform a code like:
static void visit_binary_expr (gvisitor_t *self, gnode_binary_expr_t *node) {
DECLARE_CODE();
bool is_assignment = (node->op == TOK_OP_ASSIGN);
if (is_assignment) {
// assignment is right associative
visit(node->right);
visit(node->left);
} else {
// visiting binary operation from left to right
visit(node->left);
visit(node->right);
}
if (!is_assignment) {
uint32_t r3 = ircode_register_pop(code);
uint32_t r2 = ircode_register_pop(code);
uint32_t r1 = ircode_register_push_temp(code);
opcode_t op = token2opcode(node->op);
ircode_add(code, op, r1, r2, r3);
}
}
With this code I can process instructions like: a + b Assuming variable a in register 1 and variable b in register 2 code generated will be:
ADD 3 1 2
The problem is that assignments require a different set of instructions and having only register numbers on the stack is not sufficient. For example in order to access (read) a global variable I should use a GLOAD instruction while to store (write) into a global variable I should use a GSTORE instruction.
I am currently solving the issue by storing a boolean is_assignment value into each node, so I can recursively check which instruction to generate but that requires a lot of logic distributed into every visited node and I really would like to find out a more elegant way where only the visit_binary_expr function can decide what is the best instruction to generate.
Aucun commentaire:
Enregistrer un commentaire