summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler.c30
-rw-r--r--tests/test_pointer_6.tnsl8
2 files changed, 32 insertions, 6 deletions
diff --git a/compiler.c b/compiler.c
index d237179..9cff99c 100644
--- a/compiler.c
+++ b/compiler.c
@@ -1146,6 +1146,7 @@ void _var_op_set_ptr(CompData *out, Variable *store, Variable *from) {
// Pointer coercion should always work
char *mov_from;
char *mov_to;
+ Vector mov_type; // load or move instruction
// First deref from var, then deref store variable, then move.
if(_var_ptr_type(store) != PTYPE_REF) {
@@ -1169,13 +1170,18 @@ void _var_op_set_ptr(CompData *out, Variable *store, Variable *from) {
}
if (_var_ptr_type(from) != PTYPE_REF) {
- if (from->location > 0 || (_var_ptr_type(store) != PTYPE_REF && store->location > 0)) {
+ if (from->location > 0 || from->location == LOC_LITL) {
mov_from = _op_get_location(from);
+ mov_type = vect_from_string("\tmov ");
+ } else if (store->location > 0 && _var_ptr_type(store) != PTYPE_REF) {
+ mov_from = _op_get_location(from);
+ mov_type = vect_from_string("\tlea ");
} else {
- vect_push_string(&out->text, "\tmov rsi, ");
+ vect_push_string(&out->text, "\tlea rsi, ");
vect_push_free_string(&out->text, _op_get_location(from));
vect_push_string(&out->text, " ; Move for ptr set\n");
mov_from = _op_get_register(5, 8);
+ mov_type = vect_from_string("\tmov ");
}
} else {
// Need to deref
@@ -1209,13 +1215,25 @@ void _var_op_set_ptr(CompData *out, Variable *store, Variable *from) {
}
mov_from = _op_get_register(5, 8);
+ mov_type = vect_from_string("\tmov ");
}
- vect_push_string(&out->text, "\tmov ");
- vect_push_free_string(&out->text, mov_to);
+ vect_push_free_string(&out->text, vect_as_string(&mov_type));
+ vect_push_string(&out->text, mov_to);
vect_push_string(&out->text, ", ");
vect_push_free_string(&out->text, mov_from);
- vect_push_string(&out->text, " ; Ptr set final\n\n");
+ vect_push_string(&out->text, " ; Ptr set final\n");
+
+ if (_var_first_nonref(store) == PTYPE_PTR && _var_first_nonref(from) == PTYPE_ARR) {
+ vect_push_string(&out->text, "\tadd ");
+ vect_push_string(&out->text, mov_to);
+ vect_push_string(&out->text, ", ");
+ vect_push_string(&out->text, "8 ; Reference to first el in array\n\n");
+ } else {
+ vect_push_string(&out->text, "\n");
+ }
+
+ free(mov_to);
return;
}
@@ -4837,7 +4855,7 @@ Variable _eval_literal(Scope *s, CompData *data, Vector *tokens, size_t literal)
out.mod = s->current;
out.location = LOC_DATA;
free(label);
- int arr_t = str_dat.count;
+ int arr_t = PTYPE_ARR;
vect_push(&out.ptr_chain, &arr_t);
} else if (tok_str_eq(t, "false") || tok_str_eq(t, "true")) {
out.type = typ_get_inbuilt("bool");
diff --git a/tests/test_pointer_6.tnsl b/tests/test_pointer_6.tnsl
new file mode 100644
index 0000000..3a850cb
--- /dev/null
+++ b/tests/test_pointer_6.tnsl
@@ -0,0 +1,8 @@
+/; main [int]
+ ~uint8 a = "asdf\0"
+ {}uint8 b = "bsdf\0"
+ /; if (a` == 'a' && b{0} == 'b')
+ return 69
+ ;/
+ return 0
+;/