aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/execute.c9
-rw-r--r--src/lower.c53
2 files changed, 39 insertions, 23 deletions
diff --git a/src/execute.c b/src/execute.c
index cfa64fb..5f99dcd 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -6,5 +6,12 @@
void execute()
{
struct fn *f = find_fn(0);
- ejit_run_func(f->f, 0, NULL);
+ struct vec globals = vec_create(sizeof(int64_t));
+ vec_reserve(&globals, num_globals());
+ struct ejit_arg args[1] = {
+ EJIT_ARG_POINTER(globals.buf)
+ };
+
+ ejit_run_func(f->f, 1, args);
+ vec_destroy(&globals);
}
diff --git a/src/lower.c b/src/lower.c
index f3c6672..15ce6d1 100644
--- a/src/lower.c
+++ b/src/lower.c
@@ -93,7 +93,7 @@ static void put(struct fn *f, struct loc l)
return;
/* something like this I think, should still check the type width */
- ejit_stxi_64(f->f, EJIT_GPR(l.s), EJIT_GPR(0), l.g);
+ ejit_stxi_64(f->f, EJIT_GPR(l.s), EJIT_GPR(0), l.g * sizeof(int64_t));
}
static void get(struct fn *f, struct loc l)
@@ -102,7 +102,7 @@ static void get(struct fn *f, struct loc l)
if (l.g <= 1)
return;
- ejit_ldxi_u64(f->f, EJIT_GPR(l.s), EJIT_GPR(0), l.g);
+ ejit_ldxi_u64(f->f, EJIT_GPR(l.s), EJIT_GPR(0), l.g * sizeof(int64_t));
}
static void lower_var(struct fn *f, struct ast *n)
@@ -312,6 +312,30 @@ static void lower_dot_assign(struct fn *f, struct ast *n)
put(f, n->l);
}
+static void get_id_loc(struct fn *f, struct ast *n)
+{
+ assert(n->k == AST_ID);
+ struct ast *exists = file_scope_find(n->scope, n->id);
+ assert(exists);
+
+ /* using ast nodes/scope lookup as convenient way to store variable ->
+ * location mappings */
+ n->l = exists->l;
+ assert(n->l.g != 1);
+ if (n->l.g > 1) {
+ /* global variables should get loaded to the stack for handling */
+ n->l.s = f->sp;
+ }
+}
+
+static void lower_id(struct fn *f, struct ast *n)
+{
+ /* first calculate location */
+ get_id_loc(f, n);
+ /* then value at location */
+ get(f, n->l);
+}
+
static void lower_assign(struct fn *f, struct ast *n)
{
struct ast *l = assign_l(n);
@@ -321,7 +345,9 @@ static void lower_assign(struct fn *f, struct ast *n)
struct ast *r = assign_r(n);
lower(f, r);
- lower(f, l);
+ /* get location for variable, at this point we should be certain that
+ * we're dealing with a simple variable */
+ get_id_loc(f, l);
ejit_movr(f->f, reg(l), reg(r));
/* maybe store possible global value to global array */
put(f, l->l);
@@ -329,23 +355,6 @@ static void lower_assign(struct fn *f, struct ast *n)
n->l = null_loc();
}
-static void lower_id(struct fn *f, struct ast *n)
-{
- UNUSED(f);
- struct ast *exists = file_scope_find(n->scope, n->id);
- assert(exists);
-
- /* using ast nodes/scope lookup as convenient way to store variable ->
- * location mappings */
- n->l = exists->l;
- assert(n->l.g != 1);
- if (n->l.g > 1) {
- /* global variables should get loaded to the stack for handling */
- n->l.s = f->sp;
- }
-
- get(f, n->l);
-}
static void lower_return(struct fn *f, struct ast *n)
{
@@ -811,7 +820,7 @@ static void lower_until(struct fn *f, struct ast *n)
struct ast *cond = until_cond(n);
lower(f, cond);
- struct ejit_reloc r = ejit_bnei(f->f, reg(cond), 0);
+ struct ejit_reloc r = ejit_beqi(f->f, reg(cond), 0);
ejit_patch(f->f, r, l);
n->l = null_loc();
}
@@ -932,7 +941,7 @@ static void lower(struct fn *f, struct ast *n)
/* each ast node is assigned some location, regardless of if it actually
* needs one as a sanity check */
- assert(n->l.g);
+ assert(n->l.g || n->l.s);
}
static void lower_global_var(struct fn *f, struct ast *n) {