From 6385450ddba34bc28bd7492d126fd38cb3f86f36 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Mon, 12 Aug 2024 19:01:21 +0300 Subject: make id scope point to defining scope + Allows defers to refer to the correct scope, but might be a bit surprising since effectively all other nodes use the scope to refer to the containing scope rather than the defining scope. --- src/actualize.c | 14 +++++++------ src/ast.c | 1 - src/lower.c | 63 +++++++++++---------------------------------------------- 3 files changed, 20 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/actualize.c b/src/actualize.c index 602325a..66fcff9 100644 --- a/src/actualize.c +++ b/src/actualize.c @@ -1183,12 +1183,12 @@ static int actualize_block(struct act_state *state, block_defers(node) = clone_defers(state, defers); if (!block_defers(node)) { internal_error("failed cloning defers"); + clear_defers(state, defers); return -1; } - - clear_defers(state, defers); } + clear_defers(state, defers); return 0; } @@ -1197,7 +1197,6 @@ static int actualize_id(struct act_state *state, { UNUSED(state); assert(id && id->k == AST_ID); - id->scope = scope; /** @todo vars and procs kind of override eachother, i.e. * do_something(){..} @@ -1218,8 +1217,13 @@ static int actualize_id(struct act_state *state, return -1; } + /* set scope of use to scope of definition, this makes sure that when + * lower() calls scope_find_*() it gets the one we just found and not a + * possible shadow. This is a pretty major hack, it might be more clean + * to add a ->def field into the AST or something but this works for + * now. */ + id->scope = decl->scope; set_type(id, decl->t); - decl->uses++; return 0; } @@ -2230,7 +2234,6 @@ static int actualize_dot(struct act_state *state, id); if (exists) { assert(exists->t); - exists->uses++; set_type(node, exists->t); return 0; } @@ -2415,7 +2418,6 @@ 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/ast.c b/src/ast.c index c36d7a7..aeb8c69 100644 --- a/src/ast.c +++ b/src/ast.c @@ -396,7 +396,6 @@ struct ast *clone_ast(struct ast *n) assert(n->k); struct ast *new = create_empty_ast(); new->scope = n->scope; - new->uses = n->uses; new->loc = n->loc; new->k = n->k; new->v = n->v; diff --git a/src/lower.c b/src/lower.c index c239836..d0dd161 100644 --- a/src/lower.c +++ b/src/lower.c @@ -96,19 +96,6 @@ static void pop_loop(struct lower_state *s) #define label_peek(v) \ vect_back(char *, v) -static int64_t retval_width(struct retval r) -{ - switch (r.kind) { - case REG_I27: return 3; - case REG_I9: return 1; - case CONST_I9: return 1; - case CONST_I27: return 3; - default: abort(); - } - - return 0; -} - static const char *retval_kind_str(enum retval_kind kind) { switch (kind) { @@ -250,34 +237,6 @@ static void output_ast_id(struct ast *id) free(name); } -static int lower_global_var(struct ast *n) -{ - /* trivial types are reasonably easy, but stuff like compound types need - * a lot of work */ - struct type *type = var_type(n); - if (is_primitive(type)) { - semantic_error(n->scope->fctx, n, - "only primitive globals currently implemented"); - return -1; - } - - struct ast *init = var_init(n); - if (init->k != AST_CONST_INT) { - semantic_error(n->scope->fctx, n, - "only constant expressions currently implemented"); - return -1; - } - - output_ast_id(n); - printf(" = "); - - /* hmm, this might be useful elsewhere as well */ - char *t = is_small_type(type) ? "i9" : "i27"; - printf("%s %lli", t, int_val(init)); - printf(";\n"); - return 0; -} - static int lower_simple_param(struct lower_state *s, struct ast *p) { UNUSED(s); @@ -533,6 +492,10 @@ static int lower_id(struct lower_state *s, struct ast *id, /* this likely isn't enough and we need to add the & to most things we * want to take the address of */ if (type->k == TYPE_CALLABLE) { + /** @todo global variables? The parser currently doesn't support + * them but if we did have them we might have to run + * file_scope_find_symbol and add it to the state as we run into + * them */ struct ast *def = file_scope_find_proc(id->scope, id->s); assert(def); @@ -567,13 +530,14 @@ static int lower_struct_return(struct lower_state *s, struct ast *n, size_t o, static int lower_deferred(struct lower_state *s, struct ast *d) { - struct ast *t = reverse_ast_list(d); - foreach_node(n, t) { - if (lower_statement(s, n)) - return -1; - } + if (!d) + return 0; - return 0; + /* we want to output the top of the stack first and work our way down */ + if (lower_deferred(s, d->n)) + return -1; + + return lower_statement(s, d); } static int lower_return(struct lower_state *s, struct ast *r, @@ -1230,7 +1194,7 @@ static int lower_label(struct lower_state *s, struct ast *n) assert(n->k == AST_LABEL); char *out = mangle_scope(n, n->scope); - printf("-> %s\n", out); + printf("%s:\n", out); free(out); return 0; } @@ -1265,9 +1229,6 @@ static int lower_statement(struct lower_state *s, struct ast *n) static int lower_proc(struct ast *n) { assert(n->k == AST_PROC_DEF); - /* nobody uses the proc, so no need to do anything */ - if (n->uses == 0 && !ast_flags(n, AST_FLAG_NOMANGLE)) - return 0; /* we're just a prototype, no need to do anything */ if (!proc_body(n)) -- cgit v1.3