diff options
Diffstat (limited to 'src/lower.c')
-rw-r--r-- | src/lower.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/src/lower.c b/src/lower.c index f4ca28e..beb89c5 100644 --- a/src/lower.c +++ b/src/lower.c @@ -1,4 +1,5 @@ #include <stdlib.h> +#include <sys/mman.h> #include <posthaste/lower.h> #include <posthaste/scope.h> @@ -40,12 +41,18 @@ static struct loc null_loc() return build_global_loc(1); } -static void output_insn(struct fn *f, enum insn_kind k, struct loc o, struct loc i0, struct loc i1, int64_t v) +static void output_insn(struct fn *f, enum insn_kind k, struct loc o, + struct loc i0, struct loc i1, int64_t v) { struct insn i = {.k = k, .o = o, .i0 = i0, .i1 = i1, .v = v}; vect_append(struct insn, f->insns, &i); } +static void output_label(struct fn *f) +{ + output_insn(f, LABEL, null_loc(), null_loc(), null_loc(), 0); +} + static void lower_var(struct fn *f, struct ast *n) { n->l = build_local_loc(f->sp++); @@ -222,7 +229,8 @@ static void lower_print(struct fn *f, struct ast *p) /* don't print space on last element */ if (n->n) - output_insn(f, PRINT_SPACE, null_loc(), null_loc(), null_loc(), 0); + output_insn(f, PRINT_SPACE, null_loc(), null_loc(), + null_loc(), 0); } output_insn(f, PRINT_NEWLINE, null_loc(), null_loc(), null_loc(), 0); @@ -243,7 +251,8 @@ static void lower_proc_call(struct fn *f, struct ast *c) } struct ast *def = file_scope_find(c->scope, proc_call_id(c)); - output_insn(f, CALL, null_loc(), null_loc(), null_loc(), loc_as_int(def->l)); + output_insn(f, CALL, null_loc(), null_loc(), null_loc(), + loc_as_int(def->l)); c->l = build_local_loc(f->sp); if (c->t != TYPE_VOID) @@ -266,7 +275,8 @@ static void lower_func_call(struct fn *f, struct ast *c) } struct ast *def = file_scope_find(c->scope, func_call_id(c)); - output_insn(f, CALL, null_loc(), null_loc(), null_loc(), loc_as_int(def->l)); + output_insn(f, CALL, null_loc(), null_loc(), null_loc(), + loc_as_int(def->l)); c->l = build_local_loc(f->sp); if (c->t != TYPE_VOID) output_insn(f, RETVAL, c->l, null_loc(), null_loc(), 0); @@ -394,7 +404,7 @@ static void lower_date_diff(struct fn *f, struct ast *n) static void lower_until(struct fn *f, struct ast *n) { size_t off = vec_len(&f->insns); - output_insn(f, LABEL, null_loc(), null_loc(), null_loc(), 0); + output_label(f); lower_list(f, until_body(n)); @@ -407,6 +417,8 @@ static void lower_until(struct fn *f, struct ast *n) static void patch_branch(struct fn *f, size_t branch, size_t off) { + assert((vect_at(struct insn, f->insns, off)).k == LABEL); + struct insn i = vect_at(struct insn, f->insns, branch); i.v = off; vect_at(struct insn, f->insns, branch) = i; @@ -429,12 +441,14 @@ static void lower_unless(struct fn *f, struct ast *n) output_insn(f, J, null_loc(), null_loc(), null_loc(), 0); size_t off = vec_len(&f->insns); + output_label(f); patch_branch(f, branch, off); struct ast *otherwise = unless_otherwise(n); lower_list(f, otherwise); off = vec_len(&f->insns); + output_label(f); patch_branch(f, jump, off); n->l = null_loc(); @@ -461,6 +475,7 @@ static void lower_unless_expr(struct fn *f, struct ast *n) output_insn(f, J, null_loc(), null_loc(), null_loc(), 0); size_t off = vec_len(&f->insns); + output_label(f); patch_branch(f, branch, off); struct ast *otherwise = unless_expr_otherwise(n); @@ -468,6 +483,7 @@ static void lower_unless_expr(struct fn *f, struct ast *n) output_insn(f, MOVE, n->l, otherwise->l, null_loc(), 0); off = vec_len(&f->insns); + output_label(f); patch_branch(f, jump, off); } @@ -538,9 +554,9 @@ static void add_proc(struct ast *n) { size_t idx = vec_len(&fns); n->l = build_global_loc(idx); struct fn f = {.name = proc_id(n), - .idx = idx, - .sp = 0, - .insns = vec_create(sizeof(struct insn))}; + .idx = idx, + .sp = 0, + .insns = vec_create(sizeof(struct insn))}; vect_append(struct fn, fns, &f); } @@ -549,9 +565,9 @@ static void add_func(struct ast *n) { size_t idx = vec_len(&fns); n->l = build_global_loc(idx); struct fn f = {.name = func_id(n), - .idx = idx, - .sp = 0, - .insns = vec_create(sizeof(struct insn))}; + .idx = idx, + .sp = 0, + .insns = vec_create(sizeof(struct insn))}; vect_append(struct fn, fns, &f); } @@ -561,6 +577,8 @@ static void lower_proc_def(struct ast *d) struct fn *f = vec_at(&fns, d->l.o); assert(f); + f->params = ast_list_len(proc_formals(d)); + lower_list(f, proc_formals(d)); lower_list(f, proc_vars(d)); lower_list(f, proc_body(d)); @@ -574,6 +592,8 @@ static void lower_func_def(struct ast *d) struct fn *f = vec_at(&fns, d->l.o); assert(f); + f->params = ast_list_len(func_formals(d)); + lower_list(f, func_formals(d)); lower_list(f, func_vars(d)); lower_list(f, func_body(d)); @@ -678,9 +698,9 @@ int lower_ast(struct ast *tree) fns = vec_create(sizeof(struct fn)); struct fn main = {.name = "main", - .idx = 0, - .sp = 0, - .insns = vec_create(sizeof(struct insn))}; + .idx = 0, + .sp = 0, + .insns = vec_create(sizeof(struct insn))}; vect_append(struct fn, fns, &main); @@ -717,6 +737,8 @@ int lower_ast(struct ast *tree) static void destroy_fn(struct fn *f) { vec_destroy(&f->insns); + if (f->arena) + munmap(f->arena, f->size); } void destroy_lowering() |