summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-13 00:18:36 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-13 00:18:36 -0400
commit9cd746f1a358ea626a0748f1d3825397316afb5e (patch)
tree2c796ef8c987843397d5003aea97490f93fdae4a
parent9dc3dea276c2cc045a77dfbf2734fe85207c3452 (diff)
improved FnExpr structure
-rw-r--r--cgen.c46
-rw-r--r--decls_cgen.c14
-rw-r--r--parse.c7
-rw-r--r--types.c7
-rw-r--r--types.h18
5 files changed, 43 insertions, 49 deletions
diff --git a/cgen.c b/cgen.c
index 2bb53bf..4351466 100644
--- a/cgen.c
+++ b/cgen.c
@@ -122,9 +122,9 @@ static void cgen_defs_decl(CGenerator *g, Declaration *d);
case EXPR_FN: { \
FnExpr *fn = e->fn; \
if (fn_has_instances(fn)) { \
- Instance **data = fn->instances.data; \
- for (U64 i = 0; i < fn->instances.cap; ++i) { \
- if (fn->instances.occupied[i]) { \
+ Instance **data = fn->instances->data; \
+ for (U64 i = 0; i < fn->instances->cap; ++i) { \
+ if (fn->instances->occupied[i]) { \
cgen_recurse_subexprs_fn_simple(((*data)->fn), decl_f, block_f); \
} \
++data; \
@@ -432,15 +432,14 @@ static bool cgen_should_gen_fn(FnExpr *f) {
}
}
-static void cgen_full_fn_name(CGenerator *g, FnExpr *f, U64 instance) {
+static void cgen_full_fn_name(CGenerator *g, FnExpr *f) {
cgen_fn_name(g, f);
- if (instance) {
- cgen_fn_instance_number(g, instance);
+ if (f->instance_id) {
+ cgen_fn_instance_number(g, f->instance_id);
}
}
-static void cgen_fn_params(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) {
- (void)instance; /* not needed atm */
+static void cgen_fn_params(CGenerator *g, FnExpr *f, U64 which_are_const) {
bool out_param = cgen_uses_ptr(&f->ret_type);
cgen_write(g, "(");
int semi_const_idx = 0;
@@ -527,8 +526,8 @@ static inline void cgen_arg(CGenerator *g, Expression *arg) {
}
}
-/* unless f has const/semi-const args, instance and which_are_const can be set to 0 */
-static void cgen_fn_header(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) {
+/* unless f has const/semi-const args, which_are_const can be set to 0 */
+static void cgen_fn_header(CGenerator *g, FnExpr *f, U64 which_are_const) {
assert(!(f->flags & FN_EXPR_FOREIGN));
bool out_param = cgen_uses_ptr(&f->ret_type);
@@ -541,8 +540,8 @@ static void cgen_fn_header(CGenerator *g, FnExpr *f, U64 instance, U64 which_are
cgen_type_pre(g, &f->ret_type);
cgen_write(g, " ");
}
- cgen_full_fn_name(g, f, instance);
- cgen_fn_params(g, f, instance, which_are_const);
+ cgen_full_fn_name(g, f);
+ cgen_fn_params(g, f, which_are_const);
if (!out_param) {
cgen_type_post(g, &f->ret_type);
}
@@ -690,7 +689,7 @@ static void cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
cgen_expr(g, to->call.fn);
if (to->call.instance)
- cgen_fn_instance_number(g, to->call.instance->c.id);
+ cgen_fn_instance_number(g, to->call.instance->fn->instance_id);
cgen_write(g, "(");
bool any_args = false;
i = 0;
@@ -1039,7 +1038,7 @@ static void cgen_expr_pre(CGenerator *g, Expression *e) {
}
cgen_expr(g, e->call.fn);
if (e->call.instance) {
- cgen_fn_instance_number(g, e->call.instance->c.id);
+ cgen_fn_instance_number(g, e->call.instance->fn->instance_id);
}
cgen_write(g, "(");
bool any_args = false;
@@ -1068,7 +1067,7 @@ static void cgen_expr_pre(CGenerator *g, Expression *e) {
cgen_write(g, ";"); cgen_nl(g);
cgen_expr(g, e->call.fn);
if (e->call.instance) {
- cgen_fn_instance_number(g, e->call.instance->c.id);
+ cgen_fn_instance_number(g, e->call.instance->fn->instance_id);
}
cgen_write(g, "(");
bool any_args = false;
@@ -1452,7 +1451,7 @@ static void cgen_expr(CGenerator *g, Expression *e) {
cgen_write(g, "(");
cgen_expr(g, e->call.fn);
if (e->call.instance) {
- cgen_fn_instance_number(g, e->call.instance->c.id);
+ cgen_fn_instance_number(g, e->call.instance->fn->instance_id);
}
cgen_write(g, "(");
bool first_arg = true;
@@ -1608,8 +1607,11 @@ static void cgen_zero_value(CGenerator *g, Type *t) {
}
}
-/* pass 0 for instance and NULL for compile_time_args if there are no compile time arguments. */
-static void cgen_fn(CGenerator *g, FnExpr *f, U64 instance, Value *compile_time_args) {
+/* pass NULL for compile_time_args if there are no compile time arguments.
+compile_time_args is needed because we can't determine which_are_const
+from just f.
+ */
+static void cgen_fn(CGenerator *g, FnExpr *f, Value *compile_time_args) {
if (f->flags & FN_EXPR_FOREIGN)
return; /* handled by decls_cgen */
/* see also cgen_defs_expr */
@@ -1617,7 +1619,7 @@ static void cgen_fn(CGenerator *g, FnExpr *f, U64 instance, Value *compile_time_
U64 which_are_const = compile_time_args ? compile_time_args->u64 : 0;
if (!cgen_should_gen_fn(f))
return;
- cgen_fn_header(g, f, instance, which_are_const);
+ cgen_fn_header(g, f, which_are_const);
g->fn = f;
cgen_write(g, " {");
cgen_nl(g);
@@ -1982,17 +1984,17 @@ static void cgen_stmt(CGenerator *g, Statement *s) {
static void cgen_defs_fn(CGenerator *g, FnExpr *f) {
if (fn_has_instances(f)) {
- HashTable *instances = &f->instances;
+ HashTable *instances = f->instances;
/* generate each instance */
Instance **is = instances->data;
for (U64 i = 0; i < instances->cap; ++i) {
if (instances->occupied[i]) {
/* generate this instance */
- cgen_fn(g, is[i]->fn, is[i]->c.id, is[i]->val.tuple);
+ cgen_fn(g, is[i]->fn, is[i]->val.tuple);
}
}
} else {
- cgen_fn(g, f, 0, NULL);
+ cgen_fn(g, f, NULL);
}
}
diff --git a/decls_cgen.c b/decls_cgen.c
index 86c4cf9..8ebf051 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -37,9 +37,9 @@ static void cgen_decls_type(CGenerator *g, Type *type) {
cgen_recurse_subtypes(cgen_decls_type, g, type);
}
-static void cgen_single_fn_decl(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) {
+static void cgen_single_fn_decl(CGenerator *g, FnExpr *f, U64 which_are_const) {
if (cgen_should_gen_fn(f)) {
- cgen_fn_header(g, f, instance, which_are_const);
+ cgen_fn_header(g, f, which_are_const);
cgen_write(g, ";");
cgen_nl(g);
}
@@ -47,13 +47,13 @@ static void cgen_single_fn_decl(CGenerator *g, FnExpr *f, U64 instance, U64 whic
static void cgen_decls_fn_instances(CGenerator *g, FnExpr *f) {
- Instance **data = f->instances.data;
- for (U64 i = 0; i < f->instances.cap; ++i) {
- if (f->instances.occupied[i]) {
+ Instance **data = f->instances->data;
+ for (U64 i = 0; i < f->instances->cap; ++i) {
+ if (f->instances->occupied[i]) {
if (cgen_should_gen_fn((*data)->fn)) {
(*data)->fn->c.name = f->c.name;
(*data)->fn->c.id = f->c.id;
- cgen_single_fn_decl(g, (*data)->fn, (*data)->c.id, (*data)->val.tuple[0].u64);
+ cgen_single_fn_decl(g, (*data)->fn, (*data)->val.tuple[0].u64);
cgen_write(g, ";");
cgen_nl(g);
}
@@ -170,7 +170,7 @@ static void cgen_fn_decl(CGenerator *g, FnExpr *f, Type *t) {
if (fn_has_instances(f)) {
cgen_decls_fn_instances(g, f);
} else {
- cgen_single_fn_decl(g, f, 0, 0);
+ cgen_single_fn_decl(g, f, 0);
}
}
diff --git a/parse.c b/parse.c
index b011ed0..f7cdca2 100644
--- a/parse.c
+++ b/parse.c
@@ -950,12 +950,9 @@ static Status parse_decl_list(Parser *p, Declaration **decls, DeclEndKind decl_e
static Status parse_fn_expr(Parser *p, FnExpr *f) {
Tokenizer *t = p->tokr;
+ f->instance_id = 0;
f->ret_decls = NULL;
- {
- /* help types.c */
- HashTable z = {0};
- f->instances = z;
- }
+ f->instances = NULL;
/* only called when token is fn */
assert(token_is_kw(t->token, KW_FN));
++t->token;
diff --git a/types.c b/types.c
index 7b8207f..506dea0 100644
--- a/types.c
+++ b/types.c
@@ -1466,8 +1466,7 @@ static Status types_expr(Typer *tr, Expression *e) {
return false;
}
if (fn_has_any_const_params(e->fn) || fn_type_has_varargs(&e->type.fn)) {
- HashTable z = {0};
- e->fn->instances = z;
+ e->fn->instances = typer_calloc(tr, 1, sizeof *e->fn->instances);
} else {
if (!types_fn(tr, e->fn, &e->type, NULL)) {
return false;
@@ -2444,14 +2443,14 @@ static Status types_expr(Typer *tr, Expression *e) {
}
}
bool instance_already_exists;
- c->instance = instance_table_adda(tr->allocr, &original_fn->instances, table_index, &table_index_type, &instance_already_exists);
+ c->instance = instance_table_adda(tr->allocr, original_fn->instances, table_index, &table_index_type, &instance_already_exists);
if (instance_already_exists) {
arr_cleara(&table_index_type.tuple, tr->allocr);
arr_cleara(&table_index.tuple, tr->allocr);
} else {
c->instance->fn = fn_copy;
/* fix parameter and return types (they were kind of problematic before, because we didn't know about the instance) */
- c->instance->c.id = original_fn->instances.n; /* let's help cgen out and assign an ID to this */
+ fn_copy->instance_id = 1+original_fn->instances->n; /* let's help cgen out and assign a non-zero ID to this */
/* type this instance */
/* if anything happens, make sure we let the user know that this happened while generating a fn */
diff --git a/types.h b/types.h
index 9d55b84..5540d16 100644
--- a/types.h
+++ b/types.h
@@ -684,6 +684,7 @@ typedef struct FnExpr {
struct {
struct Declaration *params; /* declarations of the parameters to this function */
struct Declaration *ret_decls; /* array of decls, if this has named return values. otherwise, NULL */
+ U64 instance_id;
Type ret_type;
Block body;
};
@@ -701,11 +702,11 @@ typedef struct FnExpr {
void (*fn_ptr)();
} foreign;
};
- HashTable instances; /* for fns with constant parameters. the key is a tuple where
- the first element is a u64 value whose ith bit (1<<i) is 1
- if the ith semi-constant parameter is constant.
- cgen relies on this being here even for foreign fns.
- */
+ HashTable *instances; /* for fns with constant parameters. the key is a tuple where
+ the first element is a u64 value whose ith bit (1<<i) is 1
+ if the ith semi-constant parameter is constant.
+ cgen relies on this being here even for foreign fns.
+ */
struct {
/* if name = NULL, this is an anonymous function, and id will be the ID of the fn. */
Identifier name;
@@ -717,12 +718,7 @@ typedef struct FnExpr {
typedef struct Instance {
Value val; /* key into hash table */
union {
- struct {
- FnExpr *fn; /* the typed function */
- struct {
- U64 id;
- } c;
- };
+ FnExpr *fn; /* the typed function */
StructDef struc;
};
} Instance;