add exponent operator

https://www.pivotaltracker.com/n/projects/1189488/stories/83746404
This commit is contained in:
Lu Guanqun 2015-02-08 19:23:17 +08:00
parent cf4144b702
commit d307b0914c
4 changed files with 24 additions and 4 deletions

View File

@ -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."));
}

View File

@ -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 '%':
// % %=

View File

@ -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)

View File

@ -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();
}