diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-07 15:42:00 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-07 17:33:55 +0900 |
| commit | cdddf2422553f1f21c8d2c57cd382b8362dc80fb (patch) | |
| tree | 3053026498552aecda2e4889c8455298ad70c8cb /src/codegen.c | |
| parent | e1042a6373773830297dfd5718938c12f21ae624 (diff) | |
| download | ducc-cdddf2422553f1f21c8d2c57cd382b8362dc80fb.tar.gz ducc-cdddf2422553f1f21c8d2c57cd382b8362dc80fb.tar.zst ducc-cdddf2422553f1f21c8d2c57cd382b8362dc80fb.zip | |
feat: support function calls via function pointers
The two-pass parsing of function pointer declaration is referenced from chibicc:
https://github.com/rui314/chibicc
Diffstat (limited to 'src/codegen.c')
| -rw-r--r-- | src/codegen.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/src/codegen.c b/src/codegen.c index 5ac61ed..91baef8 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -398,9 +398,12 @@ static void codegen_args(CodeGen* g, AstNode* args) { } static void codegen_func_call(CodeGen* g, FuncCallNode* call) { - const char* func_name = call->name; + const char* func_name = NULL; + if (call->func->kind == AstNodeKind_func) { + func_name = call->func->as.func->name; + } - if (strcmp(func_name, "__ducc_va_start") == 0) { + if (func_name && strcmp(func_name, "__ducc_va_start") == 0) { fprintf(g->out, " # __ducc_va_start BEGIN\n"); AstNode* va_list_args = &call->args->as.list->items[0]; codegen_expr(g, va_list_args, GenMode_rval); @@ -428,7 +431,7 @@ static void codegen_func_call(CodeGen* g, FuncCallNode* call) { return; } - if (strcmp(func_name, "__ducc_va_arg") == 0) { + if (func_name && strcmp(func_name, "__ducc_va_arg") == 0) { fprintf(g->out, " # __ducc_va_arg BEGIN\n"); // Evaluate va_list argument (first argument) @@ -511,7 +514,12 @@ static void codegen_func_call(CodeGen* g, FuncCallNode* call) { fprintf(g->out, " sub rsp, 8\n"); codegen_args(g, args); fprintf(g->out, " mov rax, 0\n"); - fprintf(g->out, " call %s\n", func_name); + if (func_name) { + fprintf(g->out, " call %s\n", func_name); + } else { + codegen_expr(g, call->func, GenMode_rval); + fprintf(g->out, " call rax\n"); + } fprintf(g->out, " add rsp, 8\n"); fprintf(g->out, " jmp .Lend%d\n", label); @@ -519,7 +527,12 @@ static void codegen_func_call(CodeGen* g, FuncCallNode* call) { codegen_args(g, args); fprintf(g->out, " mov rax, 0\n"); - fprintf(g->out, " call %s\n", func_name); + if (func_name) { + fprintf(g->out, " call %s\n", func_name); + } else { + codegen_expr(g, call->func, GenMode_rval); + fprintf(g->out, " call rax\n"); + } fprintf(g->out, ".Lend%d:\n", label); // Pop pass-by-stack arguments. |
