From 5a5e3e2de5839bcaf36a5eb73354f33f86e46f45 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Mon, 15 Apr 2024 17:50:41 +0300 Subject: fix inits --- src/actualize.c | 19 ++++++++-------- src/lower.c | 70 +++++++++++++++++++++++++++++++++------------------------ src/parser.y | 5 +---- 3 files changed, 51 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/actualize.c b/src/actualize.c index 7bb4e55..0c9d09e 100644 --- a/src/actualize.c +++ b/src/actualize.c @@ -2167,6 +2167,7 @@ static int actualize_dot(struct act_state *state, id); if (exists) { assert(exists->t); + exists->uses++; set_type(node, exists->t); return 0; } @@ -2234,18 +2235,15 @@ static int actualize_init(struct act_state *state, struct init_helper arg = vect_at(struct init_helper, init_args, ai); - struct init_helper mem = {0}; - foreach_vec(mi, struct_members) { - mem = vect_at(struct init_helper, struct_members, mi); - if (same_id(mem.id, arg.id)) - goto ok; - } + struct init_helper mem = vect_at(struct init_helper, struct_members, + ai); - semantic_error(scope->fctx, arg.n, "unknown argument %s", - arg.id); - goto err; + /* not the best error message but works for now */ + if (!same_id(arg.id, mem.id)) { + semantic_error(scope->fctx, node, "malformed init"); + goto err; + } -ok: if (!types_match(arg.n->t, mem.n->t)) { type_mismatch(scope, "init type mismatch", arg.n, arg.n->t, mem.n->t); @@ -2344,6 +2342,7 @@ static int actualize_fetch(struct act_state *state, struct scope *scope, return -1; } + member->uses++; set_type(fetch, member->t); return 0; } diff --git a/src/lower.c b/src/lower.c index 1ce91a4..58ffe7a 100644 --- a/src/lower.c +++ b/src/lower.c @@ -173,40 +173,19 @@ char *build_str(const char *fmt, ...) { return buf; } -static size_t get_scope_number(struct ast *id) +static char *mangle_scope(struct ast *id, struct scope *s) { - /** @todo this mirrors what's in actualize.c:actualize_id, same comments - * apply */ - struct ast *def = file_scope_find_var(id->scope, id->s); - if (def) - return def->scope->number; - - def = file_scope_find_proc(id->scope, id->s); - if (def) - return def->scope->number; - - return 0; + return build_str("%s_s%zi", id->s, s->number); } -static char *mangle_idx(struct ast *id, size_t idx) +static char *mangle(struct ast *id) { - assert(id->scope); - assert(id->s); - char *name = id->s; - /* oh wait, I need to do a variable lookup on the ID, not use the ID's - * scope number, duh */ struct ast *def = file_scope_find_symbol(id->scope, name); if (ast_flags(def, AST_FLAG_NOMANGLE)) return strdup(name); - size_t number = get_scope_number(def); - return build_str("%s_s%zif%zi", name, number, idx); -} - -static char *mangle(struct ast *id) -{ - return mangle_idx(id, 0); + return mangle_scope(id, def->scope); } typedef int (*visit_struct_t)(struct lower_state *s, struct ast *n, size_t o, @@ -869,7 +848,8 @@ static void lower_struct_retval(struct lower_state *s, struct type *rtype, static void lower_simple_retval(struct lower_state *s, struct type *rtype, struct retval *retval) { - char *name = build_str("(rv_%zd);\n", s->uniq++); + char *name = build_str("rv_%zd", s->uniq++); + printf("(%s);\n", name); *retval = build_retval(is_small_type(rtype) ? REG_I9 : REG_I27, name); } @@ -980,8 +960,17 @@ static int lower_fetch(struct lower_state *s, struct ast *f, * specific function from a struct */ assert(f->k == AST_FETCH); assert(f->t->k == TYPE_CALLABLE); - char *name = mangle(f); - *retval = build_retval(REG_I27, name); + + struct ast *def = (fetch_type(f))->d; + assert(def); + + struct ast *proc = scope_find_proc(def->scope, fetch_id(f)); + assert(proc); + + char *name = mangle(proc); + char *fetch = build_str("&%s", name); + *retval = build_retval(REG_I27, fetch); + free(name); return 0; } @@ -1178,6 +1167,9 @@ static int lower_proc(struct ast *n) if (!proc_body(n)) return 0; + if (ast_flags(n, AST_FLAG_LOWERED)) + return 0; + struct lower_state state = create_state(); /* name */ @@ -1213,6 +1205,21 @@ static int lower_proc(struct ast *n) printf("}\n"); destroy_state(&state); + ast_set_flags(n, AST_FLAG_LOWERED); + return 0; +} + +static int lower_struct(struct ast *s) +{ + if (ast_flags(s, AST_FLAG_LOWERED)) + return 0; + + foreach_node(n, struct_body(s)) { + if (n->k == AST_PROC_DEF && lower_proc(n)) + return -1; + } + + ast_set_flags(s, AST_FLAG_LOWERED); return 0; } @@ -1234,8 +1241,13 @@ int lower(struct scope *root) struct ast *node = p->node; if (node->k == AST_PROC_DEF && lower_proc(p->node)) return -1; + } - /** @todo variables, structs, etc. */ + foreach_visible(p, root->types) { + assert(p->node); + struct ast *node = p->node; + if (node->k == AST_STRUCT_DEF && lower_struct(p->node)) + return -1; } return 0; diff --git a/src/parser.y b/src/parser.y index b120e1b..8cb51cb 100644 --- a/src/parser.y +++ b/src/parser.y @@ -421,10 +421,7 @@ while : "while" expr body { $$ = gen_while($2, $3, src_loc(@$)); } do_while - : "do" body "while" expr ";" { - $$ = gen_while($2, $4, src_loc(@$)); - ast_set_flags($$, AST_FLAG_DELAYED); - } + : "do" body "while" expr ";" { $$ = gen_do_while($2, $4, src_loc(@$)); } goto : "goto" ID { $$ = gen_goto($[ID], NULL, src_loc(@$)); } -- cgit v1.3