diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-05 20:28:56 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-05 20:28:56 -0500 |
| commit | 4f99b1e1a4528d679b64915446663091ca09bb7a (patch) | |
| tree | 5033313c0cdca28fb7dd84abf9073ac664a0c305 /compiler/codegen.cup | |
| parent | [compiler.cup] codegen for unary ops, short circuiting &&/|| (diff) | |
| download | cup-4f99b1e1a4528d679b64915446663091ca09bb7a.tar.xz cup-4f99b1e1a4528d679b64915446663091ca09bb7a.zip | |
[compiler.cup] Add support for function calls!
Diffstat (limited to 'compiler/codegen.cup')
| -rw-r--r-- | compiler/codegen.cup | 24 |
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)); } |