aboutsummaryrefslogtreecommitdiff
path: root/src/lower.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lower.c')
-rw-r--r--src/lower.c24
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