diff --git a/src/Expr.cc b/src/Expr.cc index b1f6922565..98965ec380 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -211,6 +211,11 @@ ExprPtr Expr::MakeLvalue() return {NewRef{}, this}; } +bool Expr::InvertSense() + { + return false; + } + void Expr::EvalIntoAggregate(const zeek::Type* /* t */, Val* /* aggr */, Frame* /* f */) const { @@ -2043,6 +2048,12 @@ ValPtr EqExpr::Fold(Val* v1, Val* v2) const return BinaryExpr::Fold(v1, v2); } +bool EqExpr::InvertSense() + { + tag = (tag == EXPR_EQ ? EXPR_NE : EXPR_EQ); + return true; + } + RelExpr::RelExpr(BroExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) : BinaryExpr(arg_tag, std::move(arg_op1), std::move(arg_op2)) { @@ -2100,6 +2111,19 @@ void RelExpr::Canonicize() } } +bool RelExpr::InvertSense() + { + switch ( tag ) { + case EXPR_LT: tag = EXPR_GE; return true; + case EXPR_LE: tag = EXPR_GT; return true; + case EXPR_GE: tag = EXPR_LT; return true; + case EXPR_GT: tag = EXPR_LE; return true; + + default: + return false; + } + } + CondExpr::CondExpr(ExprPtr arg_op1, ExprPtr arg_op2, ExprPtr arg_op3) : Expr(EXPR_COND), op1(std::move(arg_op1)), op2(std::move(arg_op2)), op3(std::move(arg_op3)) diff --git a/src/Expr.h b/src/Expr.h index 64430465c8..91a0cc3750 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -197,6 +197,11 @@ public: // the current value of expr (this is the default method). virtual ExprPtr MakeLvalue(); + // Invert the sense of the operation. Returns true if the expression + // was invertible (currently only true for relational/equality + // expressions), false otherwise. + virtual bool InvertSense(); + // Marks the expression as one requiring (or at least appearing // with) parentheses. Used for pretty-printing. void MarkParen() { paren = true; } @@ -791,6 +796,7 @@ public: ExprPtr Duplicate() override; bool WillTransform(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + bool InvertSense() override; protected: ValPtr Fold(Val* v1, Val* v2) const override; @@ -805,6 +811,7 @@ public: ExprPtr Duplicate() override; bool WillTransform(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + bool InvertSense() override; }; class CondExpr final : public Expr {