aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLu Guanqun <guanqun.lu@gmail.com>2015-02-08 19:23:17 +0800
committerLu Guanqun <guanqun.lu@gmail.com>2015-02-10 23:39:13 +0800
commitd307b0914c4425ffbdf312b270a5528868915667 (patch)
treeacd96e9f0412bc57efa78dfeb194ac5edfb68d3c
parentcf4144b70246b53589b3238213f688244485f9b0 (diff)
downloaddexon-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.cpp3
-rw-r--r--Scanner.cpp10
-rw-r--r--Token.h5
-rw-r--r--Types.cpp10
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 '%':
// % %=
diff --git a/Token.h b/Token.h
index b913f0ce..ac8c618f 100644
--- a/Token.h
+++ b/Token.h
@@ -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)
diff --git a/Types.cpp b/Types.cpp
index 6fd9e8b4..dcc0738d 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -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();
}