aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-08-12 19:01:21 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-08-12 19:06:03 +0300
commit6385450ddba34bc28bd7492d126fd38cb3f86f36 (patch)
tree25717c5d13e67207932bdc6393da7807720b2f6d /src
parent29c6d398d22d633425177400f34ab508260f02bf (diff)
downloadek-6385450ddba34bc28bd7492d126fd38cb3f86f36.tar.gz
ek-6385450ddba34bc28bd7492d126fd38cb3f86f36.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/actualize.c14
-rw-r--r--src/ast.c1
-rw-r--r--src/lower.c63
3 files changed, 20 insertions, 58 deletions
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))