aboutsummaryrefslogtreecommitdiff
path: root/compiler/codegen.cup
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/codegen.cup')
-rw-r--r--compiler/codegen.cup37
1 files changed, 37 insertions, 0 deletions
diff --git a/compiler/codegen.cup b/compiler/codegen.cup
index 41eea33..70a83c8 100644
--- a/compiler/codegen.cup
+++ b/compiler/codegen.cup
@@ -34,6 +34,16 @@ fn generate_syscall(num: int) {
emit_asm(" syscall\n");
}
+fn generate_lvalue_into_rax(node: Node*) {
+ if (node.typ == AST_LOCAL_VAR) {
+ let offset = node.d.variable.offset;
+ emit_asm(" mov rax, rbp\n");
+ emit_asm(" sub rax, "); emit_num(offset); emit_asm("\n");
+ } else {
+ die2("Unsupported type in generate_lvalue_into_rax: ", node_type_to_string(node.typ));
+ }
+}
+
fn generate_expr_into_rax(node: Node*) {
if (node.typ == AST_LITERAL) {
if (node.etyp.typ == TYPE_INT) {
@@ -76,15 +86,42 @@ fn generate_expr_into_rax(node: Node*) {
generate_expr_into_rax(node.d.binary.lhs);
emit_asm(" pop rbx\n");
emit_asm(" imul rbx\n");
+ } else if (is_lvalue(node.typ)) {
+ generate_lvalue_into_rax(node);
+ emit_asm(" mov rax, [rax]\n");
+
+ } else if (node.typ == AST_ASSIGN) {
+ putsln("...");
+ generate_lvalue_into_rax(node.d.assign.lhs);
+ emit_asm(" push rax\n");
+ generate_expr_into_rax(node.d.assign.rhs);
+ emit_asm(" pop rbx\n");
+ emit_asm(" mov [rbx], rax\n");
+
+ } else {
+ die2("Unsupported node type in generate_expr_into_rax: ", node_type_to_string(node.typ));
}
}
+fn generate_block(node: Node*);
+
fn generate_statement(node: Node*) {
if (node.typ == AST_RETURN) {
generate_expr_into_rax(node.d.unary);
emit_asm(" mov rsp, rbp\n");
emit_asm(" pop rbp\n");
emit_asm(" ret\n");
+ } else if (node.typ == AST_VARDECL) {
+ if (node.d.var_decl.init) {
+ generate_expr_into_rax(node.d.var_decl.init);
+ let offset = node.d.var_decl.var.offset;
+ emit_asm(" mov [rbp-"); emit_num(offset); emit_asm("], rax\n");
+ }
+ } else if (node.typ == AST_BLOCK) {
+ generate_block(node);
+ } else {
+ // Default to a simple expression statement
+ generate_expr_into_rax(node);
}
}