aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--TODO7
-rw-r--r--include/ek/ast.h2
-rw-r--r--src/actualize.c14
-rw-r--r--src/ast.c1
-rw-r--r--src/lower.c63
5 files changed, 27 insertions, 60 deletions
diff --git a/TODO b/TODO
index 4bc3d86..4e0dd66 100644
--- a/TODO
+++ b/TODO
@@ -43,3 +43,10 @@ i27 or something?
us. Should it also check that no abstract data types are used in the final
lowering? Which would mean that even the lowering is allowed to fail, and not
just the actualization phase.
+
++ continue/break could probably fairly easily use labels as well, just check
+that the following AST node is a loop and treat is as the name for that loop.
+Then continue just goes to the bottom of the loop and break goes out of the
+loop, pretty much what we're currently doing but just with the top loop
+in the stack. We'd probably just have to check the loop stack in lower.c,
+should be fairly straightforward?
diff --git a/include/ek/ast.h b/include/ek/ast.h
index 642b561..3d839ad 100644
--- a/include/ek/ast.h
+++ b/include/ek/ast.h
@@ -237,8 +237,6 @@ struct ast {
enum ast_flags f;
struct ast *n;
- long long uses;
-
struct src_loc loc;
struct scope *scope;
};
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))