diff options
Diffstat (limited to 'src/lower.c')
-rw-r--r-- | src/lower.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/lower.c b/src/lower.c index 02efb1b..0a6c07d 100644 --- a/src/lower.c +++ b/src/lower.c @@ -4,13 +4,24 @@ #include <posthaste/lower.h> #include <posthaste/scope.h> +#include <posthaste/utils.h> -#define UNUSED(x) (void)x - +/* globals are kind of ugly and could/should be made into parameters (or + * potentially even members of some all-encompassing state) but this works for + * this simple implementation, implementing the change would mosty just require + * changing function signatures which is boring and I don't want to do it right + * now */ static struct vec fns = {0}; -/* zero is unintialized, global 1 reserved as null, so skip two first globals */ + +/* locs use global 0 to mean unitialized and global 1 is reserved as null_loc(), + * so skip two first globals */ static size_t globals = 2; +size_t num_globals() +{ + return globals; +} + static void lower(struct fn *f, struct ast *n); static void lower_list(struct fn *f, struct ast *l) { @@ -698,6 +709,8 @@ int lower_ast(struct ast *tree) { fns = vec_create(sizeof(struct fn)); + /* make body of file out to be a kind of main function, it will always + * be at index 0 */ struct fn main = {.name = "main", .idx = 0, .sp = 0, @@ -705,6 +718,7 @@ int lower_ast(struct ast *tree) vect_append(struct fn, fns, &main); + /* first create function nodes in fns to assign each procedure an index */ foreach_node(n, tree) { switch (n->k) { case AST_PROC_DEF: add_proc(n); break; @@ -714,6 +728,9 @@ int lower_ast(struct ast *tree) } struct fn *f = &vect_at(struct fn, fns, 0); + /* we can't treat file scope as a regular function, as all variable + * definitions must be made global, so we have a little bit of + * duplicated code here but that's fine */ foreach_node(n, tree) { switch (n->k) { case AST_VAR_DEF: lower_global_var(f, n); break; @@ -723,6 +740,7 @@ int lower_ast(struct ast *tree) } } + /* append a return without value so we know when to stop interpretation */ output_insn(f, STOP, null_loc(), null_loc(), null_loc(), 0); #ifdef DEBUG |