aboutsummaryrefslogtreecommitdiff
path: root/src/lower.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lower.c')
-rw-r--r--src/lower.c70
1 files changed, 41 insertions, 29 deletions
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;