mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Support for negative literals.
This commit is contained in:
parent
b5e77678c9
commit
627c80f0a8
22
Scanner.cpp
22
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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user