summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler.c130
-rw-r--r--tests/test_controll.tnsl12
-rw-r--r--tests/test_funcall_2.tnsl12
-rw-r--r--tests/test_funcall_3.tnsl16
4 files changed, 124 insertions, 46 deletions
diff --git a/compiler.c b/compiler.c
index 0ac9078..f464a45 100644
--- a/compiler.c
+++ b/compiler.c
@@ -932,7 +932,7 @@ void var_op_pure_set(CompData *out, Variable *store, Variable *from) {
if (store->location == LOC_LITL) {
printf("ERROR: Can't set a literal value by pure set.\n");
return;
- } else if (_var_pure_size(from) != _var_pure_size(store)) {
+ } else if (_var_pure_size(from) != _var_pure_size(store) && from->location != LOC_LITL) {
printf("ERROR: Can't set one variable to the other as their pure sizes are different!\n");
return;
}
@@ -973,7 +973,7 @@ void var_op_pure_set(CompData *out, Variable *store, Variable *from) {
vect_push_free_string(&out->text, int_to_str(_var_pure_size(from)));
vect_push_string(&out->text, "\n");
- vect_push_string(&out->text, "\tmovsb ; Move struct complete\n\n");
+ vect_push_string(&out->text, "\trep movsb ; Move struct complete\n\n");
} else if (from->location < 1 && store->location < 1) {
// Both in memory, use rsi as temp storage for move
vect_push_string(&out->text, "\tmov ");
@@ -1307,7 +1307,7 @@ void var_op_set(CompData *out, Variable *store, Variable *from) {
} else {
vect_push_free_string(&out->text, int_to_str(_var_size(store)));
}
- vect_push_string(&out->text, "\n\tmovsb ; Complete struct move\n\n");
+ vect_push_string(&out->text, "\n\trep movsb ; Complete struct move\n\n");
}
}
@@ -3326,17 +3326,9 @@ void p1_resolve_func_types(Module *root, Function *func) {
if (method)
reg = 2;
int stack_accum = 0;
- for (size_t i = 0; i < func->inputs.count; i++) {
- Variable *var = vect_get(&func->inputs, i);
- char *n_end = strchr(var->name, ' ');
-
- if (n_end == NULL) {
- printf("COMPILER ERROR: Did not properly assure function %s had all parameters with both name and RTN\n\n", func->name);
- p1_error = true;
- break;
- }
-
- Artifact rtn = art_from_str(n_end + 1, '.');
+ for (size_t i = 0; i < func->outputs.count; i++) {
+ Variable *var = vect_get(&func->outputs, i);
+ Artifact rtn = art_from_str(var->name, '.');
Type *t = mod_find_type(root, &rtn);
if(t == NULL) {
@@ -3349,13 +3341,12 @@ void p1_resolve_func_types(Module *root, Function *func) {
art_end(&rtn);
- *n_end = 0;
- Vector name = vect_from_string(var->name);
+ Vector name = vect_from_string(t->name);
free(var->name);
var->name = vect_as_string(&name);
var->type = t;
-
- // Check where the input should be read from
+
+ // Check where the output should be stored
if (
(
// is struct
@@ -3370,8 +3361,8 @@ void p1_resolve_func_types(Module *root, Function *func) {
) {
// The output should be stored on the stack
var->location = LOC_STCK;
- var->offset = stack_accum;
stack_accum += _var_pure_size(var);
+ var->offset = stack_accum;
} else {
// The output should be stored in a register
var->location = reg;
@@ -3379,14 +3370,22 @@ void p1_resolve_func_types(Module *root, Function *func) {
reg++;
}
}
-
+
reg = 1;
if (method)
reg = 2;
// Stack accum not reset because the stack would get clobbered
- for (size_t i = 0; i < func->outputs.count; i++) {
- Variable *var = vect_get(&func->outputs, i);
- Artifact rtn = art_from_str(var->name, '.');
+ for (size_t i = 0; i < func->inputs.count; i++) {
+ Variable *var = vect_get(&func->inputs, i);
+ char *n_end = strchr(var->name, ' ');
+
+ if (n_end == NULL) {
+ printf("COMPILER ERROR: Did not properly assure function %s had all parameters with both name and RTN\n\n", func->name);
+ p1_error = true;
+ break;
+ }
+
+ Artifact rtn = art_from_str(n_end + 1, '.');
Type *t = mod_find_type(root, &rtn);
if(t == NULL) {
@@ -3399,12 +3398,13 @@ void p1_resolve_func_types(Module *root, Function *func) {
art_end(&rtn);
- Vector name = vect_from_string(t->name);
+ *n_end = 0;
+ Vector name = vect_from_string(var->name);
free(var->name);
var->name = vect_as_string(&name);
var->type = t;
-
- // Check where the output should be stored
+
+ // Check where the input should be read from
if (
(
// is struct
@@ -3419,8 +3419,8 @@ void p1_resolve_func_types(Module *root, Function *func) {
) {
// The output should be stored on the stack
var->location = LOC_STCK;
- var->offset = stack_accum;
stack_accum += _var_pure_size(var);
+ var->offset = stack_accum;
} else {
// The output should be stored in a register
var->location = reg;
@@ -3428,6 +3428,22 @@ void p1_resolve_func_types(Module *root, Function *func) {
reg++;
}
}
+
+ // Stack variables will be pushed on in reverse order for a call
+ // so we need to invert all the variable offsets
+ // we are adding 8 here because we assume a return pointer right where
+ // rbp is located
+ for(size_t i = 0; i < func->outputs.count; i++) {
+ Variable *var = vect_get(&func->outputs, i);
+ if(var->location == LOC_STCK)
+ var->offset = 8 + stack_accum - var->offset;
+ }
+
+ for(size_t i = 0; i < func->inputs.count; i++) {
+ Variable *var = vect_get(&func->inputs, i);
+ if(var->location == LOC_STCK)
+ var->offset = 8 + stack_accum - var->offset;
+ }
}
void p1_resolve_types(Module *root) {
@@ -3728,15 +3744,25 @@ void scope_free_tmp(Scope *s, CompData *data, Variable *v) {
}
void scope_free_to(Scope *s, CompData *data, Variable *v) {
+ bool freed = false;
+
for (size_t i = s->stack_vars.count; i > 0; i--) {
- Variable *cur = vect_get(&s->stack_vars, i);
+ Variable *cur = vect_get(&s->stack_vars, i - 1);
if (cur->offset < v->offset) {
var_end(cur);
vect_pop(&s->stack_vars);
+ freed = true;
} else {
break;
}
}
+
+ if (freed) {
+ int next_loc = _scope_next_stack_loc(s, 0);
+ vect_push_string(&data->text, "\tlea rsp, [rbp - ");
+ vect_push_free_string(&data->text, int_to_str(-next_loc));
+ vect_push_string(&data->text, "]; Scope free to\n");
+ }
}
Variable scope_get_stack_pin(Scope *s) {
@@ -4021,16 +4047,16 @@ Variable _eval_call(Scope *s, CompData *data, Vector *tokens, Function *f, Varia
// First, load all stack-based outputs onto the stack
// and set the output
- for (size_t i = f->outputs.count; i > 0; i--) {
- Variable *cur = vect_get(&f->outputs, i - 1);
+ for (size_t i = 0; i < f->outputs.count; i++) {
+ Variable *cur = vect_get(&f->outputs, i);
if (cur->location == LOC_STCK) {
Variable store = scope_mk_stmp(s, data, cur);
- if (i == 1) {
+ if (i == 0) {
out = store;
} else {
var_end(&store);
}
- } else if (i == 1) {
+ } else if (i == 0) {
out = var_copy(cur);
}
}
@@ -4040,8 +4066,8 @@ Variable _eval_call(Scope *s, CompData *data, Vector *tokens, Function *f, Varia
size_t pstart = start + 1;
size_t pend = start + 1;
- for(size_t i = f->inputs.count; i > 0; i--) {
- Variable *cur = vect_get(&f->outputs, i - 1);
+ for(size_t i = 0; i < f->inputs.count; i++) {
+ Variable *cur = vect_get(&f->inputs, i);
// preprocess, find end of current param
while (pend < max) {
@@ -4075,11 +4101,25 @@ Variable _eval_call(Scope *s, CompData *data, Vector *tokens, Function *f, Varia
Vector inputs = vect_init(sizeof(Variable));
Variable inpin = scope_get_stack_pin(s);
- pstart = start;
- pend = start;
+ // handle self for methods
+ if (self != NULL) {
+ Variable from = {0};
+ if (_var_ptr_type(self) == PTYPE_NONE) {
+ var_op_reference(data, &from, self);
+ } else
+ from = var_copy(self);
+
+ Variable set = scope_mk_stmp(s, data, self);
+ var_op_pure_set(data, &set, &from);
+ var_end(&from);
+ vect_push(&inputs, &set);
+ }
+
+ pstart = start + 1;
+ pend = start + 1;
- for(size_t i = f->inputs.count; i > 0; i--) {
- Variable *cur = vect_get(&f->outputs, i - 1);
+ for(size_t i = 0; i < f->inputs.count; i++) {
+ Variable *cur = vect_get(&f->inputs, i);
// preprocess, find end of current param
while (pend < max) {
@@ -4110,13 +4150,13 @@ Variable _eval_call(Scope *s, CompData *data, Vector *tokens, Function *f, Varia
}
}
- // Fourth, move all register based parameters into their correct registers
+ // Fifth, move all register based parameters into their correct registers
for(size_t i = 0; i < inputs.count; i++) {
Variable *cur = vect_get(&inputs, i);
// create tmp var
Variable set = var_copy(cur);
- set.location = inputs.count - i;
+ set.location = i + 1;
// eval and set
var_op_pure_set(data, &set, cur);
@@ -4127,23 +4167,21 @@ Variable _eval_call(Scope *s, CompData *data, Vector *tokens, Function *f, Varia
vect_end(&inputs);
// set stack to where it needs to be for call
+ scope_free_to(s, data, &inpin);
if (inpin.name != NULL) {
- scope_free_to(s, data, &inpin);
var_end(&inpin);
}
- // Fifth, make call
+ // Sixth, make call
vect_push_string(&data->text, "\tcall ");
vect_push_free_string(&data->text, mod_label_prefix(f->module));
vect_push_string(&data->text, f->name);
vect_push_string(&data->text, "; Function call\n\n");
- // Sixth, return output
+ // Seventh, return output
+ scope_free_to(s, data, &pin);
if (out.name != NULL) {
- scope_free_to(s, data, &pin);
var_end(&pin);
- } else {
- scope_free_all_tmp(s, data);
}
return out;
}
diff --git a/tests/test_controll.tnsl b/tests/test_controll.tnsl
new file mode 100644
index 0000000..47ff241
--- /dev/null
+++ b/tests/test_controll.tnsl
@@ -0,0 +1,12 @@
+/; main [int]
+
+ /; if (false)
+ return 1
+ ;; else if (1 == 0)
+ return 2
+ ;; else
+ return 69
+ ;/
+
+ return 0
+;/
diff --git a/tests/test_funcall_2.tnsl b/tests/test_funcall_2.tnsl
new file mode 100644
index 0000000..3bf746c
--- /dev/null
+++ b/tests/test_funcall_2.tnsl
@@ -0,0 +1,12 @@
+/; ret_a [int]
+ return 9
+;/
+
+/; ret_b (int i, j) [int]
+ return i + j
+;/
+
+/; main [int]
+ int i = ret_a()
+ return ret_b(60, i)
+;/
diff --git a/tests/test_funcall_3.tnsl b/tests/test_funcall_3.tnsl
new file mode 100644
index 0000000..b974ea7
--- /dev/null
+++ b/tests/test_funcall_3.tnsl
@@ -0,0 +1,16 @@
+struct Str {
+ int i, j
+}
+
+/; strout [Str]
+ Str out
+ out.i = 60
+ out.j = 9
+ return out
+;/
+
+/; main [int]
+ Str out
+ out = strout()
+ return out.j + out.i
+;/