diff options
author | Christian <c@ethdev.com> | 2014-11-05 15:40:21 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2014-11-06 09:44:43 +0800 |
commit | 627c80f0a8b37426c2c6625ff4852d77e4d43464 (patch) | |
tree | 496c5f2bdcd6d5c3bb92556081f707cdefac9d47 | |
parent | b5e77678c9257f97be89139cf1d12bfa178147ef (diff) | |
download | dexon-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.cpp | 22 | ||||
-rw-r--r-- | Scanner.h | 2 | ||||
-rw-r--r-- | Types.cpp | 8 |
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 @@ -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); } |