diff options
| author | WormHeamer | 2025-08-03 21:51:29 -0400 |
|---|---|---|
| committer | WormHeamer | 2025-08-03 21:51:29 -0400 |
| commit | a49e785e8536acd6d5ff2c6bebf8d9902d2f3620 (patch) | |
| tree | a84dc858dc046df1c99488a1ae32a9b0003f03e7 /ir.c | |
| parent | 3cdc850f2a7dbf1e170242417d67acf8d7e7b0d8 (diff) | |
add booleans and comparison operators
Diffstat (limited to 'ir.c')
| -rw-r--r-- | ir.c | 54 |
1 files changed, 48 insertions, 6 deletions
@@ -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; } |
