|
|
@@ -849,19 +849,19 @@ static void BinaryExpr__dtor(Expr* self_) {
|
|
|
vtdelete(self->rhs);
|
|
|
}
|
|
|
|
|
|
-static Opcode cmp_token2op(TokenIndex token) {
|
|
|
+static Opcode cmp_token2name(TokenIndex token) {
|
|
|
switch(token) {
|
|
|
- case TK_LT: return OP_COMPARE_LT; break;
|
|
|
- case TK_LE: return OP_COMPARE_LE; break;
|
|
|
- case TK_EQ: return OP_COMPARE_EQ; break;
|
|
|
- case TK_NE: return OP_COMPARE_NE; break;
|
|
|
- case TK_GT: return OP_COMPARE_GT; break;
|
|
|
- case TK_GE: return OP_COMPARE_GE; break;
|
|
|
- default: return OP_NO_OP; // 0
|
|
|
+ case TK_LT: return __lt__;
|
|
|
+ case TK_LE: return __le__;
|
|
|
+ case TK_EQ: return __eq__;
|
|
|
+ case TK_NE: return __ne__;
|
|
|
+ case TK_GT: return __gt__;
|
|
|
+ case TK_GE: return __ge__;
|
|
|
+ default: return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#define is_compare_expr(e) ((e)->vt->is_binary && cmp_token2op(((BinaryExpr*)(e))->op))
|
|
|
+#define is_compare_expr(e) ((e)->vt->is_binary && cmp_token2name(((BinaryExpr*)(e))->op))
|
|
|
|
|
|
static void _emit_compare(BinaryExpr* self, Ctx* ctx, c11_vector* jmps) {
|
|
|
if(is_compare_expr(self->lhs)) {
|
|
|
@@ -872,8 +872,7 @@ static void _emit_compare(BinaryExpr* self, Ctx* ctx, c11_vector* jmps) {
|
|
|
vtemit_(self->rhs, ctx); // [a, b]
|
|
|
Ctx__emit_(ctx, OP_DUP_TOP, BC_NOARG, self->line); // [a, b, b]
|
|
|
Ctx__emit_(ctx, OP_ROT_THREE, BC_NOARG, self->line); // [b, a, b]
|
|
|
- Opcode opcode = cmp_token2op(self->op);
|
|
|
- Ctx__emit_(ctx, opcode, BC_NOARG, self->line);
|
|
|
+ Ctx__emit_(ctx, OP_BINARY_OP, cmp_token2name(self->op), self->line);
|
|
|
// [b, RES]
|
|
|
int index = Ctx__emit_(ctx, OP_JUMP_IF_FALSE_OR_POP, BC_NOARG, self->line);
|
|
|
c11_vector__push(int, jmps, index);
|
|
|
@@ -883,7 +882,7 @@ static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) {
|
|
|
BinaryExpr* self = (BinaryExpr*)self_;
|
|
|
c11_vector /*T=int*/ jmps;
|
|
|
c11_vector__ctor(&jmps, sizeof(int));
|
|
|
- if(cmp_token2op(self->op) && is_compare_expr(self->lhs)) {
|
|
|
+ if(cmp_token2name(self->op) && is_compare_expr(self->lhs)) {
|
|
|
// (a < b) < c
|
|
|
BinaryExpr* e = (BinaryExpr*)self->lhs;
|
|
|
_emit_compare(e, ctx, &jmps);
|
|
|
@@ -906,22 +905,34 @@ static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) {
|
|
|
case TK_ADD: arg = __add__ | (__radd__ << 8); break;
|
|
|
case TK_SUB: arg = __sub__ | (__rsub__ << 8); break;
|
|
|
case TK_MUL: arg = __mul__ | (__rmul__ << 8); break;
|
|
|
- case TK_DIV: arg = __truediv__; break;
|
|
|
- case TK_FLOORDIV: arg = __floordiv__; break;
|
|
|
- case TK_MOD: arg = __mod__; break;
|
|
|
- case TK_POW: arg = __pow__; break;
|
|
|
-
|
|
|
- case TK_LT: opcode = OP_COMPARE_LT; break;
|
|
|
- case TK_LE: opcode = OP_COMPARE_LE; break;
|
|
|
- case TK_EQ: opcode = OP_COMPARE_EQ; break;
|
|
|
- case TK_NE: opcode = OP_COMPARE_NE; break;
|
|
|
- case TK_GT: opcode = OP_COMPARE_GT; break;
|
|
|
- case TK_GE: opcode = OP_COMPARE_GE; break;
|
|
|
-
|
|
|
- case TK_IN: opcode = OP_IN_OP; break;
|
|
|
- case TK_NOT_IN: opcode = OP_NOT_IN_OP; break;
|
|
|
- case TK_IS: opcode = OP_IS_OP; break;
|
|
|
- case TK_IS_NOT: opcode = OP_IS_NOT_OP; break;
|
|
|
+ case TK_DIV: arg = __truediv__ | (__rtruediv__ << 8); break;
|
|
|
+ case TK_FLOORDIV: arg = __floordiv__ | (__rfloordiv__ << 8); break;
|
|
|
+ case TK_MOD: arg = __mod__ | (__rmod__ << 8); break;
|
|
|
+ case TK_POW: arg = __pow__ | (__rpow__ << 8); break;
|
|
|
+
|
|
|
+ case TK_LT: arg = __lt__ | (__gt__ << 8); break;
|
|
|
+ case TK_LE: arg = __le__ | (__ge__ << 8); break;
|
|
|
+ case TK_EQ: arg = __eq__ | (__eq__ << 8); break;
|
|
|
+ case TK_NE: arg = __ne__ | (__ne__ << 8); break;
|
|
|
+ case TK_GT: arg = __gt__ | (__lt__ << 8); break;
|
|
|
+ case TK_GE: arg = __ge__ | (__le__ << 8); break;
|
|
|
+
|
|
|
+ case TK_IN:
|
|
|
+ opcode = OP_CONTAINS_OP;
|
|
|
+ arg = 0;
|
|
|
+ break;
|
|
|
+ case TK_NOT_IN:
|
|
|
+ opcode = OP_CONTAINS_OP;
|
|
|
+ arg = 1;
|
|
|
+ break;
|
|
|
+ case TK_IS:
|
|
|
+ opcode = OP_IS_OP;
|
|
|
+ arg = 0;
|
|
|
+ break;
|
|
|
+ case TK_IS_NOT:
|
|
|
+ opcode = OP_IS_OP;
|
|
|
+ arg = 1;
|
|
|
+ break;
|
|
|
|
|
|
case TK_LSHIFT: arg = __lshift__; break;
|
|
|
case TK_RSHIFT: arg = __rshift__; break;
|
|
|
@@ -1734,8 +1745,13 @@ static Error* exprBinaryOp(Compiler* self) {
|
|
|
TokenIndex op = prev()->type;
|
|
|
check(parse_expression(self, rules[op].precedence + 1, false));
|
|
|
BinaryExpr* e = BinaryExpr__new(line, op, false);
|
|
|
- e->rhs = Ctx__s_popx(ctx());
|
|
|
- e->lhs = Ctx__s_popx(ctx());
|
|
|
+ if(op == TK_IN || op == TK_NOT_IN) {
|
|
|
+ e->lhs = Ctx__s_popx(ctx());
|
|
|
+ e->rhs = Ctx__s_popx(ctx());
|
|
|
+ } else {
|
|
|
+ e->rhs = Ctx__s_popx(ctx());
|
|
|
+ e->lhs = Ctx__s_popx(ctx());
|
|
|
+ }
|
|
|
Ctx__s_push(ctx(), (Expr*)e);
|
|
|
return NULL;
|
|
|
}
|