aboutsummaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-03-24 15:06:59 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-03-24 15:06:59 -0400
commit5157988efa388f956d3ea8204e496baf6db11b52 (patch)
treeb1cc89f2244d21de4811a3467b4bc15f795b7019 /compile.c
parenta29d2ed6d1735d4f12dd250900785db4271edeca (diff)
Implement 'extern' functionality
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/compile.c b/compile.c
index 4c4b322d..75943004 100644
--- a/compile.c
+++ b/compile.c
@@ -58,7 +58,6 @@ static bool promote(env_t *env, CORD *code, type_t *actual, type_t *needed)
return false;
}
-
CORD compile_declaration(env_t *env, type_t *t, const char *name)
{
if (t->tag == FunctionType) {
@@ -735,6 +734,25 @@ CORD compile_statement(env_t *env, ast_t *ast)
return compile_statement(env, loop);
}
}
+ case Extern: {
+ auto ext = Match(ast, Extern);
+ type_t *t = parse_type_ast(env, ext->type);
+ CORD decl;
+ if (t->tag == ClosureType) {
+ t = Match(t, ClosureType)->fn;
+ auto fn = Match(t, FunctionType);
+ decl = CORD_all(compile_type(env, fn->ret), " ", ext->name, "(");
+ for (arg_t *arg = fn->args; arg; arg = arg->next) {
+ decl = CORD_all(decl, compile_type(env, arg->type));
+ if (arg->next) decl = CORD_cat(decl, ", ");
+ }
+ decl = CORD_cat(decl, ")");
+ } else {
+ decl = compile_declaration(env, t, ext->name);
+ }
+ env->code->fndefs = CORD_all(env->code->fndefs, "extern ", decl, ";\n");
+ return CORD_EMPTY;
+ }
case InlineCCode: return Match(ast, InlineCCode)->code;
default:
return CORD_asprintf("(void)%r;", compile(env, ast));