summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-11-17 13:40:59 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-11-17 13:40:59 -0500
commit6aa688daf4fbd5afd664b7687bcccebcc4eccb98 (patch)
tree7f3aee9d89dcb2df1fd0feccd43ef8dbbdd78975
parent673b993783f99bf4317215cf967d0db534112823 (diff)
declarations of fns with const params
-rw-r--r--cgen.c20
-rw-r--r--decls_cgen.c45
-rw-r--r--main.c1
-rw-r--r--test.toc26
4 files changed, 48 insertions, 44 deletions
diff --git a/cgen.c b/cgen.c
index ccc84ae..8191d71 100644
--- a/cgen.c
+++ b/cgen.c
@@ -128,14 +128,6 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d);
break; \
}
-static inline bool fn_has_any_const_params(FnExpr *f) {
- arr_foreach(f->params, Declaration, param) {
- if (param->flags & DECL_IS_CONST)
- return true;
- }
- return false;
-}
-
static bool cgen_block_enter(CGenerator *g, Block *b) {
g->block = b;
Statement *stmts;
@@ -418,6 +410,10 @@ static inline void cgen_fn_name(CGenerator *g, FnExpr *f) {
}
}
+static inline void cgen_fn_instance_number(CGenerator *g, U64 instance) {
+ cgen_write(g, "%"PRIu64"_", instance);
+}
+
/* unless f has const/semi-const args, instance and which_are_const can be set to 0 */
static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) {
bool out_param = cgen_uses_ptr(&f->ret_type);
@@ -432,7 +428,7 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instanc
}
cgen_fn_name(g, f);
if (instance) {
- cgen_write(g, "%"PRIu64, instance);
+ cgen_fn_instance_number(g, instance);
}
if (!out_param) {
if (!cgen_type_post(g, &f->ret_type, where)) return false;
@@ -599,7 +595,7 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
/* e.g. a, b = fn_which_returns_tuple(); */
if (!cgen_expr(g, to->call.fn)) return false;
if (to->call.instance)
- cgen_write(g, "%"PRIu64, to->call.instance->c.id);
+ cgen_fn_instance_number(g, to->call.instance->c.id);
cgen_write(g, "(");
bool any_args = false;
Constness *constness = to->call.fn->type.fn.constness;
@@ -966,7 +962,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) {
cgen_write(g, ";"); cgen_nl(g);
if (!cgen_expr(g, e->call.fn)) return false;
if (e->call.instance) {
- cgen_write(g, "%"PRIu64, e->call.instance->c.id);
+ cgen_fn_instance_number(g, e->call.instance->c.id);
}
cgen_write(g, "(");
bool any_args = false;
@@ -1325,7 +1321,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
if (!cgen_expr(g, e->call.fn))
return false;
if (e->call.instance) {
- cgen_write(g, "%"PRIu64, e->call.instance->c.id);
+ cgen_fn_instance_number(g, e->call.instance->c.id);
}
cgen_write(g, "(");
bool first_arg = true;
diff --git a/decls_cgen.c b/decls_cgen.c
index 1df359d..ad547ee 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -2,23 +2,37 @@ static bool cgen_decls_stmt(CGenerator *g, Statement *s);
static bool cgen_decls_block(CGenerator *g, Block *b);
static bool cgen_decls_decl(CGenerator *g, Declaration *d);
+static bool cgen_decls_fn_instances(CGenerator *g, Expression *e) {
+ assert(e->kind == EXPR_FN);
+ FnExpr *f = &e->fn;
+ FnType *type = &e->type.fn;
+ assert(type->constness);
+ Instance **data = f->instances.data;
+ for (U64 i = 0; i < f->instances.cap; i++) {
+ if (f->instances.occupied[i]) {
+ if (!cgen_fn_header(g, f, e->where, (*data)->c.id, (*data)->val.tuple[0].u64))
+ return false;
+ cgen_write(g, ";");
+ cgen_nl(g);
+ }
+ data++;
+ }
+ return true;
+}
+
static bool cgen_decls_expr(CGenerator *g, Expression *e) {
cgen_recurse_subexprs(g, e, cgen_decls_expr, cgen_decls_block, cgen_decls_decl);
switch (e->kind) {
- case EXPR_FN:
- e->fn.c.name = NULL;
- if (!e->fn.c.id)
- e->fn.c.id = g->ident_counter++;
- bool any_const = false;
+ case EXPR_FN: {
+ FnExpr *f = &e->fn;
+ f->c.name = NULL;
+ if (!f->c.id)
+ f->c.id = g->ident_counter++;
FnType *fn_type = &e->type.fn;
if (fn_type->constness) {
- for (size_t i = 0; i < arr_len(fn_type->types)-1; i++) {
- if (fn_type->constness[i] == CONSTNESS_YES)
- any_const = true;
- }
- }
-
- if (!any_const) {
+ if (!cgen_decls_fn_instances(g, e))
+ return false;
+ } else {
fn_enter(&e->fn, 0);
if (!cgen_fn_header(g, &e->fn, e->where, 0, 0))
return false;
@@ -26,7 +40,7 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) {
cgen_nl(g);
fn_exit(&e->fn);
}
- break;
+ } break;
default:
break;
}
@@ -48,7 +62,10 @@ static bool cgen_decls_block(CGenerator *g, Block *b) {
static bool cgen_decls_decl(CGenerator *g, Declaration *d) {
if (cgen_fn_is_direct(g, d)) {
d->expr.fn.c.name = d->idents[0];
- if (!fn_has_any_const_params(&d->expr.fn)) {
+ if (d->expr.type.fn.constness) {
+ if (!cgen_decls_fn_instances(g, &d->expr))
+ return false;
+ } else {
fn_enter(&d->expr.fn, 0);
if (!cgen_fn_header(g, &d->expr.fn, d->where, 0, 0))
return false;
diff --git a/main.c b/main.c
index 3726f67..ff79e08 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,5 @@
/*
TODO:
-declarations of things with constant params
deal with typing functions with type parameters (we need to type every single instance)
struct parameters
diff --git a/test.toc b/test.toc
index fbc7272..d82f31e 100644
--- a/test.toc
+++ b/test.toc
@@ -7,23 +7,15 @@ puti @= fn(x: int) {
// ");
// };
-f@= fn(x : int, y :@ int) int {
- x+y
-};
+
+
main @= fn() {
- something := f(10, 20);
- puti(something);
- something2 @= f(10, 20);
- puti(something2);
- something3 := f(10, 10+10);
- puti(something3);
- something4 := f(10, 23);
- puti(something4);
- r := 20;
- something5 := f(10, r);
- puti(something5);
-g := f;
-something6 := g(10, r);
-puti(something6);
+ a, b := f(10, 20);
+ c, d := f(10, 10+10);
+ puti(a); puti(b);
+ puti(c); puti(d);
+f @= fn(a: int, x @ int) (int, int) {
+ x * a, x + a
+};
};