aboutsummaryrefslogtreecommitdiff
path: root/src/compile/functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile/functions.c')
-rw-r--r--src/compile/functions.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/compile/functions.c b/src/compile/functions.c
index fdde7cfe..d9bee1e2 100644
--- a/src/compile/functions.c
+++ b/src/compile/functions.c
@@ -26,6 +26,29 @@
#include "types.h"
public
+Text_t compile_function_declaration(env_t *env, ast_t *ast) {
+ DeclareMatch(fndef, ast, FunctionDef);
+ const char *decl_name = Match(fndef->name, Var)->name;
+ bool is_private = decl_name[0] == '_';
+ if (is_private) return EMPTY_TEXT;
+ Text_t arg_signature = Text("(");
+ for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) {
+ type_t *arg_type = get_arg_ast_type(env, arg);
+ arg_signature = Texts(arg_signature, compile_declaration(arg_type, Texts("_$", arg->name)));
+ if (arg->next) arg_signature = Texts(arg_signature, ", ");
+ }
+ arg_signature = Texts(arg_signature, ")");
+
+ type_t *ret_t = fndef->ret_type ? parse_type_ast(env, fndef->ret_type) : Type(VoidType);
+ Text_t ret_type_code = compile_type(ret_t);
+ if (ret_t->tag == AbortType) ret_type_code = Texts("__attribute__((noreturn)) _Noreturn ", ret_type_code);
+ Text_t name = namespace_name(env, env->namespace, Text$from_str(decl_name));
+ if (env->namespace && env->namespace->parent && env->namespace->name && streq(decl_name, env->namespace->name))
+ name = namespace_name(env, env->namespace, Text$from_str(String(get_line_number(ast->file, ast->start))));
+ return Texts(ret_type_code, " ", name, arg_signature, ";\n");
+}
+
+public
Text_t compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_t *call_args) {
Table_t used_args = {};
Text_t code = EMPTY_TEXT;