diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/ast/Types.cpp | 12 | ||||
-rw-r--r-- | libsolidity/parsing/Scanner.cpp | 8 | ||||
-rw-r--r-- | libsolidity/parsing/Token.cpp | 111 | ||||
-rw-r--r-- | libsolidity/parsing/Token.h | 32 |
4 files changed, 50 insertions, 113 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index f8050898..250ec102 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -118,20 +118,20 @@ u256 const& MemberList::storageSize() const TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) { string tokenString = _type.toString(); - solAssert(Token::isElementaryTypeName(_type.returnTok()), + solAssert(Token::isElementaryTypeName(_type.token()), "Expected an elementary type name but got " + tokenString); - Token::Value token = _type.returnTok(); - unsigned int M = _type.firstNumber(); + Token::Value token = _type.token(); + unsigned int m = _type.firstNumber(); switch (token) { case Token::IntM: - return make_shared<IntegerType>(M, IntegerType::Modifier::Signed); + return make_shared<IntegerType>(m, IntegerType::Modifier::Signed); case Token::UIntM: - return make_shared<IntegerType>(M, IntegerType::Modifier::Unsigned); + return make_shared<IntegerType>(m, IntegerType::Modifier::Unsigned); case Token::BytesM: - return make_shared<FixedBytesType>(M); + return make_shared<FixedBytesType>(m); case Token::Int: return make_shared<IntegerType>(256, IntegerType::Modifier::Signed); case Token::UInt: diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp index 510d283e..d630d0ab 100644 --- a/libsolidity/parsing/Scanner.cpp +++ b/libsolidity/parsing/Scanner.cpp @@ -387,8 +387,8 @@ void Scanner::scanToken() Token::Value token; // M and N are for the purposes of grabbing different type sizes - unsigned M; - unsigned N; + unsigned m; + unsigned n; do { // Remember the position of the next token @@ -556,7 +556,7 @@ void Scanner::scanToken() break; default: if (isIdentifierStart(m_char)) - tie(token, M, N) = scanIdentifierOrKeyword(); + tie(token, m, n) = scanIdentifierOrKeyword(); else if (isDecimalDigit(m_char)) token = scanNumber(); else if (skipWhitespace()) @@ -573,7 +573,7 @@ void Scanner::scanToken() while (token == Token::Whitespace); m_nextToken.location.end = sourcePos(); m_nextToken.token = token; - m_nextToken.extendedTokenInfo = make_tuple(M,N); + m_nextToken.extendedTokenInfo = make_tuple(m, n); } bool Scanner::scanEscape() diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp index b07b5c1b..693ed420 100644 --- a/libsolidity/parsing/Token.cpp +++ b/libsolidity/parsing/Token.cpp @@ -50,65 +50,26 @@ namespace dev namespace solidity { -void ElementaryTypeNameToken::parseDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second) +void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second) { solAssert(Token::isElementaryTypeName(_baseType), ""); - string baseType = Token::toString(_baseType); - if (_first == 0 && _second == 0) - { - m_name = baseType; - m_firstNumber = _first; - m_secondNumber = _second; - } - - if (baseType == "bytesM") + string tokenString = Token::toString(_baseType); + if (_baseType == Token::BytesM) { solAssert(_second == 0, "There should not be a second size argument to type bytesM."); - for (unsigned m = 1; m <= 32; m++) - if (m == _first) - { - m_name = baseType.substr(0, baseType.size()-1) + to_string(_first); - m_firstNumber = _first; - m_secondNumber = _second; - } + solAssert(_first <= 32, "No elementary type bytes" + to_string(_first) + "."); } - else if (baseType == "uintM" || baseType == "intM") + else if (_baseType == Token::UIntM || _baseType == Token::IntM) { - solAssert(_second == 0, "There should not be a second size argument to type " + baseType + "."); - for (unsigned m = 8; m <= 256; m+=8) - if (m == _first) - { - m_name = baseType.substr(0, baseType.size()-1) + to_string(_first); - m_firstNumber = _first; - m_secondNumber = _second; - } - } - else if (baseType == "ufixedMxN" || baseType == "fixedMxN") - { - for (unsigned m = 0; m <= 256; m+=8) - for (unsigned n = 8; m + n <= 256; n+=8) - if (m == _first && n == _second) - { - m_name = baseType.substr(0, baseType.size()-3) + - to_string(_first) + - "x" + - to_string(_second); - m_firstNumber = _first; - m_secondNumber = _second; - } + solAssert(_second == 0, "There should not be a second size argument to type " + tokenString + "."); + solAssert( + _first <= 256 && _first % 8 == 0, + "No elementary type " + tokenString + to_string(_first) + "." + ); } - - if (m_name.empty()) - BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << - errinfo_comment( - "Cannot create elementary type name token out of type " + - baseType + - " and size(s) " + - to_string(_first) + - " and " + - to_string(_second) - ) - ); + m_token = _baseType; + m_firstNumber = _first; + m_secondNumber = _second; } #define T(name, string, precedence) #name, @@ -141,11 +102,11 @@ char const Token::m_tokenType[] = { TOKEN_LIST(KT, KK) }; -unsigned Token::extractM(string _literal) +unsigned Token::extractM(string const& _literal) { try { - unsigned short m = stoi(_literal.substr(_literal.find_first_of("0123456789"))); + unsigned short m = stoi(_literal); return m; } catch(out_of_range& e) @@ -153,57 +114,31 @@ unsigned Token::extractM(string _literal) return 0; } } -pair<unsigned, unsigned> Token::extractMxN(string _literal) -{ - try - { - unsigned short m = stoi(_literal.substr(0, _literal.find_last_of("x") - 1)); - unsigned short n = stoi(_literal.substr(_literal.find_last_of("x") + 1)); - return make_pair(m, n); - } - catch (out_of_range& e) - { - return make_pair(0, 0); - } -} tuple<Token::Value, unsigned short, unsigned short> Token::fromIdentifierOrKeyword(string const& _literal) { - if (_literal.find_first_of("0123456789") != string::npos) + auto positionM = find_if(_literal.begin(), _literal.end(), ::isdigit); + if (positionM != _literal.end()) { - string baseType = _literal.substr(0, _literal.find_first_of("0123456789")); - if (baseType == "bytes") + string baseType(_literal.begin(), positionM); + auto positionX = find(positionM, _literal.end(), 'x'); + unsigned short m = extractM(string(positionM, positionX)); + if (baseType == toString(Token::Bytes)) { - unsigned short m = extractM(_literal); if (0 < m && m <= 32) return make_tuple(Token::BytesM, m, 0); return make_tuple(Token::Identifier, 0, 0); } - else if (baseType == "uint" || baseType == "int") + else if (baseType == toString(Token::UInt) || baseType == toString(Token::Int)) { - unsigned short m = extractM(_literal); if (0 < m && m <= 256 && m % 8 == 0) { - if (baseType == "uint") + if (baseType == toString(Token::UInt)) return make_tuple(Token::UIntM, m, 0); else return make_tuple(Token::IntM, m, 0); } return make_tuple(Token::Identifier, 0, 0); } - else if (baseType == "ufixed" || baseType == "fixed") - { - unsigned short m; - unsigned short n; - tie(m, n) = extractMxN(_literal); - if (0 < n + m && n + m <= 256 && ((n % 8 == 0) && (m % 8 == 0))) - { - if (baseType == "ufixed") - return make_tuple(Token::UFixedMxN, m, n); - else - return make_tuple(Token::FixedMxN, m, n); - } - return make_tuple(Token::Identifier, 0, 0); - } } // The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored // and keywords to be put inside the keywords variable. diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h index 7193627f..3de204e0 100644 --- a/libsolidity/parsing/Token.h +++ b/libsolidity/parsing/Token.h @@ -198,10 +198,8 @@ namespace solidity K(String, "string", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ - K(Fixed, "fixed", 0) \ - T(FixedMxN, "fixedMxN", 0) \ - K(UFixed, "ufixed", 0) \ - T(UFixedMxN, "ufixedMxN", 0) \ + K(Real, "real", 0) \ + K(UReal, "ureal", 0) \ T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ \ /* Literals */ \ @@ -305,11 +303,10 @@ public: static std::tuple<Token::Value, unsigned short, unsigned short> fromIdentifierOrKeyword(std::string const& _literal); private: - // extractM and extractMxN provide a safe way to extract numbers, + // extractM provides a safe way to extract numbers, // if out_of_range error is thrown, they returns 0s, therefore securing // the variable's identity as an identifier. - static unsigned extractM(std::string _literal); - static std::pair<unsigned, unsigned> extractMxN(std::string _literal); + static unsigned extractM(std::string const& _literal); static char const* const m_name[NUM_TOKENS]; static char const* const m_string[NUM_TOKENS]; static int8_t const m_precedence[NUM_TOKENS]; @@ -321,23 +318,28 @@ class ElementaryTypeNameToken public: ElementaryTypeNameToken(Token::Value _token, unsigned const& _firstNumber, unsigned const& _secondNumber) { - parseDetails(_token, _firstNumber, _secondNumber); - m_token = _token; + assertDetails(_token, _firstNumber, _secondNumber); } - unsigned int const& firstNumber() const { return m_firstNumber; } - unsigned int const& secondNumber() const { return m_secondNumber; } - Token::Value const& returnTok() const { return m_token; } + unsigned int firstNumber() const { return m_firstNumber; } + unsigned int secondNumber() const { return m_secondNumber; } + Token::Value token() const { return m_token; } ///if tokValue is set to true, then returns the actual token type name, otherwise, returns full type - std::string toString(bool const& tokValue = false) const { return tokValue ? Token::toString(m_token) : m_name; } + std::string toString(bool const& tokenValue = false) const + { + std::string name = Token::toString(m_token); + if (tokenValue || (firstNumber() == 0 && secondNumber() == 0)) + return name; + //need to set it up this way for fixed types construction in future + return name.substr(0, name.size() - 1) + std::to_string(m_firstNumber); + } private: Token::Value m_token; - std::string m_name; unsigned int m_firstNumber; unsigned int m_secondNumber; /// throws if type is not properly sized - void parseDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second); + void assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second); }; } |