From cee13fbec0745bed52f52e5cf97a6266df1a0c7c Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 25 Nov 2014 17:04:20 +0100 Subject: [PATCH] Implement the %, ^, %=, ^=, &= and |= operators fixes #7813 --- lib/config/config_lexer.ll | 6 ++++++ lib/config/config_parser.yy | 15 ++++++++++++++- lib/config/expression.cpp | 22 ++++++++++++++++++++++ lib/config/expression.hpp | 30 ++++++++++++++++++++++++++++-- 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index de8c39364..8f17c33b4 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -278,10 +278,16 @@ in return T_IN; -= { yylval->csop = OpSetSubtract; return T_SET_SUBTRACT; } \*= { yylval->csop = OpSetMultiply; return T_SET_MULTIPLY; } \/= { yylval->csop = OpSetDivide; return T_SET_DIVIDE; } +\%= { yylval->csop = OpSetModulo; return T_SET_MODULO; } +\^= { yylval->csop = OpSetXor; return T_SET_XOR; } +\&= { yylval->csop = OpSetBinaryAnd; return T_SET_BINARY_AND; } +\|= { yylval->csop = OpSetBinaryOr; return T_SET_BINARY_OR; } \+ return T_PLUS; \- return T_MINUS; \* return T_MULTIPLY; \/ return T_DIVIDE_OP; +\% return T_MODULO; +\^ return T_XOR; \& return T_BINARY_AND; \| return T_BINARY_OR; \< return T_LESS_THAN; diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 43f0899d2..1d6679c66 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -114,6 +114,10 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig %token T_SET_SUBTRACT "-= (T_SET_SUBTRACT)" %token T_SET_MULTIPLY "*= (T_SET_MULTIPLY)" %token T_SET_DIVIDE "/= (T_SET_DIVIDE)" +%token T_SET_MODULO "%= (T_SET_MODULO)" +%token T_SET_XOR "^= (T_SET_XOR)" +%token T_SET_BINARY_AND "&= (T_SET_BINARY_AND)" +%token T_SET_BINARY_OR "|= (T_SET_BINARY_OR)" %token T_SHIFT_LEFT "<< (T_SHIFT_LEFT)" %token T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)" @@ -129,6 +133,8 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig %token T_MINUS "- (T_MINUS)" %token T_MULTIPLY "* (T_MULTIPLY)" %token T_DIVIDE_OP "/ (T_DIVIDE_OP)" +%token T_MODULO "% (T_MODULO)" +%token T_XOR "^ (T_XOR)" %token T_BINARY_AND "& (T_BINARY_AND)" %token T_BINARY_OR "| (T_BINARY_OR)" %token T_LESS_THAN "< (T_LESS_THAN)" @@ -203,8 +209,9 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig %left T_LOGICAL_AND %left T_LOCAL T_RETURN %left T_IDENTIFIER -%left T_SET T_SET_ADD T_SET_SUBTRACT T_SET_MULTIPLY T_SET_DIVIDE +%left T_SET T_SET_ADD T_SET_SUBTRACT T_SET_MULTIPLY T_SET_DIVIDE T_SET_MODULO T_SET_XOR T_SET_BINARY_AND T_SET_BINARY_OR %left T_BINARY_OR +%left T_XOR T_MODULO %left T_BINARY_AND %left T_IN T_NOT_IN %nonassoc T_EQUAL T_NOT_EQUAL @@ -560,6 +567,10 @@ combined_set_op: T_SET | T_SET_SUBTRACT | T_SET_MULTIPLY | T_SET_DIVIDE + | T_SET_MODULO + | T_SET_XOR + | T_SET_BINARY_AND + | T_SET_BINARY_OR { $$ = $1; } @@ -802,6 +813,8 @@ rterm_without_indexer: T_STRING | rterm T_MINUS rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } | rterm T_MULTIPLY rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } | rterm T_DIVIDE_OP rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_MODULO rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_XOR rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } | T_FUNCTION identifier '(' identifier_items ')' use_specifier rterm_scope { DictExpression *aexpr = dynamic_cast($7); diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index 895e00026..8fcdcd177 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -124,6 +124,16 @@ Value DivideExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const return m_Operand1->Evaluate(frame) / m_Operand2->Evaluate(frame); } +Value ModuloExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const +{ + return (long)m_Operand1->Evaluate(frame) % (long)m_Operand2->Evaluate(frame); +} + +Value XorExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const +{ + return (long)m_Operand1->Evaluate(frame) ^ (long)m_Operand2->Evaluate(frame); +} + Value BinaryAndExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const { return m_Operand1->Evaluate(frame) & m_Operand2->Evaluate(frame); @@ -337,6 +347,18 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const case OpSetDivide: right = DivideExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint); break; + case OpSetModulo: + right = ModuloExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint); + break; + case OpSetXor: + right = XorExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint); + break; + case OpSetBinaryAnd: + right = BinaryAndExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint); + break; + case OpSetBinaryOr: + right = BinaryOrExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint); + break; default: VERIFY(!"Invalid opcode."); } diff --git a/lib/config/expression.hpp b/lib/config/expression.hpp index f7ef9deea..e98c69745 100644 --- a/lib/config/expression.hpp +++ b/lib/config/expression.hpp @@ -98,7 +98,11 @@ enum CombinedSetOp OpSetAdd, OpSetSubtract, OpSetMultiply, - OpSetDivide + OpSetDivide, + OpSetModulo, + OpSetXor, + OpSetBinaryAnd, + OpSetBinaryOr }; class InterruptExecutionError : virtual public std::exception, virtual public boost::exception @@ -309,7 +313,29 @@ public: protected: virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const; }; - + +class I2_CONFIG_API ModuloExpression : public BinaryExpression +{ +public: + ModuloExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo = DebugInfo()) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const; +}; + +class I2_CONFIG_API XorExpression : public BinaryExpression +{ +public: + XorExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo = DebugInfo()) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const; +}; + class I2_CONFIG_API BinaryAndExpression : public BinaryExpression { public: