aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2014-11-05 15:40:21 +0800
committerChristian <c@ethdev.com>2014-11-06 09:44:43 +0800
commit627c80f0a8b37426c2c6625ff4852d77e4d43464 (patch)
tree496c5f2bdcd6d5c3bb92556081f707cdefac9d47
parentb5e77678c9257f97be89139cf1d12bfa178147ef (diff)
downloaddexon-solidity-627c80f0a8b37426c2c6625ff4852d77e4d43464.tar
dexon-solidity-627c80f0a8b37426c2c6625ff4852d77e4d43464.tar.gz
dexon-solidity-627c80f0a8b37426c2c6625ff4852d77e4d43464.tar.bz2
dexon-solidity-627c80f0a8b37426c2c6625ff4852d77e4d43464.tar.lz
dexon-solidity-627c80f0a8b37426c2c6625ff4852d77e4d43464.tar.xz
dexon-solidity-627c80f0a8b37426c2c6625ff4852d77e4d43464.tar.zst
dexon-solidity-627c80f0a8b37426c2c6625ff4852d77e4d43464.zip
Support for negative literals.
-rw-r--r--Scanner.cpp22
-rw-r--r--Scanner.h2
-rw-r--r--Types.cpp8
3 files changed, 17 insertions, 15 deletions
diff --git a/Scanner.cpp b/Scanner.cpp
index 63deba49..b13e52d7 100644
--- a/Scanner.cpp
+++ b/Scanner.cpp
@@ -271,7 +271,7 @@ void Scanner::scanToken()
token = Token::ADD;
break;
case '-':
- // - -- -=
+ // - -- -= Number
advance();
if (m_char == '-')
{
@@ -280,6 +280,8 @@ void Scanner::scanToken()
}
else if (m_char == '=')
token = selectToken(Token::ASSIGN_SUB);
+ else if (m_char == '.' || IsDecimalDigit(m_char))
+ token = scanNumber('-');
else
token = Token::SUB;
break;
@@ -331,7 +333,7 @@ void Scanner::scanToken()
// . Number
advance();
if (IsDecimalDigit(m_char))
- token = scanNumber(true);
+ token = scanNumber('.');
else
token = Token::PERIOD;
break;
@@ -372,7 +374,7 @@ void Scanner::scanToken()
if (IsIdentifierStart(m_char))
token = scanIdentifierOrKeyword();
else if (IsDecimalDigit(m_char))
- token = scanNumber(false);
+ token = scanNumber();
else if (skipWhitespace())
token = Token::WHITESPACE;
else if (isSourcePastEndOfInput())
@@ -461,14 +463,11 @@ void Scanner::scanDecimalDigits()
}
-Token::Value Scanner::scanNumber(bool _periodSeen)
+Token::Value Scanner::scanNumber(char _charSeen)
{
- // the first digit of the number or the fraction
- if (asserts(IsDecimalDigit(m_char)))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Number does not start with decimal digit."));
- enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL;
+ enum { DECIMAL, HEX, BINARY } kind = DECIMAL;
LiteralScope literal(this);
- if (_periodSeen)
+ if (_charSeen == '.')
{
// we have already seen a decimal point of the float
addLiteralChar('.');
@@ -476,12 +475,13 @@ Token::Value Scanner::scanNumber(bool _periodSeen)
}
else
{
+ if (_charSeen == '-')
+ addLiteralChar('-');
// if the first character is '0' we must check for octals and hex
if (m_char == '0')
{
addLiteralCharAndAdvance();
- // either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or
- // an octal number.
+ // either 0, 0exxx, 0Exxx, 0.xxx or a hex number
if (m_char == 'x' || m_char == 'X')
{
// hex number
diff --git a/Scanner.h b/Scanner.h
index 537c2434..997365f3 100644
--- a/Scanner.h
+++ b/Scanner.h
@@ -180,7 +180,7 @@ private:
Token::Value skipMultiLineComment();
void scanDecimalDigits();
- Token::Value scanNumber(bool _periodSeen);
+ Token::Value scanNumber(char _charSeen = 0);
Token::Value scanIdentifierOrKeyword();
Token::Value scanString();
diff --git a/Types.cpp b/Types.cpp
index 334f5044..7354255e 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -89,10 +89,14 @@ shared_ptr<Type> Type::forLiteral(Literal const& _literal)
shared_ptr<IntegerType> IntegerType::smallestTypeForLiteral(string const& _literal)
{
bigint value(_literal);
+ bool isSigned = value < 0 || (!_literal.empty() && _literal.front() == '-');
+ if (isSigned)
+ // convert to positive number of same bit requirements
+ value = ((-value) - 1) << 1;
unsigned bytes = max(bytesRequired(value), 1u);
if (bytes > 32)
return shared_ptr<IntegerType>();
- return make_shared<IntegerType>(bytes * 8, Modifier::UNSIGNED);
+ return make_shared<IntegerType>(bytes * 8, isSigned ? Modifier::SIGNED : Modifier::UNSIGNED);
}
IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
@@ -169,8 +173,6 @@ string IntegerType::toString() const
u256 IntegerType::literalValue(Literal const& _literal) const
{
bigint value(_literal.getValue());
- //@todo check that the number is not too large
- //@todo does this work for signed numbers?
return u256(value);
}