summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/ir.c b/ir.c
index c296e9a..e3d64f5 100644
--- a/ir.c
+++ b/ir.c
@@ -8,8 +8,11 @@ extern int no_opt;
/* convenience macros (lisp-inspired lol) */
-#define CAR(n) n->in.data[0]
-#define CDR(n) n->in.data[1]
+#define IN(n, i) ((n)->in.data[i])
+#define OUT(n, i) ((n)->out.data[i])
+
+#define CAR(n) IN(n, 0)
+#define CDR(n) IN(n, 1)
#define CAAR(n) CAR(CAR(n))
#define CADR(n) CDR(CAR(n))
#define CDAR(n) CAR(CDR(n))
@@ -59,7 +62,7 @@ void type_err(Node *n, Lexer *l) {
Str s = S("");
for (int i = 0; i < n->in.len; i++) {
if (i > 0) str_cat(&s, S(", "), &l->arena);
- str_cat(&s, type_desc(&n->in.data[i]->val.type, &l->arena), &l->arena);
+ str_cat(&s, type_desc(&IN(n, i)->val.type, &l->arena), &l->arena);
}
lex_error_at(l, n->src_pos, LE_ERROR, str_fmt(&l->arena, "type error (%S)", s));
}
@@ -68,18 +71,18 @@ int type_check(Node *n) {
switch (n->type) {
case N_OP_NEG:
n->val.type = (Type) { .lvl = T_TOP, .t = T_INT };
- return n->in.data[0]->val.type.t == T_INT;
+ return CAR(n)->val.type.t == T_INT;
case N_OP_NOT:
- n->val.type = (Type) { .lvl = T_TOP, .t = n->in.data[0]->val.type.t };
- return n->in.data[0]->val.type.t == T_INT || n->in.data[0]->val.type.t == T_BOOL;
+ n->val.type = (Type) { .lvl = T_TOP, .t = CAR(n)->val.type.t };
+ return CAR(n)->val.type.t == T_INT || CAR(n)->val.type.t == T_BOOL;
case N_OP_AND: case N_OP_OR: case N_OP_XOR:
- n->val.type = (Type) { .lvl = T_TOP, .t = n->in.data[0]->val.type.t };
- return (n->in.data[0]->val.type.t == T_INT && n->in.data[1]->val.type.t == T_INT)
- || (n->in.data[0]->val.type.t == T_BOOL && n->in.data[1]->val.type.t == T_BOOL);
+ n->val.type = (Type) { .lvl = T_TOP, .t = CAR(n)->val.type.t };
+ return (CAR(n)->val.type.t == T_INT && CDR(n)->val.type.t == T_INT)
+ || (CAR(n)->val.type.t == T_BOOL && CDR(n)->val.type.t == T_BOOL);
case N_OP_ADD: case N_OP_SUB: case N_OP_MUL: case N_OP_DIV:
case N_OP_SHL: case N_OP_SHR:
n->val.type = (Type) { .lvl = T_TOP, .t = T_INT };
- return n->in.data[0]->val.type.t == T_INT && n->in.data[1]->val.type.t == T_INT;
+ return CAR(n)->val.type.t == T_INT && CDR(n)->val.type.t == T_INT;
case N_CMP_LES: case N_CMP_GTR:
case N_CMP_LTE: case N_CMP_GTE:
n->val.type = (Type) { .lvl = T_TOP, .t = T_BOOL };
@@ -87,9 +90,9 @@ int type_check(Node *n) {
case N_CMP_EQL:
case N_CMP_NEQ:
n->val.type = (Type) { .lvl = T_TOP, .t = T_BOOL };
- return type_base_eql(&n->in.data[0]->val.type, &n->in.data[1]->val.type);
- /* (n->in.data[0]->val.type.t == T_INT && n->in.data[1]->val.type.t == T_INT)
- || (n->in.data[0]->val.type.t == T_BOOL && n->in.data[1]->val.type.t == T_BOOL); */
+ return type_base_eql(&CAR(n)->val.type, &CDR(n)->val.type);
+ /* (CAR(n)->val.type.t == T_INT && CDR(n)->val.type.t == T_INT)
+ || (CAR(n)->val.type.t == T_BOOL && CDR(n)->val.type.t == T_BOOL); */
default:
return 1;
}
@@ -445,13 +448,13 @@ static int node_equiv_input(Node *a, Node *b) {
/* note that this means the order of inputs isn't guaranteed, so be
* careful what you use this procedure for */
if ((node_op_communative(a->type) || node_op_communative(b->type))
- && node_equiv(a->in.data[1], b->in.data[0])
- && node_equiv(a->in.data[0], b->in.data[1])) {
+ && node_equiv(CDR(a), CAR(b))
+ && node_equiv(CAR(a), CDR(b))) {
/* assuming input count is 2 */
return 1;
}
for (int i = 0; i < a->in.len; i++) {
- if (!node_equiv(a->in.data[i], b->in.data[i])) return 0;
+ if (!node_equiv(IN(a, i), IN(b, i))) return 0;
}
return 1;
}
@@ -498,9 +501,9 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
int same = 1, same_ptr = 1;
for (int i = 1; i < n->in.len; i++) {
- if (n->in.data[i] == n->in.data[0]) continue;
+ if (IN(n, i) == CAR(n)) continue;
same_ptr = 0;
- if (!node_equiv(n->in.data[i], n->in.data[0])) {
+ if (!node_equiv(IN(n, i), CAR(n))) {
same = 0;
break;
}
@@ -509,7 +512,7 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
if (n->in.len > 1 && same && !same_ptr) {
Node *r = node_new_empty(p, n->type);
for (int i = 0; i < n->in.len; i++) {
- node_add(p, n->in.data[0], r);
+ node_add(p, CAR(n), r);
}
return node_peephole(r, p, l);
}