summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
authorWormHeamer2025-08-03 21:51:29 -0400
committerWormHeamer2025-08-03 21:51:29 -0400
commita49e785e8536acd6d5ff2c6bebf8d9902d2f3620 (patch)
treea84dc858dc046df1c99488a1ae32a9b0003f03e7 /ir.c
parent3cdc850f2a7dbf1e170242417d67acf8d7e7b0d8 (diff)
add booleans and comparison operators
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/ir.c b/ir.c
index 0ef19b9..8a2baf5 100644
--- a/ir.c
+++ b/ir.c
@@ -7,10 +7,17 @@ extern int no_opt;
int type_eql(Type *a, Type *b) {
if (a->t != b->t) return 0;
+ if (a->lvl != b->lvl) return 0;
if (a->next != b->next) return 0;
return a->next ? type_eql(a->next, b->next) : 1;
}
+int type_base_eql(Type *a, Type *b) {
+ if (a->t != b->t) return 0;
+ if (a->next != b->next) return 0;
+ return a->next ? type_base_eql(a->next, b->next) : 1;
+}
+
/* nodes */
const char *node_type_name(NodeType t) {
@@ -24,14 +31,20 @@ const char *node_type_name(NodeType t) {
"and", "or", "xor",
"lshift", "rshift",
"neg", "not",
+ "equal",
+ "not-equal",
+ "less",
+ "greater",
+ "less-or-equal",
+ "greater-or-equal",
"value"
};
return names[t];
}
void node_die(Node *n, Proc *p) {
- n->prev_free = p->free_list;
- p->free_list = n;
+ /*n->prev_free = p->free_list;
+ p->free_list = n;*/
}
void node_del_out(Node *n, Node *p) {
@@ -135,8 +148,7 @@ Node *node_dedup_lit(Proc *p, Value v) {
return NULL;
}
-Node *node_new_lit_i64(Proc *p, int64_t i) {
- Value v = (Value) { { .lvl = T_CONST, .t = T_INT }, { .i = i } };
+Node *node_new_lit(Proc *p, Value v) {
Node *t = node_dedup_lit(p, v);
if (t) return t;
Node *n = node_new(p, N_LIT, p->start);
@@ -144,6 +156,14 @@ Node *node_new_lit_i64(Proc *p, int64_t i) {
return n;
}
+Node *node_new_lit_i64(Proc *p, int64_t i) {
+ return node_new_lit(p, (Value) { { .lvl = T_CONST, .t = T_INT }, { .i = i } });
+}
+
+Node *node_new_lit_bool(Proc *p, int b) {
+ return node_new_lit(p, (Value) { { .lvl = T_CONST, .t = T_BOOL }, { .i = b } });
+}
+
static inline int node_op_communative(NodeType t) {
NodeType ops[] = { N_OP_ADD, N_OP_MUL, N_OP_AND, N_OP_XOR, N_OP_OR };
for (unsigned i = 0; i < sizeof ops / sizeof *ops; i++) {
@@ -170,8 +190,12 @@ Value node_compute(Node *n, Lexer *l) {
}
}
}
- if (lit_type.lvl == T_CONST && lit_type.t == T_INT) {
- Value v = { .type = lit_type };
+
+ if (lit_type.lvl != T_CONST) return n->val;
+
+ Value v = { .type = lit_type };
+
+ if (lit_type.t == T_INT) {
switch (n->type) {
case N_OP_NEG: v.i = -in[0]->val.i; break;
case N_OP_NOT: v.i = ~in[0]->val.i; break;
@@ -189,10 +213,28 @@ Value node_compute(Node *n, Lexer *l) {
case N_OP_XOR: v.i = in[0]->val.i ^ in[1]->val.i; break;
case N_OP_SHL: v.i = in[0]->val.u << in[1]->val.u; break;
case N_OP_SHR: v.i = in[0]->val.u >> in[1]->val.u; break;
+ case N_CMP_EQL: v.type.t = T_BOOL; v.i = in[0]->val.i == in[1]->val.i; break;
+ case N_CMP_NEQ: v.type.t = T_BOOL; v.i = in[0]->val.i != in[1]->val.i; break;
+ case N_CMP_LES: v.type.t = T_BOOL; v.i = in[0]->val.i < in[1]->val.i; break;
+ case N_CMP_GTR: v.type.t = T_BOOL; v.i = in[0]->val.i > in[1]->val.i; break;
+ case N_CMP_LTE: v.type.t = T_BOOL; v.i = in[0]->val.i <= in[1]->val.i; break;
+ case N_CMP_GTE: v.type.t = T_BOOL; v.i = in[0]->val.i >= in[1]->val.i; break;
+ default: return n->val;
+ }
+ return v;
+ } else if (lit_type.t == T_BOOL) {
+ switch (n->type) {
+ case N_OP_NOT: v.i = !in[0]->val.i; break;
+ case N_CMP_EQL: v.i = in[0]->val.i == in[1]->val.i; break;
+ case N_CMP_NEQ: v.i = in[0]->val.i != in[1]->val.i; break;
+ case N_OP_AND: v.i = in[0]->val.i && in[1]->val.i; break;
+ case N_OP_OR: v.i = in[0]->val.i || in[1]->val.i; break;
+ case N_OP_XOR: v.i = in[0]->val.i ^ in[1]->val.i; break;
default: return n->val;
}
return v;
}
+
return n->val;
}