summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base_cgen.c47
-rw-r--r--cgen.c4
-rw-r--r--out.c3
-rw-r--r--test.toc5
-rw-r--r--util/arr.c2
5 files changed, 47 insertions, 14 deletions
diff --git a/base_cgen.c b/base_cgen.c
index c2aa9da..e59e84c 100644
--- a/base_cgen.c
+++ b/base_cgen.c
@@ -115,15 +115,45 @@ static const char *builtin_type_to_str(BuiltinType b) {
return NULL;
}
-/* NOTE: this will eventually be split into two functions when functions/arrays are added */
-static bool cgen_type(CGenerator *g, Type *t) {
+static bool cgen_type_pre(CGenerator *g, Type *t) {
switch (t->kind) {
case TYPE_VOID:
- cgen_write(g, "void");
+ cgen_write(g, "void ");
break;
case TYPE_BUILTIN:
- cgen_write(g, "%s", builtin_type_to_str(t->builtin));
+ cgen_write(g, "%s ", builtin_type_to_str(t->builtin));
break;
+ case TYPE_FN: {
+ Type *types = t->fn.types.data;
+ Type *ret_type = &types[0];
+ if (!cgen_type_pre(g, ret_type)) return false;
+ cgen_write(g, "(*");
+ } break;
+ }
+ return true;
+}
+
+static bool cgen_type_post(CGenerator *g, Type *t) {
+ switch (t->kind) {
+ case TYPE_VOID:
+ case TYPE_BUILTIN:
+ break;
+ case TYPE_FN: {
+ Type *types = t->fn.types.data;
+ Type *ret_type = &types[0];
+ Type *param_types = types + 1;
+ assert(t->fn.types.len > 0);
+ size_t nparams = t->fn.types.len-1;
+ cgen_write(g, ")(");
+ for (size_t i = 0; i < nparams; i++) {
+ if (!cgen_type_pre(g, &param_types[i])) return true;
+ if (!cgen_type_post(g, &param_types[i])) return true;
+ cgen_write(g, ",");
+ cgen_write_space(g);
+ }
+ cgen_write(g, ")");
+ if (!cgen_type_post(g, ret_type)) return false;
+ } break;
}
return true;
}
@@ -148,19 +178,20 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f) {
if (!f->name || g->block != NULL) {
cgen_write(g, "static "); /* anonymous functions only exist in this translation unit */
}
- if (!cgen_type(g, &f->ret_type)) return false;
- cgen_write(g, " ");
+ if (!cgen_type_pre(g, &f->ret_type)) return false;
cgen_fn_name(g, f);
+ if (!cgen_type_post(g, &f->ret_type)) return false;
cgen_write(g, "(");
arr_foreach(&f->params, Param, p) {
if (p != f->params.data) {
cgen_write(g, ",");
cgen_write_space(g);
}
- if (!cgen_type(g, &p->type))
+ if (!cgen_type_pre(g, &p->type))
return false;
- cgen_write(g, " ");
cgen_ident(g, p->name);
+ if (!cgen_type_post(g, &p->type))
+ return false;
}
cgen_write(g, ")");
g->writing_to = writing_to_before;
diff --git a/cgen.c b/cgen.c
index 152baf6..d0bf0a6 100644
--- a/cgen.c
+++ b/cgen.c
@@ -86,9 +86,9 @@ static bool cgen_fn(CGenerator *g, FnExpr *f) {
static bool cgen_decl(CGenerator *g, Declaration *d) {
arr_foreach(&d->idents, Identifier, ident) {
- cgen_type(g, &d->type);
- cgen_write(g, " ");
+ cgen_type_pre(g, &d->type);
cgen_ident(g, *ident);
+ cgen_type_post(g, &d->type);
cgen_write_space(g);
cgen_write(g, "=");
cgen_write_space(g);
diff --git a/out.c b/out.c
index f839a20..767e654 100644
--- a/out.c
+++ b/out.c
@@ -2,7 +2,8 @@
/* toc */
void main__(void) {
-printf ("\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0a\x00");
+ int64_t foo = 3;
+ void (*bar)() = 0;
}
int main(void) {
diff --git a/test.toc b/test.toc
index a7abd42..d437110 100644
--- a/test.toc
+++ b/test.toc
@@ -1,3 +1,4 @@
-main @ fn (int) fn(fn() fn()) = fn() {
- printf("Hello, World!\n");
+main @= fn() {
+ foo : int = 3;
+ bar : fn() = 0;
}; \ No newline at end of file
diff --git a/util/arr.c b/util/arr.c
index f8da701..54d05d6 100644
--- a/util/arr.c
+++ b/util/arr.c
@@ -21,7 +21,7 @@ static void arr_reserve(Array *arr, size_t n) {
static void *arr_add(Array *arr) {
if (arr->len >= arr->cap) {
- arr_reserve(arr, (arr->cap + 2) * 2);
+ arr_reserve(arr, (arr->cap + 1) * 2);
}
arr->len++;
arr->last = (char*)arr->last + arr->item_sz;