diff options
author | Lu Guanqun <guanqun.lu@gmail.com> | 2015-02-08 19:23:17 +0800 |
---|---|---|
committer | Lu Guanqun <guanqun.lu@gmail.com> | 2015-02-10 23:39:13 +0800 |
commit | d307b0914c4425ffbdf312b270a5528868915667 (patch) | |
tree | acd96e9f0412bc57efa78dfeb194ac5edfb68d3c | |
parent | cf4144b70246b53589b3238213f688244485f9b0 (diff) | |
download | dexon-solidity-d307b0914c4425ffbdf312b270a5528868915667.tar dexon-solidity-d307b0914c4425ffbdf312b270a5528868915667.tar.gz dexon-solidity-d307b0914c4425ffbdf312b270a5528868915667.tar.bz2 dexon-solidity-d307b0914c4425ffbdf312b270a5528868915667.tar.lz dexon-solidity-d307b0914c4425ffbdf312b270a5528868915667.tar.xz dexon-solidity-d307b0914c4425ffbdf312b270a5528868915667.tar.zst dexon-solidity-d307b0914c4425ffbdf312b270a5528868915667.zip |
add exponent operator
https://www.pivotaltracker.com/n/projects/1189488/stories/83746404
-rw-r--r-- | ExpressionCompiler.cpp | 3 | ||||
-rw-r--r-- | Scanner.cpp | 10 | ||||
-rw-r--r-- | Token.h | 5 | ||||
-rw-r--r-- | Types.cpp | 10 |
4 files changed, 24 insertions, 4 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 1d3f23e6..beda0132 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -650,6 +650,9 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty case Token::Mod: m_context << (c_isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD); break; + case Token::Exp: + m_context << eth::Instruction::EXP; + break; default: BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator.")); } diff --git a/Scanner.cpp b/Scanner.cpp index fc4bdb6b..fbe3ea97 100644 --- a/Scanner.cpp +++ b/Scanner.cpp @@ -465,8 +465,14 @@ void Scanner::scanToken() token = Token::Sub; break; case '*': - // * *= - token = selectToken('=', Token::AssignMul, Token::Mul); + // * ** *= + advance(); + if (m_char == '*') + token = selectToken(Token::Exp); + else if (m_char == '=') + token = selectToken(Token::AssignMul); + else + token = Token::Mul; break; case '%': // % %= @@ -118,6 +118,7 @@ namespace solidity T(Mul, "*", 13) \ T(Div, "/", 13) \ T(Mod, "%", 13) \ + T(Exp, "**", 14) \ \ /* Compare operators sorted by precedence. */ \ /* IsCompareOp() relies on this block of enum values */ \ @@ -361,10 +362,10 @@ public: // Predicates static bool isElementaryTypeName(Value tok) { return Int <= tok && tok < TypesEnd; } static bool isAssignmentOp(Value tok) { return Assign <= tok && tok <= AssignMod; } - static bool isBinaryOp(Value op) { return Comma <= op && op <= Mod; } + static bool isBinaryOp(Value op) { return Comma <= op && op <= Exp; } static bool isCommutativeOp(Value op) { return op == BitOr || op == BitXor || op == BitAnd || op == Add || op == Mul || op == Equal || op == NotEqual; } - static bool isArithmeticOp(Value op) { return Add <= op && op <= Mod; } + static bool isArithmeticOp(Value op) { return Add <= op && op <= Exp; } static bool isCompareOp(Value op) { return Equal <= op && op <= In; } static Value AssignmentToBinaryOp(Value op) @@ -320,6 +320,16 @@ TypePointer IntegerConstantType::binaryOperatorResult(Token::Value _operator, Ty return TypePointer(); value = m_value % other.m_value; break; + case Token::Exp: + if (other.m_value < 0) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("exponent can't be negative")); + else + { + value = boost::multiprecision::powm(m_value, other.m_value, bigint(2) << 256); + if (value >= (bigint(1) << 256)) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("exp result overflowed")); + } + break; default: return TypePointer(); } |