aboutsummaryrefslogtreecommitdiff
path: root/src/lower.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-08-12 19:00:42 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-08-12 19:06:03 +0300
commit29c6d398d22d633425177400f34ab508260f02bf (patch)
tree1f51a32536cab07243d1fe42aba38f86a856f3d4 /src/lower.c
parent2157fdbaca0b80e488c4f77ad5c0d04b051175cf (diff)
downloadek-29c6d398d22d633425177400f34ab508260f02bf.tar.gz
ek-29c6d398d22d633425177400f34ab508260f02bf.zip
implement defer for most control flow
+ continue/break
Diffstat (limited to 'src/lower.c')
-rw-r--r--src/lower.c73
1 files changed, 36 insertions, 37 deletions
diff --git a/src/lower.c b/src/lower.c
index 18d0576..c239836 100644
--- a/src/lower.c
+++ b/src/lower.c
@@ -32,6 +32,8 @@ struct lower_state {
struct vec dealloc;
size_t deallocs;
+
+ struct vec procs;
};
static struct lower_state create_state()
@@ -41,6 +43,8 @@ static struct lower_state create_state()
state.bottom = vec_create(sizeof(char *));
state.out = vec_create(sizeof(char *));
state.dealloc = vec_create(sizeof(char *));
+ state.procs = vec_create(sizeof(struct ast *));
+
state.deallocs = 0;
state.uniq = 0;
return state;
@@ -57,6 +61,13 @@ static void destroy_state(struct lower_state *state)
vec_destroy(&state->bottom);
vec_destroy(&state->out);
vec_destroy(&state->dealloc);
+ vec_destroy(&state->procs);
+}
+
+static void add_proc(struct lower_state *s, struct ast *proc)
+{
+ assert(proc->k == AST_PROC_DEF);
+ vec_append(&s->procs, &proc);
}
static void add_dealloc(struct lower_state *s, char *dealloc)
@@ -190,6 +201,8 @@ static char *mangle(struct ast *id)
return mangle_scope(id, def->scope);
}
+static int lower_proc(struct ast *n);
+
typedef int (*visit_struct_t)(struct lower_state *s, struct ast *n, size_t o,
void *d);
static ssize_t visit_struct(struct lower_state *s, struct ast *def, size_t base,
@@ -520,6 +533,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) {
+ struct ast *def = file_scope_find_proc(id->scope, id->s);
+ assert(def);
+
+ add_proc(s, def);
char *o = m;
m = build_str("&%s", m);
free(o);
@@ -994,6 +1011,8 @@ static int lower_fetch(struct lower_state *s, struct ast *f,
struct ast *proc = scope_find_proc(def->scope, fetch_id(f));
assert(proc);
+ add_proc(s, proc);
+
char *name = mangle(proc);
char *fetch = build_str("&%s", name);
*retval = build_retval(REG_I27, fetch);
@@ -1219,6 +1238,10 @@ static int lower_label(struct lower_state *s, struct ast *n)
static int lower_statement(struct lower_state *s, struct ast *n)
{
struct retval retval = retval_create();
+ if (ast_flags(n, AST_FLAG_LOWERED))
+ return 0;
+
+ ast_set_flags(n, AST_FLAG_LOWERED);
int ret = 0;
switch (n->k) {
@@ -1253,6 +1276,8 @@ static int lower_proc(struct ast *n)
if (ast_flags(n, AST_FLAG_LOWERED))
return 0;
+ ast_set_flags(n, AST_FLAG_LOWERED);
+
struct lower_state state = create_state();
/* name */
@@ -1287,51 +1312,25 @@ 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))
+ foreach_vec(pi, state.procs) {
+ struct ast *proc = vect_at(struct ast*, state.procs, pi);
+ if (lower_proc(proc)) {
+ destroy_state(&state);
return -1;
+ }
}
-
- ast_set_flags(s, AST_FLAG_LOWERED);
+ destroy_state(&state);
return 0;
}
int lower(struct scope *root)
{
- /* go through all child scopes but only do actual work on file-scope
- * includes are allowed inside procs etc to make something only locally
- * visible */
- for (struct scope *c = root->children; c; c = c->next) {
- if (lower(c))
- return -1;
- }
-
- if (!scope_flags(root, SCOPE_FILE))
- return 0;
-
- foreach_visible(p, root->symbols) {
- assert(p->node);
- struct ast *node = p->node;
- if (node->k == AST_PROC_DEF && lower_proc(p->node))
- return -1;
- }
-
- 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;
+ struct ast *main = file_scope_find_proc(root, "main");
+ if (!main) {
+ error("no main");
+ return -1;
}
- return 0;
+ return lower_proc(main);
}