diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-13 00:18:36 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-13 00:18:36 -0400 |
commit | 9cd746f1a358ea626a0748f1d3825397316afb5e (patch) | |
tree | 2c796ef8c987843397d5003aea97490f93fdae4a | |
parent | 9dc3dea276c2cc045a77dfbf2734fe85207c3452 (diff) |
improved FnExpr structure
-rw-r--r-- | cgen.c | 46 | ||||
-rw-r--r-- | decls_cgen.c | 14 | ||||
-rw-r--r-- | parse.c | 7 | ||||
-rw-r--r-- | types.c | 7 | ||||
-rw-r--r-- | types.h | 18 |
5 files changed, 43 insertions, 49 deletions
@@ -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); } } @@ -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; @@ -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 */ @@ -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; |