summaryrefslogtreecommitdiff
path: root/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler.c')
-rw-r--r--compiler.c263
1 files changed, 171 insertions, 92 deletions
diff --git a/compiler.c b/compiler.c
index 8cc28d9..b66a8e9 100644
--- a/compiler.c
+++ b/compiler.c
@@ -413,6 +413,14 @@ typedef struct {
Module *module;
} Function;
+typedef struct Scope {
+ char *name;
+ Module *current;
+ Vector stack_vars, reg_vars;
+ struct Scope *parent;
+ int next_const;
+ int next_bool;
+} Scope;
// Copies the name, does not copy the module.
@@ -483,6 +491,100 @@ bool is_inbuilt(char *name) {
}
+// SCOPE FUNCTIONS
+
+Scope scope_init(char *name, Module *mod) {
+ Scope out = {0};
+
+ Vector cpy = vect_from_string(name);
+ out.name = vect_as_string(&cpy);
+
+ out.stack_vars = vect_init(sizeof(Variable));
+ out.reg_vars = vect_init(sizeof(Variable));
+ out.current = mod;
+
+ out.next_const = 0;
+ out.next_bool = 0;
+
+ return out;
+}
+
+void scope_end(Scope *s) {
+ free(s->name);
+
+ for(size_t i = 0; i < s->stack_vars.count; i++) {
+ Variable *v = vect_get(&s->stack_vars, i);
+ var_end(v);
+ }
+ vect_end(&s->stack_vars);
+
+ for(size_t i = 0; i < s->reg_vars.count; i++) {
+ Variable *v = vect_get(&s->reg_vars, i);
+ var_end(v);
+ }
+ vect_end(&s->reg_vars);
+}
+
+// Label generation
+void _scope_name_rec(Scope *s, Vector *v) {
+ // Base case
+ if (s == NULL)
+ return;
+
+ _scope_name_rec(s->parent, v);
+
+ // Add # before name if not directly from module
+ if (s->parent != NULL)
+ vect_push_string(v, "#");
+ vect_push_string(v, s->name);
+}
+
+char *mod_label_prefix(Module *m);
+Vector _scope_base_label(Scope *s) {
+ Vector out = vect_from_string("");
+ vect_push_free_string(&out, mod_label_prefix(s->current));
+
+ _scope_name_rec(s, &out);
+
+ return out;
+}
+
+char *scope_label_start(Scope *s) {
+ Vector out = _scope_base_label(s);
+ vect_push_string(&out, "#start");
+ return vect_as_string(&out);
+}
+
+char *scope_label_rep(Scope *s) {
+ Vector out = _scope_base_label(s);
+ vect_push_string(&out, "#rep");
+ return vect_as_string(&out);
+}
+
+char *scope_label_end(Scope *s) {
+ Vector out = _scope_base_label(s);
+ vect_push_string(&out, "#end");
+ return vect_as_string(&out);
+}
+
+char *scope_gen_const_label(Scope *s) {
+ Vector out = _scope_base_label(s);
+ vect_push_string(&out, "#const");
+ vect_push_free_string(&out, int_to_str(s->next_const));
+ s->next_const++;
+ return vect_as_string(&out);
+}
+
+char *scope_gen_bool_label(Scope *s) {
+ Vector out = _scope_base_label(s);
+ vect_push_string(&out, "#bool");
+ vect_push_free_string(&out, int_to_str(s->next_bool));
+ return vect_as_string(&out);
+}
+
+void scope_adv_bool_label(Scope *s) {
+ s->next_bool++;
+}
// Variables
@@ -1107,6 +1209,11 @@ char *_var_get_store(CompData *out, Variable *store) {
char *name = _var_get_datalabel(store);
return _gen_address(PREFIXES[_var_size(store) - 1], name, "", 0, 0, true);
free(name);
+ } else if (store->location == LOC_LITL) {
+ vect_push_string(&out->text, "\tmov rdi, ");
+ vect_push_free_string(&out->text, int_to_str(store->offset));
+ vect_push_string(&out->text, "; litl set\n");
+ return _op_get_register(6, _var_size(store));
} else if (store->location < 0) {
return _gen_address(PREFIXES[_var_size(store) - 1], "rbp", "", 0, store->offset, false);
} else {
@@ -1141,7 +1248,7 @@ char *_var_get_from(CompData *out, Variable *store, Variable *from) {
} else if (from->location > 0) {
mov_from = _op_get_register(from->location, _var_size(from));
} else if (from->location == LOC_LITL) {
- if (store->location < 1 || _var_ptr_type(store) == PTYPE_REF) {
+ if ((store->location == LOC_DATA || store->location == LOC_STCK) || _var_ptr_type(store) == PTYPE_REF) {
vect_push_string(&out->text, "\tmov ");
vect_push_free_string(&out->text, _op_get_register(5, _var_size(store)));
vect_push_string(&out->text, ", ");
@@ -1694,6 +1801,66 @@ void var_op_bsr(CompData *out, Variable *base, Variable *bsr) {
vect_push_string(&out->text, " ; Complete not\n");
}
+void _var_op_cmpbase(CompData *out, Variable *base, Variable *cmp, char *cc) {
+
+ char *store = _var_get_store(out, base);
+ char *from = _var_get_from(out, base, cmp);
+
+ vect_push_string(&out->text, "\txor rax, rax\n");
+ vect_push_string(&out->text, "\tmov rdx, 1\n");
+
+ // cmp
+ vect_push_string(&out->text, "\tcmp ");
+ vect_push_free_string(&out->text, from);
+ vect_push_string(&out->text, ", ");
+ vect_push_free_string(&out->text, from);
+
+ 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");
+
+}
+
+// Less than
+void var_op_lt(CompData *out, Variable *base, Variable *lt) {
+ _var_op_cmpbase(out, base, lt, "lt");
+}
+
+// Greater than
+void var_op_gt(CompData *out, Variable *base, Variable *lt) {
+ _var_op_cmpbase(out, base, lt, "gt");
+}
+
+// Less or equal
+void var_op_let(CompData *out, Variable *base, Variable *lt) {
+ _var_op_cmpbase(out, base, lt, "le");
+}
+
+// Greater or equal
+void var_op_get(CompData *out, Variable *base, Variable *lt) {
+ _var_op_cmpbase(out, base, lt, "ge");
+}
+
+// Boolean and
+void var_op_band(CompData *out, Scope *s) {
+ // Just parsed the left side, short circuit if zero
+
+}
+
+// Generate a bool
+Variable var_gen_bool(CompData *out) {
+ // load bool value into rax
+ vect_push_string(&out->text, "\txor rax, rax\n");
+ vect_push_string(&out->text, "\tmov rdx, 1\n");
+ vect_push_string(&out->text, "\tcmovnz rax, rdx ; bool gen\n");
+
+ // Generate variable
+ Variable v = var_init("#bool", typ_get_inbuilt("bool"));
+ v.location = 1;
+ return v;
+}
+
// Multiplies "base" by "mul" and sets "base" to the result.
void var_op_mul(CompData *out, Variable *base, Variable *mul) {
if(base->location == LOC_LITL) {
@@ -3698,94 +3865,6 @@ void phase_1(Artifact *path, Module *root) {
// Phase 2
-typedef struct Scope {
- char *name;
- Module *current;
- Vector stack_vars, reg_vars;
- struct Scope *parent;
- int next_const;
-} Scope;
-
-Scope scope_init(char *name, Module *mod) {
- Scope out = {0};
-
- Vector cpy = vect_from_string(name);
- out.name = vect_as_string(&cpy);
-
- out.stack_vars = vect_init(sizeof(Variable));
- out.reg_vars = vect_init(sizeof(Variable));
- out.current = mod;
-
- out.next_const = 0;
-
- return out;
-}
-
-void scope_end(Scope *s) {
- free(s->name);
-
- for(size_t i = 0; i < s->stack_vars.count; i++) {
- Variable *v = vect_get(&s->stack_vars, i);
- var_end(v);
- }
- vect_end(&s->stack_vars);
-
- for(size_t i = 0; i < s->reg_vars.count; i++) {
- Variable *v = vect_get(&s->reg_vars, i);
- var_end(v);
- }
- vect_end(&s->reg_vars);
-}
-
-// Label generation
-void _scope_name_rec(Scope *s, Vector *v) {
- // Base case
- if (s == NULL)
- return;
-
- _scope_name_rec(s->parent, v);
-
- // Add # before name if not directly from module
- if (s->parent != NULL)
- vect_push_string(v, "#");
- vect_push_string(v, s->name);
-}
-
-Vector _scope_base_label(Scope *s) {
- Vector out = vect_from_string("");
- vect_push_free_string(&out, mod_label_prefix(s->current));
-
- _scope_name_rec(s, &out);
-
- return out;
-}
-
-char *scope_label_start(Scope *s) {
- Vector out = _scope_base_label(s);
- vect_push_string(&out, "#start");
- return vect_as_string(&out);
-}
-
-char *scope_label_rep(Scope *s) {
- Vector out = _scope_base_label(s);
- vect_push_string(&out, "#rep");
- return vect_as_string(&out);
-}
-
-char *scope_label_end(Scope *s) {
- Vector out = _scope_base_label(s);
- vect_push_string(&out, "#end");
- return vect_as_string(&out);
-}
-
-char *scope_gen_const_label(Scope *s) {
- Vector out = _scope_base_label(s);
- vect_push_string(&out, "#const");
- vect_push_free_string(&out, int_to_str(s->next_const));
- s->next_const++;
- return vect_as_string(&out);
-}
-
// Sub scopes
Scope scope_subscope(Scope *s, char *name) {
@@ -4761,13 +4840,13 @@ Variable _eval(Scope *s, CompData *data, Vector *tokens, size_t start, size_t en
}
break;
case '=':
- var_op_eq(data, &out, &rhs);
+ var_op_eq(data, s, &out, &rhs);
break;
case '&':
- var_op_band(data, &out, &rhs);
+ var_op_band(data, s);
break;
case '|':
- var_op_bor(data, &out, &rhs);
+ var_op_bor(data, s, &out, &rhs);
break;
case '<':
var_op_bsl(data, &out, &rhs);