diff options
| m--------- | deps/ejit | 0 | ||||
| -rw-r--r-- | examples/fib.ph | 11 | ||||
| -rw-r--r-- | include/posthaste/ast.h | 2 | ||||
| -rw-r--r-- | src/lower.c | 42 | 
4 files changed, 32 insertions, 23 deletions
| diff --git a/deps/ejit b/deps/ejit -Subproject 8e04d594e8d280e37651f9976be52e0052c9051 +Subproject cb21b31b31dc30023d6fadcab3c15b258f40be9 diff --git a/examples/fib.ph b/examples/fib.ph new file mode 100644 index 0000000..9e1a185 --- /dev/null +++ b/examples/fib.ph @@ -0,0 +1,11 @@ +function Fib{ num[int] } return int +is +	do +		1 +	unless 1 < num +	otherwise +		Fib(num - 1) + Fib(num - 2) +	done +end function + +print Fib(42) diff --git a/include/posthaste/ast.h b/include/posthaste/ast.h index 64e987f..3096186 100644 --- a/include/posthaste/ast.h +++ b/include/posthaste/ast.h @@ -68,7 +68,7 @@ enum type_kind {  /* used by lower.c, defined here to avoid circular dependencies */  struct loc { -	/* offset within either local stack */ +	/* offset within local stack */  	uintptr_t s;  	/* offset within global array */  	uintptr_t g; diff --git a/src/lower.c b/src/lower.c index 5e0e41e..cdede46 100644 --- a/src/lower.c +++ b/src/lower.c @@ -36,9 +36,7 @@   * now */  static struct vec fns = {0}; -/* 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; +static size_t globals = 1;  /* get register/stack slot for AST node */  #define regno(x) ((x)->l.s) @@ -59,18 +57,17 @@ static void lower_list(struct fn *f, struct ast *l)  static struct loc build_local_loc(size_t idx)  { -	return (struct loc){.g = 0, .s = idx}; +	return (struct loc){.g = -1, .s = idx};  }  static struct loc build_global_loc(size_t idx)  { -	return (struct loc){.g = idx, .s = 0}; +	return (struct loc){.g = idx, .s = -1};  }  static struct loc null_loc()  { -	/* don't exactly love this but I guess it works */ -	return build_global_loc(1); +	return (struct loc){.g = -1, .s = -1};  }  static enum ejit_type ejit_type_from(enum type_kind t) @@ -87,9 +84,9 @@ static enum ejit_type ejit_type_from(enum type_kind t)  static void put(struct fn *f, struct loc l)  { -	assert(l.g != 1); +	assert(l.g != 0);  	/* local values are already where they should be */ -	if (l.g <= 1) +	if (l.g == -1)  		return;  	/* something like this I think, should still check the type width */ @@ -98,8 +95,8 @@ static void put(struct fn *f, struct loc l)  static void get(struct fn *f, struct loc l)  { -	assert(l.g != 1); -	if (l.g <= 1) +	assert(l.g != 0); +	if (l.g == -1)  		return;  	ejit_ldxi_u64(f->f, EJIT_GPR(l.s), EJIT_GPR(0), l.g * sizeof(int64_t)); @@ -321,8 +318,8 @@ static void get_id_loc(struct fn *f, struct ast *n)  	/* 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) { +	assert(n->l.g != 0); +	if (n->l.g != -1) {  		/* global variables should get loaded to the stack for handling */  		n->l.s = f->sp;  	} @@ -538,7 +535,10 @@ static void lower_proc_call(struct fn *f, struct ast *c)  	}  	struct ast *def = file_scope_find(c->scope, proc_call_id(c)); -	ejit_calli(f->f, (struct ejit_func *)def->l.s, count, args); +	struct fn *target = vec_at(&fns, def->l.s); +	assert(target); + +	ejit_calli(f->f, target->f, count, args);  	f->sp -= count; @@ -562,9 +562,10 @@ static void lower_func_call(struct fn *f, struct ast *c)  	}  	struct ast *def = file_scope_find(c->scope, func_call_id(c)); -	/* note, def->l.s is not actually a register, rather a pointer to the -	 * struct ejit_func */ -	ejit_calli(f->f, (struct ejit_func *)def->l.s, count, args); +	struct fn *target = vec_at(&fns, def->l.s); +	assert(target); + +	ejit_calli(f->f, target->f, count, args);  	f->sp -= count; @@ -957,10 +958,7 @@ static void lower_global_var(struct fn *f, struct ast *n) {  static void add_proc(struct ast *n) {  	size_t idx = vec_len(&fns); -	/* global locs are effectively just indexes, so this is a nifty way to -	 * encode the procedure index into the AST for later use by -	 * lower_proc_call and so on */ -	n->l = build_global_loc(idx); +	n->l = build_local_loc(idx);  	struct fn f = {.name = proc_id(n),  		       .idx = idx,  		       .sp = 0, @@ -971,7 +969,7 @@ static void add_proc(struct ast *n) {  static void add_func(struct ast *n) {  	size_t idx = vec_len(&fns); -	n->l = build_global_loc(idx); +	n->l = build_local_loc(idx);  	struct fn f = {.name = func_id(n),  		       .idx = idx,  		       .sp = 0, | 
