commit 2a8af28e0f1f3dabb248c2f28a089780077cc7c1
parent 227eff85dc68dbd4941a1c5771172aca98654604
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Wed, 29 Dec 2021 14:57:27 -0600
expr: put left and right into binop struct inside union
Diffstat:
5 files changed, 42 insertions(+), 40 deletions(-)
diff --git a/main.c b/main.c
@@ -415,26 +415,26 @@ genexpr(char *buf, size_t idx, struct place *out)
total += place_move(buf ? buf + total : NULL, out, &src);
freereg(src.l.reg);
} else if (expr->kind == EXPR_BINARY) {
- total += genexpr(buf ? buf + total : buf, expr->left, out);
+ total += genexpr(buf ? buf + total : buf, expr->d.bop.left, out);
struct place place2 = { PLACE_REG, .size = 8, .l.reg = getreg() };
- total += genexpr(buf ? buf + total : buf, expr->right, &place2);
+ total += genexpr(buf ? buf + total : buf, expr->d.bop.right, &place2);
struct place regbuf = { PLACE_REG, .size = 8, .l.reg = getreg() };
total += place_move(buf ? buf + total : buf, ®buf, out);
// FIXME: abstract these to act on places, so that we can generate more efficient code
- switch (expr->d.op) {
- case OP_PLUS: {
+ switch (expr->d.bop.kind) {
+ case BOP_PLUS: {
total += add_r64_r64(buf ? buf + total : buf, regbuf.l.reg, place2.l.reg);
break;
}
- case OP_MINUS: {
+ case BOP_MINUS: {
total += sub_r64_r64(buf ? buf + total : buf, regbuf.l.reg, place2.l.reg);
break;
}
- case OP_EQUAL:
- case OP_GREATER: {
+ case BOP_EQUAL:
+ case BOP_GREATER: {
total += cmp_r64_r64(buf ? buf + total : buf, regbuf.l.reg, place2.l.reg);
break;
}
@@ -473,11 +473,11 @@ genexpr(char *buf, size_t idx, struct place *out)
total += genexpr(buf ? buf + total : NULL, expr->d.cond.cond, &tempplace);
size_t iflen = genblock(NULL, &expr->d.cond.bif, false) + jmp(NULL, 0);
size_t elselen = genblock(NULL, &expr->d.cond.belse, false);
- switch (binary->d.op) {
- case OP_GREATER:
+ switch (binary->d.bop.kind) {
+ case BOP_GREATER:
total += jng(buf ? buf + total : NULL, iflen);
break;
- case OP_EQUAL:
+ case BOP_EQUAL:
total += jne(buf ? buf + total : NULL, iflen);
break;
default:
diff --git a/nooc.h b/nooc.h
@@ -181,11 +181,15 @@ struct proc {
struct block block;
};
-enum binop {
- OP_PLUS,
- OP_MINUS,
- OP_GREATER,
- OP_EQUAL,
+struct binop {
+ enum {
+ BOP_PLUS,
+ BOP_MINUS,
+ BOP_GREATER,
+ BOP_EQUAL,
+ } kind;
+ size_t left;
+ size_t right;
};
struct value {
@@ -217,15 +221,13 @@ struct expr {
enum class class;
union {
struct value v;
- enum binop op;
+ struct binop bop;
struct slice s;
struct fcall call;
struct cond cond;
struct loop loop;
struct proc proc;
} d;
- size_t left;
- size_t right;
struct token *start;
};
diff --git a/parse.c b/parse.c
@@ -238,27 +238,27 @@ parseexpr(struct block *block)
break;
case TOK_EQUAL:
expr.kind = EXPR_BINARY;
- expr.d.op = OP_EQUAL;
+ expr.d.bop.kind = BOP_EQUAL;
goto binary_common;
case TOK_GREATER:
expr.kind = EXPR_BINARY;
- expr.d.op = OP_GREATER;
+ expr.d.bop.kind = BOP_GREATER;
goto binary_common;
case TOK_PLUS:
expr.kind = EXPR_BINARY;
- expr.d.op = OP_PLUS;
+ expr.d.bop.kind = BOP_PLUS;
goto binary_common;
case TOK_MINUS:
expr.kind = EXPR_BINARY;
- expr.d.op = OP_MINUS;
+ expr.d.bop.kind = BOP_MINUS;
binary_common:
expr.start = tok;
tok = tok->next;
- expr.left = parseexpr(block);
- expr.right = parseexpr(block);
- if (exprs.data[expr.left].class != exprs.data[expr.right].class)
+ expr.d.bop.left = parseexpr(block);
+ expr.d.bop.right = parseexpr(block);
+ if (exprs.data[expr.d.bop.left].class != exprs.data[expr.d.bop.right].class)
error(tok->line, tok->col, "expected binary expression operands to be of same class");
- expr.class = exprs.data[expr.left].class;
+ expr.class = exprs.data[expr.d.bop.left].class;
break;
case TOK_STRING:
parsestring(&expr);
diff --git a/util.c b/util.c
@@ -71,20 +71,20 @@ dumpval(struct expr *e)
}
void
-dumpbinop(enum binop op)
+dumpbinop(struct binop *op)
{
- switch (op) {
- case OP_PLUS:
- fprintf(stderr, "OP_PLUS");
+ switch (op->kind) {
+ case BOP_PLUS:
+ fprintf(stderr, "BOP_PLUS");
break;
- case OP_MINUS:
- fprintf(stderr, "OP_MINUS");
+ case BOP_MINUS:
+ fprintf(stderr, "BOP_MINUS");
break;
- case OP_GREATER:
- fprintf(stderr, "OP_GREATER");
+ case BOP_GREATER:
+ fprintf(stderr, "BOP_GREATER");
break;
- case OP_EQUAL:
- fprintf(stderr, "OP_EQUAL");
+ case BOP_EQUAL:
+ fprintf(stderr, "BOP_EQUAL");
break;
default:
die("invalid binop");
@@ -106,10 +106,10 @@ dumpexpr(int indent, struct expr *expr)
fputc('\n', stderr);
break;
case EXPR_BINARY:
- dumpbinop(expr->d.op);
+ dumpbinop(&expr->d.bop);
fputc('\n', stderr);
- dumpexpr(indent + 8, &exprs.data[expr->left]);
- dumpexpr(indent + 8, &exprs.data[expr->right]);
+ dumpexpr(indent + 8, &exprs.data[expr->d.bop.left]);
+ dumpexpr(indent + 8, &exprs.data[expr->d.bop.right]);
break;
case EXPR_COND:
dumpexpr(indent + 8, &exprs.data[expr->d.cond.cond]);
diff --git a/util.h b/util.h
@@ -1,6 +1,6 @@
char *exprkind_str(enum exprkind kind);
void dumpval(struct expr *e);
-void dumpbinop(enum binop op);
+void dumpbinop(struct binop *op);
void dumpexpr(int indent, struct expr *expr);
int slice_cmp(struct slice *s1, struct slice *s2);
int slice_cmplit(struct slice *s1, char *s2);