summaryrefslogtreecommitdiff
path: root/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler.c')
-rw-r--r--compiler.c156
1 files changed, 120 insertions, 36 deletions
diff --git a/compiler.c b/compiler.c
index 9eeb94b..5291c83 100644
--- a/compiler.c
+++ b/compiler.c
@@ -1252,10 +1252,10 @@ char *_var_get_from(CompData *out, Variable *store, Variable *from) {
} else if (from->location == LOC_LITL) {
if (store->location == LOC_LITL) {
vect_push_string(&out->text, "\tmov rsi, ");
- vect_push_free_string(&out->text, int_to_str(store->offset));
+ vect_push_free_string(&out->text, int_to_str(from->offset));
vect_push_string(&out->text, "; litl set\n");
if (store->type != NULL)
- return _op_get_register(5, _var_size(store));
+ return _op_get_register(5, store->type->size);
return _op_get_register(5, 8);
} else if (store->location < 1 || _var_ptr_type(store) == PTYPE_REF) {
vect_push_string(&out->text, "\tmov ");
@@ -1840,6 +1840,7 @@ Variable var_op_cmpbase(CompData *out, Variable *base, Variable *cmp, char *cc)
vect_push_free_string(&out->text, store);
vect_push_string(&out->text, ", ");
vect_push_free_string(&out->text, from);
+ vect_push_string(&out->text, "\n");
// prime rax and rdx
vect_push_string(&out->text, "\tmov rax, 0\n");
@@ -1849,7 +1850,7 @@ Variable var_op_cmpbase(CompData *out, Variable *base, Variable *cmp, char *cc)
vect_push_string(&out->text, "\tcmov");
vect_push_string(&out->text, cc);
vect_push_string(&out->text, " rax, rdx ; bool gen\n");
- vect_push_string(&out->text, "\ttest rax, rax ; less than test\n");
+ vect_push_string(&out->text, "\ttest rax, rax ; less than test\n\n");
// Generate variable
Variable v = var_init("#bool", typ_get_inbuilt("bool"));
@@ -2441,6 +2442,7 @@ bool tok_eq(Token *a, Token *b) {
char *KEYWORDS = "module,export,asm,if,else,loop,label,goto,continue,break,return,import,as,using,struct,method,interface,enum,implements,operator,len,is";
char *KEYTYPES = "uint8,uint16,uint32,uint64,uint,int8,int16,int32,int64,int,float32,float64,float,comp64,comp,bool,vect,void,type";
+char *LITERALS = "false,true";
char *RESERVED = "~`!@#$%^&*()[]{}+-=\"\'\\|:;/?>.<,";
@@ -2511,6 +2513,8 @@ int token_type(char*data) {
return TT_KEYTYPE;
} else if (in_csv(KEYWORDS, data)) {
return TT_KEYWORD;
+ } else if (in_csv(LITERALS, data)){
+ return TT_LITERAL;
}
return TT_DEFWORD;
@@ -4035,10 +4039,6 @@ int _scope_avail_reg(Scope *s) {
Variable scope_mk_tmp(Scope *s, CompData *data, Variable *v) {
Variable out = var_copy(v);
- while (_var_ptr_type(&out) == PTYPE_REF) {
- vect_pop(&out.ptr_chain);
- }
-
int p_typ = _var_ptr_type(v);
free(out.name);
@@ -4148,7 +4148,7 @@ void scope_free_to(Scope *s, CompData *data, Variable *v) {
for (size_t i = s->stack_vars.count; i > 0; i--) {
Variable *cur = vect_get(&s->stack_vars, i - 1);
- if (cur->offset < v->offset) {
+ if (cur->offset < v->offset || v->offset == 0) {
var_end(cur);
vect_pop(&s->stack_vars);
freed = true;
@@ -4157,7 +4157,7 @@ void scope_free_to(Scope *s, CompData *data, Variable *v) {
}
}
- if (freed) {
+ if (freed || v->offset == 0) {
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));
@@ -4732,7 +4732,17 @@ Variable _eval_literal(Scope *s, CompData *data, Vector *tokens, size_t literal)
free(label);
int arr_t = str_dat.count;
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");
+ if (tok_str_eq(t, "true")) {
+ vect_push_string(&data->text, "\tmov rax, 1\n");
+ vect_push_string(&data->text, "\ttest rax, rax ; literal bool\n\n");
+ out.offset = 1;
+ } else {
+ vect_push_string(&data->text, "\tmov rax, 0\n");
+ vect_push_string(&data->text, "\ttest rax, rax ; literal bool\n\n");
+ out.offset = 0;
+ }
} else {
out.location = LOC_LITL;
if (t->data[0] == '\'')
@@ -5461,6 +5471,43 @@ void _p2_func_scope_end(CompData *out, Scope *fs) {
}
+void p2_compile_control(Scope *s, Function *f, CompData *out, Vector *tokens, size_t *pos, Vector *p_list);
+
+void p2_wrap_control(Scope *s, Function *f, CompData *out, Vector *tokens, size_t *pos, Vector *p_list) {
+ Scope sub = scope_subscope(s, "wrap");
+
+ int end;
+ Token *cur;
+ bool first = true;
+ for (;*pos < tokens->count;) {
+ end = tnsl_find_closing(tokens, *pos);
+ cur = vect_get(tokens, *pos);
+ if (end < 0 || (!tok_str_eq(cur, "/;") && !tok_str_eq(cur, ";;"))) {
+ break;
+ }
+
+ cur = vect_get(tokens, *pos + 1);
+
+ if (tok_str_eq(cur, "if") && first) {
+ p2_compile_control(&sub, f, out, tokens, pos, p_list);
+ first = false;
+ } else if (tok_str_eq(cur, "else") && !first) {
+ p2_compile_control(&sub, f, out, tokens, pos, p_list);
+ } else {
+ if (tok_str_eq(cur, "else") && first) {
+ printf("ERROR: Expected if block before else block (%d:%d)\n\n", cur->line, cur->col);
+ }
+ break;
+ }
+
+ *pos = end;
+ }
+
+ vect_push_free_string(&out->text, scope_label_end(&sub));
+ vect_push_string(&out->text, ":\n\n");
+ scope_end(&sub);
+}
+
// TODO loop blocks, if blocks, else blocks
void p2_compile_control(Scope *s, Function *f, CompData *out, Vector *tokens, size_t *pos, Vector *p_list) {
int end = tnsl_find_closing(tokens, *pos);
@@ -5475,13 +5522,27 @@ void p2_compile_control(Scope *s, Function *f, CompData *out, Vector *tokens, si
*pos += 1;
t = vect_get(tokens, *pos);
- Scope wrap = {0};
Scope sub;
- // Get
- if (tok_str_eq(t, "if")) {
- wrap = scope_subscope(s, "wrap");
- sub = scope_subscope(&wrap, t->data);
+ // Generate wrap for if if none exists
+ if (tok_str_eq(t, "if") || tok_str_eq(t, "else")) {
+ if (s->parent == NULL || !scope_name_eq(s, "wrap")) {
+ *pos -= 1;
+ p2_wrap_control(s, f, out, tokens, pos, p_list);
+ return;
+ }
+ }
+
+ // Generate subscope
+ if (tok_str_eq(t, "if") || tok_str_eq(t, "else")) {
+ t = vect_get(tokens, *pos + 1);
+ if (tok_str_eq(t, "if")) {
+ *pos += 1;
+ sub = scope_subscope(s, "elif");
+ } else {
+ t = vect_get(tokens, *pos);
+ sub = scope_subscope(s, t->data);
+ }
} else if (t->type != TT_KEYWORD || !tok_str_eq(t, "loop")) {
printf("ERROR: Expected control block type ('loop' or 'if'), found \"%s\" (%d:%d)\n", t->data, t->line, t->col);
p2_error = true;
@@ -5528,10 +5589,9 @@ void p2_compile_control(Scope *s, Function *f, CompData *out, Vector *tokens, si
if (strcmp(v.type->name, "bool") == 0 && tok_str_eq(t, ")")) {
build = start - 1;
start = b_end;
- var_op_test(out, &v);
- vect_push_string(&out->data, "\tjz ");
- vect_push_free_string(&out->data, scope_label_end(&sub));
- vect_push_string(&out->data, "; Conditional start\n");
+ vect_push_string(&out->text, "\tjz ");
+ vect_push_free_string(&out->text, scope_label_end(&sub));
+ vect_push_string(&out->text, "; Conditional start\n");
} else {
start = build + 1;
}
@@ -5640,45 +5700,69 @@ void p2_compile_control(Scope *s, Function *f, CompData *out, Vector *tokens, si
if (rep != start) {
// Eval, check ending
Variable v = _eval(&sub, out, tokens, start, rep);
- if (strcmp(v.type->name, "bool") == 0 && tok_str_eq(t, "]") && strcmp(sub.name, "loop") == 0) {
+ if (strcmp(v.type->name, "bool") == 0 && tok_str_eq(t, "]") && scope_name_eq(&sub, "loop")) {
rep = start - 1;
start = r_end;
- var_op_test(out, &v);
vect_push_string(&out->text, "\tjnz ");
vect_push_free_string(&out->text, scope_label_start(&sub));
vect_push_string(&out->text, "; Conditional rep\n");
} else {
- start = build + 1;
+ start = rep + 1;
}
var_end(&v);
} else {
- start = build + 1;
+ start = rep + 1;
}
} else if (t->type == TT_DELIMIT) {
- build = tnsl_find_closing(tokens, build);
+ rep = tnsl_find_closing(tokens, rep);
}
}
- if (build > r_end) {
- build = -1;
+ if (rep > r_end) {
+ rep = -1;
}
}
+ Variable free_to = {0};
+
+ // Post control
if (scope_name_eq(&sub, "loop")) {
- }
-
+ if (build >= 0 && rep < 0) {
+ // find end of build, re-eval and cond jmp
+ int b_end = build;
+ t = vect_get(tokens, b_end);
+ while(!tok_str_eq(t, ")")) {
+ if (t->type == TT_DELIMIT) {
+ b_end = tnsl_find_closing(tokens, b_end);
+ b_end++;
+ }
+ t = vect_get(tokens, b_end);
+ }
+ Variable v = _eval(&sub, out, tokens, build, b_end);
+ vect_push_string(&out->text, "\tjnz ");
+ vect_push_free_string(&out->text, scope_label_start(&sub));
+ vect_push_string(&out->text, "; Conditional rep\n");
+ var_end(&v);
+ } else if (build < 0 && rep < 0) {
+ vect_push_string(&out->text, "\tjmp ");
+ vect_push_free_string(&out->text, scope_label_start(&sub));
+ vect_push_string(&out->text, "\n");
+ }
+ } else {
+ // Jmp to outer wrap at end of if
+ scope_free_to(&sub, out, &free_to);
+ vect_push_string(&out->text, "\tjmp ");
+ vect_push_free_string(&out->text, scope_label_end(s));
+ vect_push_string(&out->text, "\n");
+ }
+
+ // Cleanup scope
vect_push_free_string(&out->text, scope_label_end(&sub));
vect_push_string(&out->text, ": ; End label\n");
-
- // Scope cleanup
+ scope_free_to(&sub, out, &free_to);
scope_end(&sub);
-
- if (wrap.name != NULL) {
- vect_push_free_string(&out->text, scope_label_end(&wrap));
- vect_push_string(&out->text, ": ; End wrap label\n");
- scope_end(&wrap);
- }
+ vect_push_string(&out->text, "\n\n");
}
// Handles the 'self' variable in the case where the function is in a method block.