aboutsummaryrefslogtreecommitdiff
path: root/compiler/codegen.cup
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-02-05 20:28:56 -0500
committerMustafa Quraish <[email protected]>2022-02-05 20:28:56 -0500
commit4f99b1e1a4528d679b64915446663091ca09bb7a (patch)
tree5033313c0cdca28fb7dd84abf9073ac664a0c305 /compiler/codegen.cup
parent[compiler.cup] codegen for unary ops, short circuiting &&/|| (diff)
downloadcup-4f99b1e1a4528d679b64915446663091ca09bb7a.tar.xz
cup-4f99b1e1a4528d679b64915446663091ca09bb7a.zip
[compiler.cup] Add support for function calls!
Diffstat (limited to 'compiler/codegen.cup')
-rw-r--r--compiler/codegen.cup24
1 files changed, 24 insertions, 0 deletions
diff --git a/compiler/codegen.cup b/compiler/codegen.cup
index 407fab5..975844d 100644
--- a/compiler/codegen.cup
+++ b/compiler/codegen.cup
@@ -27,6 +27,11 @@ fn emit_asm(msg: char*) {
}
fn emit_num(num: int) {
+ // FIXME: Just support printing negatives directly.
+ if (num < 0) {
+ emit_asm("-");
+ num = -num;
+ }
fputu(gen_out_file, num);
}
@@ -35,6 +40,8 @@ fn generate_syscall(num: int) {
emit_asm(" syscall\n");
}
+fn generate_expr_into_rax(node: Node*);
+
fn generate_lvalue_into_rax(node: Node*) {
if (node.typ == AST_LOCAL_VAR) {
let offset = node.d.variable.offset;
@@ -45,6 +52,20 @@ fn generate_lvalue_into_rax(node: Node*) {
}
}
+fn generate_function_call(node: Node*) {
+ let total_size = 0;
+ let n = node.d.call.args.size;
+ for (let i = n-1; i >= 0; --i) {
+ let expr: Node* = node.d.call.args.data[i];
+ generate_expr_into_rax(expr);
+ emit_asm(" push rax\n");
+ // TODO: this might be an issue if we pass structs some day
+ total_size = total_size + 8;
+ }
+ emit_asm3(" call func_", node.d.call.func.d.func.name, "\n");
+ emit_asm(" add rsp, "); emit_num(total_size); emit_asm("\n");
+}
+
fn generate_expr_into_rax(node: Node*) {
if (node.typ == AST_LITERAL) {
if (node.etyp.typ == TYPE_INT) {
@@ -233,6 +254,9 @@ fn generate_expr_into_rax(node: Node*) {
emit_asm(" pop rbx\n");
emit_asm(" mov [rbx], rax\n");
+ } else if (node.typ == AST_FUNCCALL) {
+ generate_function_call(node);
+
} else {
die2("Unsupported node type in generate_expr_into_rax: ", node_type_to_string(node.typ));
}