nooc

nooc programming language compiler
git clone git://git.nihaljere.xyz/nooc
Log | Files | Refs | LICENSE

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:
Mmain.c | 20++++++++++----------
Mnooc.h | 18++++++++++--------
Mparse.c | 16++++++++--------
Mutil.c | 26+++++++++++++-------------
Mutil.h | 2+-
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, &regbuf, 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);