mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
add exponent operator
https://www.pivotaltracker.com/n/projects/1189488/stories/83746404
This commit is contained in:
parent
cf4144b702
commit
d307b0914c
@ -650,6 +650,9 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty
|
|||||||
case Token::Mod:
|
case Token::Mod:
|
||||||
m_context << (c_isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD);
|
m_context << (c_isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD);
|
||||||
break;
|
break;
|
||||||
|
case Token::Exp:
|
||||||
|
m_context << eth::Instruction::EXP;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator."));
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator."));
|
||||||
}
|
}
|
||||||
|
10
Scanner.cpp
10
Scanner.cpp
@ -465,8 +465,14 @@ void Scanner::scanToken()
|
|||||||
token = Token::Sub;
|
token = Token::Sub;
|
||||||
break;
|
break;
|
||||||
case '*':
|
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;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
// % %=
|
// % %=
|
||||||
|
5
Token.h
5
Token.h
@ -118,6 +118,7 @@ namespace solidity
|
|||||||
T(Mul, "*", 13) \
|
T(Mul, "*", 13) \
|
||||||
T(Div, "/", 13) \
|
T(Div, "/", 13) \
|
||||||
T(Mod, "%", 13) \
|
T(Mod, "%", 13) \
|
||||||
|
T(Exp, "**", 14) \
|
||||||
\
|
\
|
||||||
/* Compare operators sorted by precedence. */ \
|
/* Compare operators sorted by precedence. */ \
|
||||||
/* IsCompareOp() relies on this block of enum values */ \
|
/* IsCompareOp() relies on this block of enum values */ \
|
||||||
@ -361,10 +362,10 @@ public:
|
|||||||
// Predicates
|
// Predicates
|
||||||
static bool isElementaryTypeName(Value tok) { return Int <= tok && tok < TypesEnd; }
|
static bool isElementaryTypeName(Value tok) { return Int <= tok && tok < TypesEnd; }
|
||||||
static bool isAssignmentOp(Value tok) { return Assign <= tok && tok <= AssignMod; }
|
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 ||
|
static bool isCommutativeOp(Value op) { return op == BitOr || op == BitXor || op == BitAnd ||
|
||||||
op == Add || op == Mul || op == Equal || op == NotEqual; }
|
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 bool isCompareOp(Value op) { return Equal <= op && op <= In; }
|
||||||
|
|
||||||
static Value AssignmentToBinaryOp(Value op)
|
static Value AssignmentToBinaryOp(Value op)
|
||||||
|
10
Types.cpp
10
Types.cpp
@ -320,6 +320,16 @@ TypePointer IntegerConstantType::binaryOperatorResult(Token::Value _operator, Ty
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
value = m_value % other.m_value;
|
value = m_value % other.m_value;
|
||||||
break;
|
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:
|
default:
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user