From 7b918a7bc7a3c619682266b1c2566dacb9dcc765 Mon Sep 17 00:00:00 2001 From: RJ Catalano Date: Mon, 8 Feb 2016 15:43:22 -0600 Subject: [PATCH 1/5] changes to redefine the token list, the scanner, and the parser and how they pass around variable types of different sizes not ready for change to FixedPoint just yet made this more const correct and added a switch statement for easier reading --- libsolidity/analysis/TypeChecker.cpp | 2 +- libsolidity/ast/AST.h | 25 +- libsolidity/ast/ASTJsonConverter.cpp | 4 +- libsolidity/ast/ASTPrinter.cpp | 4 +- libsolidity/ast/Types.cpp | 66 +++--- libsolidity/ast/Types.h | 2 +- libsolidity/parsing/Parser.cpp | 26 ++- libsolidity/parsing/Scanner.cpp | 37 ++- libsolidity/parsing/Scanner.h | 4 +- libsolidity/parsing/Token.cpp | 40 +++- libsolidity/parsing/Token.h | 132 +++-------- test/libsolidity/SolidityEndToEndTest.cpp | 4 +- .../SolidityNameAndTypeResolution.cpp | 213 +++++++++--------- test/libsolidity/SolidityTypes.cpp | 18 +- 14 files changed, 284 insertions(+), 293 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 857d55303..44f4629b1 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1394,7 +1394,7 @@ bool TypeChecker::visit(Identifier const& _identifier) void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr) { - _expr.annotation().type = make_shared(Type::fromElementaryTypeName(_expr.typeToken())); + _expr.annotation().type = make_shared(Type::fromElementaryTypeName(_expr.typeName())); } void TypeChecker::endVisit(Literal const& _literal) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index e10634676..d32d76a4b 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -756,18 +756,17 @@ public: class ElementaryTypeName: public TypeName { public: - ElementaryTypeName(SourceLocation const& _location, Token::Value _type): - TypeName(_location), m_type(_type) - { - solAssert(Token::isElementaryTypeName(_type), ""); - } + ElementaryTypeName(SourceLocation const& _location, ElementaryTypeNameToken const& _elem): + TypeName(_location), m_type(_elem) + {} + virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - Token::Value typeName() const { return m_type; } + ElementaryTypeNameToken const& typeName() const { return m_type; } private: - Token::Value m_type; + ElementaryTypeNameToken m_type; }; /** @@ -1408,18 +1407,16 @@ private: class ElementaryTypeNameExpression: public PrimaryExpression { public: - ElementaryTypeNameExpression(SourceLocation const& _location, Token::Value _typeToken): - PrimaryExpression(_location), m_typeToken(_typeToken) - { - solAssert(Token::isElementaryTypeName(_typeToken), ""); - } + ElementaryTypeNameExpression(SourceLocation const& _location, ElementaryTypeNameToken const& _type): + PrimaryExpression(_location), m_typeToken(_type) + {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - Token::Value typeToken() const { return m_typeToken; } + ElementaryTypeNameToken const& typeName() const { return m_typeToken; } private: - Token::Value m_typeToken; + ElementaryTypeNameToken m_typeToken; }; /** diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index df836afe2..163e22f45 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -139,7 +139,7 @@ bool ASTJsonConverter::visit(TypeName const&) bool ASTJsonConverter::visit(ElementaryTypeName const& _node) { - addJsonNode("ElementaryTypeName", { make_pair("name", Token::toString(_node.typeName())) }); + addJsonNode("ElementaryTypeName", { make_pair("name", _node.typeName().toString()) }); return true; } @@ -297,7 +297,7 @@ bool ASTJsonConverter::visit(Identifier const& _node) bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) { addJsonNode("ElementaryTypenameExpression", - { make_pair("value", Token::toString(_node.typeToken())), make_pair("type", type(_node)) }); + { make_pair("value", _node.typeName().toString()), make_pair("type", type(_node)) }); return true; } diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp index bc981f7d0..283bc8f90 100644 --- a/libsolidity/ast/ASTPrinter.cpp +++ b/libsolidity/ast/ASTPrinter.cpp @@ -145,7 +145,7 @@ bool ASTPrinter::visit(TypeName const& _node) bool ASTPrinter::visit(ElementaryTypeName const& _node) { - writeLine(string("ElementaryTypeName ") + Token::toString(_node.typeName())); + writeLine(string("ElementaryTypeName ") + _node.typeName().toString()); printSourcePart(_node); return goDeeper(); } @@ -331,7 +331,7 @@ bool ASTPrinter::visit(Identifier const& _node) bool ASTPrinter::visit(ElementaryTypeNameExpression const& _node) { - writeLine(string("ElementaryTypeNameExpression ") + Token::toString(_node.typeToken())); + writeLine(string("ElementaryTypeNameExpression ") + _node.typeName().toString()); printType(_node); printSourcePart(_node); return goDeeper(); diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index c889e6a05..df96d412f 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -115,51 +115,55 @@ u256 const& MemberList::storageSize() const return m_storageOffsets->storageSize(); } -TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) +TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) { - char const* tokenCstr = Token::toString(_typeToken); - solAssert(Token::isElementaryTypeName(_typeToken), - "Expected an elementary type name but got " + ((tokenCstr) ? string(Token::toString(_typeToken)) : "")); + string tokenString = _type.toString(); + solAssert(Token::isElementaryTypeName(_type.returnTok()), + "Expected an elementary type name but got " + tokenString); - if (Token::Int <= _typeToken && _typeToken <= Token::Bytes32) + Token::Value token = _type.returnTok(); + unsigned int M = _type.returnM(); + + switch (token) { - int offset = _typeToken - Token::Int; - int bytes = offset % 33; - if (bytes == 0 && _typeToken != Token::Bytes1) - bytes = 32; - int modifier = offset / 33; - switch(modifier) - { - case 0: - return make_shared(bytes * 8, IntegerType::Modifier::Signed); - case 1: - return make_shared(bytes * 8, IntegerType::Modifier::Unsigned); - case 2: - return make_shared(bytes + 1); - default: - solAssert(false, "Unexpected modifier value. Should never happen"); - return TypePointer(); - } - } - else if (_typeToken == Token::Byte) + case Token::IntM: + return make_shared(M, IntegerType::Modifier::Signed); + case Token::UIntM: + return make_shared(M, IntegerType::Modifier::Unsigned); + case Token::BytesM: + return make_shared(M); + case Token::Int: + return make_shared(256, IntegerType::Modifier::Signed); + case Token::UInt: + return make_shared(256, IntegerType::Modifier::Unsigned); + case Token::Byte: return make_shared(1); - else if (_typeToken == Token::Address) + case Token::Address: return make_shared(0, IntegerType::Modifier::Address); - else if (_typeToken == Token::Bool) + case Token::Bool: return make_shared(); - else if (_typeToken == Token::Bytes) + case Token::Bytes: return make_shared(DataLocation::Storage); - else if (_typeToken == Token::String) + case Token::String: return make_shared(DataLocation::Storage, true); - else + //no types found + default: BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment( - "Unable to convert elementary typename " + string(Token::toString(_typeToken)) + " to type." + "Unable to convert elementary typename " + _type.toString() + " to type." )); + } } TypePointer Type::fromElementaryTypeName(string const& _name) { - return fromElementaryTypeName(Token::fromIdentifierOrKeyword(_name)); + string keyword = _name.substr(0, _name.find_first_of("0123456789")); + string info = ""; + if (_name.find_first_of("0123456789") != string::npos) + { + keyword += "M"; + info = _name.substr(_name.find_first_of("0123456789")); + } + return fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword(keyword), info)); } TypePointer Type::forLiteral(Literal const& _literal) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 90a0509b2..b4a2d5739 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -140,7 +140,7 @@ public: /// @{ /// @name Factory functions /// Factory functions that convert an AST @ref TypeName to a Type. - static TypePointer fromElementaryTypeName(Token::Value _typeToken); + static TypePointer fromElementaryTypeName(ElementaryTypeNameToken const& _type); static TypePointer fromElementaryTypeName(std::string const& _name); /// @} diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index d9ec1a49f..9f944a0c5 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -194,7 +194,8 @@ ASTPointer Parser::parseContractDefinition(bool _isLibrary) expectToken(Token::LBrace); while (true) { - Token::Value currentTokenValue= m_scanner->currentToken(); + Token::Value currentTokenValue = m_scanner->currentToken(); + string lit = m_scanner->currentLiteral(); if (currentTokenValue == Token::RBrace) break; else if (currentTokenValue == Token::Function) @@ -590,7 +591,8 @@ ASTPointer Parser::parseTypeName(bool _allowVar) Token::Value token = m_scanner->currentToken(); if (Token::isElementaryTypeName(token)) { - type = ASTNodeFactory(*this).createNode(token); + ElementaryTypeNameToken elemTypeName(token, m_scanner->currentTokenInfo()); + type = ASTNodeFactory(*this).createNode(elemTypeName); m_scanner->next(); } else if (token == Token::Var) @@ -626,10 +628,12 @@ ASTPointer Parser::parseMapping() ASTNodeFactory nodeFactory(*this); expectToken(Token::Mapping); expectToken(Token::LParen); - if (!Token::isElementaryTypeName(m_scanner->currentToken())) - fatalParserError(string("Expected elementary type name for mapping key type")); ASTPointer keyType; - keyType = ASTNodeFactory(*this).createNode(m_scanner->currentToken()); + if (Token::isElementaryTypeName(m_scanner->currentToken())) + keyType = ASTNodeFactory(*this).createNode + (ElementaryTypeNameToken(m_scanner->currentToken(), m_scanner->currentTokenInfo())); + else + fatalParserError(string("Expected elementary type name for mapping key type")); m_scanner->next(); expectToken(Token::Arrow); bool const allowVar = false; @@ -815,12 +819,10 @@ ASTPointer Parser::parseSimpleStatement(ASTPointer const& default: break; } - // At this point, we have 'Identifier "["' or 'Identifier "." Identifier' or 'ElementoryTypeName "["'. // We parse '(Identifier ("." Identifier)* |ElementaryTypeName) ( "[" Expression "]" )+' // until we can decide whether to hand this over to ExpressionStatement or create a // VariableDeclarationStatement out of it. - vector> path; bool startedWithElementary = false; if (m_scanner->currentToken() == Token::Identifier) @@ -828,7 +830,8 @@ ASTPointer Parser::parseSimpleStatement(ASTPointer const& else { startedWithElementary = true; - path.push_back(ASTNodeFactory(*this).createNode(m_scanner->currentToken())); + ElementaryTypeNameToken elemToken(m_scanner->currentToken(), m_scanner->currentTokenInfo()); + path.push_back(ASTNodeFactory(*this).createNode(elemToken)); m_scanner->next(); } while (!startedWithElementary && m_scanner->currentToken() == Token::Period) @@ -1066,6 +1069,7 @@ ASTPointer Parser::parsePrimaryExpression() ASTNodeFactory nodeFactory(*this); Token::Value token = m_scanner->currentToken(); ASTPointer expression; + switch (token) { case Token::TrueLiteral: @@ -1134,8 +1138,8 @@ ASTPointer Parser::parsePrimaryExpression() default: if (Token::isElementaryTypeName(token)) { - // used for casts - expression = nodeFactory.createNode(token); + ElementaryTypeNameToken elementaryExpression(m_scanner->currentToken(), m_scanner->currentTokenInfo()); + expression = nodeFactory.createNode(elementaryExpression); m_scanner->next(); } else @@ -1226,7 +1230,7 @@ ASTPointer Parser::typeNameIndexAccessStructure( if (auto typeName = dynamic_cast(_path.front().get())) { solAssert(_path.size() == 1, ""); - type = nodeFactory.createNode(typeName->typeToken()); + type = nodeFactory.createNode(typeName->typeName()); } else { diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp index fe0807d52..5d40e55b9 100644 --- a/libsolidity/parsing/Scanner.cpp +++ b/libsolidity/parsing/Scanner.cpp @@ -82,13 +82,9 @@ bool isWhiteSpace(char c) { return c == ' ' || c == '\n' || c == '\t' || c == '\r'; } -bool isIdentifierStart(char c) -{ - return c == '_' || c == '$' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); -} bool isIdentifierPart(char c) { - return isIdentifierStart(c) || isDecimalDigit(c); + return c == '_' || c == '$' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); } int hexValue(char c) @@ -382,8 +378,12 @@ Token::Value Scanner::scanSlash() void Scanner::scanToken() { m_nextToken.literal.clear(); + m_nextToken.extendedTokenInfo.clear(); m_nextSkippedComment.literal.clear(); + m_nextSkippedComment.extendedTokenInfo.clear(); + Token::Value token; + string tokenExtension = ""; do { // Remember the position of the next token @@ -550,8 +550,8 @@ void Scanner::scanToken() token = selectToken(Token::BitNot); break; default: - if (isIdentifierStart(m_char)) - token = scanIdentifierOrKeyword(); + if (isIdentifierPart(m_char)) + tie(token, tokenExtension) = scanIdentifierOrKeyword(); else if (isDecimalDigit(m_char)) token = scanNumber(); else if (skipWhitespace()) @@ -568,6 +568,7 @@ void Scanner::scanToken() while (token == Token::Whitespace); m_nextToken.location.end = sourcePos(); m_nextToken.token = token; + m_nextToken.extendedTokenInfo = tokenExtension; } bool Scanner::scanEscape() @@ -699,22 +700,34 @@ Token::Value Scanner::scanNumber(char _charSeen) // not be an identifier start or a decimal digit; see ECMA-262 // section 7.8.3, page 17 (note that we read only one decimal digit // if the value is 0). - if (isDecimalDigit(m_char) || isIdentifierStart(m_char)) + if (isDecimalDigit(m_char) || isIdentifierPart(m_char)) return Token::Illegal; literal.complete(); return Token::Number; } -Token::Value Scanner::scanIdentifierOrKeyword() +tuple Scanner::scanIdentifierOrKeyword() { - solAssert(isIdentifierStart(m_char), ""); + solAssert(isIdentifierPart(m_char), ""); LiteralScope literal(this, LITERAL_TYPE_STRING); addLiteralCharAndAdvance(); // Scan the rest of the identifier characters. - while (isIdentifierPart(m_char)) + string keyword = ""; + string description = ""; + while (isIdentifierPart(m_char)) //get main keyword + addLiteralCharAndAdvance(); + keyword = m_nextToken.literal; + while (isDecimalDigit(m_char) || isIdentifierPart(m_char)) //get the description addLiteralCharAndAdvance(); literal.complete(); - return Token::fromIdentifierOrKeyword(m_nextToken.literal); + if (m_nextToken.literal.find_first_of("0123456789") != string::npos) + { + description = m_nextToken.literal.substr(m_nextToken.literal.find_first_of("0123456789")); + keyword += "M"; + if (description.find('x') != string::npos) + keyword += "xN"; + } + return make_tuple(Token::fromIdentifierOrKeyword(keyword), description); } char CharStream::advanceAndGet(size_t _chars) diff --git a/libsolidity/parsing/Scanner.h b/libsolidity/parsing/Scanner.h index a1a5c9c19..fa1f118bb 100644 --- a/libsolidity/parsing/Scanner.h +++ b/libsolidity/parsing/Scanner.h @@ -122,6 +122,7 @@ public: SourceLocation currentLocation() const { return m_currentToken.location; } std::string const& currentLiteral() const { return m_currentToken.literal; } + std::string const& currentTokenInfo() const { return m_currentToken.extendedTokenInfo; } ///@} ///@{ @@ -160,6 +161,7 @@ private: Token::Value token; SourceLocation location; std::string literal; + std::string extendedTokenInfo; }; ///@{ @@ -190,7 +192,7 @@ private: void scanDecimalDigits(); Token::Value scanNumber(char _charSeen = 0); - Token::Value scanIdentifierOrKeyword(); + std::tuple scanIdentifierOrKeyword(); Token::Value scanString(); Token::Value scanSingleLineDocComment(); diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp index cda639fba..7ea94112f 100644 --- a/libsolidity/parsing/Token.cpp +++ b/libsolidity/parsing/Token.cpp @@ -50,6 +50,44 @@ namespace dev namespace solidity { +bool ElementaryTypeNameToken::isElementaryTypeName(Token::Value _baseType, string const& _info) +{ + if (!Token::isElementaryTypeName(_baseType)) + return false; + string baseType = Token::toString(_baseType); + if (baseType.find('M') == string::npos) + return true; + short m; + m = stoi(_info.substr(_info.find_first_of("0123456789"))); + + if (baseType == "bytesM") + return (0 < m && m <= 32) ? true : false; + else if (baseType == "uintM" || baseType == "intM") + return (0 < m && m <= 256 && m % 8 == 0) ? true : false; + else if (baseType == "ufixedMxN" || baseType == "fixedMxN") + { + short n; + m = stoi(_info.substr(_info.find_first_of("0123456789"), _info.find_last_of("x") - 1)); + n = stoi(_info.substr(_info.find_last_of("x") + 1)); + return (0 < n + m && n + m <= 256 && ((n % 8 == 0) && (m % 8 == 0))); + } + return false; +} + +tuple ElementaryTypeNameToken::setTypes(Token::Value _baseType, string const& _toSet) +{ + string baseType = Token::toString(_baseType); + if (_toSet.find_first_of("0123456789") == string::npos) + return make_tuple(baseType, 0, 0); + baseType = baseType.substr(0, baseType.find('M') - 1) + _toSet; + size_t index = _toSet.find('x') == string::npos ? string::npos : _toSet.find('x') - 1; + unsigned int m = stoi(_toSet.substr(0, index)); + unsigned int n = 0; + if (baseType == "fixed" || baseType == "ufixed") + n = stoi(_toSet.substr(_toSet.find('x') + 1)); + return make_tuple(baseType, m, n); +} + #define T(name, string, precedence) #name, char const* const Token::m_name[NUM_TOKENS] = { @@ -80,7 +118,7 @@ char const Token::m_tokenType[] = { TOKEN_LIST(KT, KK) }; -Token::Value Token::fromIdentifierOrKeyword(const std::string& _name) +Token::Value Token::fromIdentifierOrKeyword(const string& _name) { // 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 88e77345d..5f8141ae3 100644 --- a/libsolidity/parsing/Token.h +++ b/libsolidity/parsing/Token.h @@ -187,113 +187,21 @@ namespace solidity K(SubWeek, "weeks", 0) \ K(SubYear, "years", 0) \ K(After, "after", 0) \ - /* type keywords, keep them in this order, keep int as first keyword - * the implementation in Types.cpp has to be synced to this here */\ + /* type keywords*/ \ K(Int, "int", 0) \ - K(Int8, "int8", 0) \ - K(Int16, "int16", 0) \ - K(Int24, "int24", 0) \ - K(Int32, "int32", 0) \ - K(Int40, "int40", 0) \ - K(Int48, "int48", 0) \ - K(Int56, "int56", 0) \ - K(Int64, "int64", 0) \ - K(Int72, "int72", 0) \ - K(Int80, "int80", 0) \ - K(Int88, "int88", 0) \ - K(Int96, "int96", 0) \ - K(Int104, "int104", 0) \ - K(Int112, "int112", 0) \ - K(Int120, "int120", 0) \ - K(Int128, "int128", 0) \ - K(Int136, "int136", 0) \ - K(Int144, "int144", 0) \ - K(Int152, "int152", 0) \ - K(Int160, "int160", 0) \ - K(Int168, "int168", 0) \ - K(Int176, "int176", 0) \ - K(Int184, "int184", 0) \ - K(Int192, "int192", 0) \ - K(Int200, "int200", 0) \ - K(Int208, "int208", 0) \ - K(Int216, "int216", 0) \ - K(Int224, "int224", 0) \ - K(Int232, "int232", 0) \ - K(Int240, "int240", 0) \ - K(Int248, "int248", 0) \ - K(Int256, "int256", 0) \ + K(IntM, "intM", 0) \ K(UInt, "uint", 0) \ - K(UInt8, "uint8", 0) \ - K(UInt16, "uint16", 0) \ - K(UInt24, "uint24", 0) \ - K(UInt32, "uint32", 0) \ - K(UInt40, "uint40", 0) \ - K(UInt48, "uint48", 0) \ - K(UInt56, "uint56", 0) \ - K(UInt64, "uint64", 0) \ - K(UInt72, "uint72", 0) \ - K(UInt80, "uint80", 0) \ - K(UInt88, "uint88", 0) \ - K(UInt96, "uint96", 0) \ - K(UInt104, "uint104", 0) \ - K(UInt112, "uint112", 0) \ - K(UInt120, "uint120", 0) \ - K(UInt128, "uint128", 0) \ - K(UInt136, "uint136", 0) \ - K(UInt144, "uint144", 0) \ - K(UInt152, "uint152", 0) \ - K(UInt160, "uint160", 0) \ - K(UInt168, "uint168", 0) \ - K(UInt176, "uint176", 0) \ - K(UInt184, "uint184", 0) \ - K(UInt192, "uint192", 0) \ - K(UInt200, "uint200", 0) \ - K(UInt208, "uint208", 0) \ - K(UInt216, "uint216", 0) \ - K(UInt224, "uint224", 0) \ - K(UInt232, "uint232", 0) \ - K(UInt240, "uint240", 0) \ - K(UInt248, "uint248", 0) \ - K(UInt256, "uint256", 0) \ - K(Bytes1, "bytes1", 0) \ - K(Bytes2, "bytes2", 0) \ - K(Bytes3, "bytes3", 0) \ - K(Bytes4, "bytes4", 0) \ - K(Bytes5, "bytes5", 0) \ - K(Bytes6, "bytes6", 0) \ - K(Bytes7, "bytes7", 0) \ - K(Bytes8, "bytes8", 0) \ - K(Bytes9, "bytes9", 0) \ - K(Bytes10, "bytes10", 0) \ - K(Bytes11, "bytes11", 0) \ - K(Bytes12, "bytes12", 0) \ - K(Bytes13, "bytes13", 0) \ - K(Bytes14, "bytes14", 0) \ - K(Bytes15, "bytes15", 0) \ - K(Bytes16, "bytes16", 0) \ - K(Bytes17, "bytes17", 0) \ - K(Bytes18, "bytes18", 0) \ - K(Bytes19, "bytes19", 0) \ - K(Bytes20, "bytes20", 0) \ - K(Bytes21, "bytes21", 0) \ - K(Bytes22, "bytes22", 0) \ - K(Bytes23, "bytes23", 0) \ - K(Bytes24, "bytes24", 0) \ - K(Bytes25, "bytes25", 0) \ - K(Bytes26, "bytes26", 0) \ - K(Bytes27, "bytes27", 0) \ - K(Bytes28, "bytes28", 0) \ - K(Bytes29, "bytes29", 0) \ - K(Bytes30, "bytes30", 0) \ - K(Bytes31, "bytes31", 0) \ - K(Bytes32, "bytes32", 0) \ + K(UIntM, "uintM", 0) \ K(Bytes, "bytes", 0) \ + K(BytesM, "bytesM", 0) \ K(Byte, "byte", 0) \ K(String, "string", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ - K(Real, "real", 0) \ - K(UReal, "ureal", 0) \ + K(Fixed, "fixed", 0) \ + K(FixedMxN, "fixedMxN", 0) \ + K(UFixed, "ufixed", 0) \ + K(UFixedMxN, "ufixedMxN", 0) \ T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ \ /* Literals */ \ @@ -403,5 +311,29 @@ private: static char const m_tokenType[NUM_TOKENS]; }; +class ElementaryTypeNameToken +{ +public: + ElementaryTypeNameToken(Token::Value token, std::string const& description) + { + solAssert(isElementaryTypeName(token, description), ""); + std::tie(m_name, M, N) = setTypes(token, description); + tok = token; + } + + std::string toString(bool const& tokValue = false) const& { return tokValue ? Token::toString(tok) : m_name; } + unsigned int const& returnM() const& { return M; } + unsigned int const& returnN() const& { return N; } + Token::Value const& returnTok() const& { return tok; } + static bool isElementaryTypeName(Token::Value _baseType, std::string const& _info); + +private: + Token::Value tok; + std::string m_name; + unsigned int M; + unsigned int N; + std::tuple setTypes(Token::Value _baseType, std::string const& _toSet); +}; + } } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c6e1b10d0..b54393e4c 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -726,7 +726,7 @@ BOOST_AUTO_TEST_CASE(small_signed_types) BOOST_AUTO_TEST_CASE(strings) { char const* sourceCode = "contract test {\n" - " function fixed() returns(bytes32 ret) {\n" + " function fixedBytes() returns(bytes32 ret) {\n" " return \"abc\\x00\\xff__\";\n" " }\n" " function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) {\n" @@ -735,7 +735,7 @@ BOOST_AUTO_TEST_CASE(strings) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("fixed()") == encodeArgs(string("abc\0\xff__", 7))); + BOOST_CHECK(callContractFunction("fixedBytes()") == encodeArgs(string("abc\0\xff__", 7))); BOOST_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true)); } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 3ca5a6b2b..91bae168b 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -927,13 +927,13 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value) BOOST_AUTO_TEST_CASE(state_variable_accessors) { char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "uint256 public foo;\n" - "mapping(uint=>bytes4) public map;\n" - "mapping(uint=>mapping(uint=>bytes4)) public multiple_map;\n" - "}\n"; + " function fun() {\n" + " uint64(2);\n" + " }\n" + "uint256 public foo;\n" + "mapping(uint=>bytes4) public map;\n" + "mapping(uint=>mapping(uint=>bytes4)) public multiple_map;\n" + "}\n"; ASTPointer source; ContractDefinition const* contract; @@ -1632,107 +1632,108 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName) { - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int) == *make_shared(256, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int8) == *make_shared(8, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int16) == *make_shared(16, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int24) == *make_shared(24, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int32) == *make_shared(32, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int40) == *make_shared(40, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int48) == *make_shared(48, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int56) == *make_shared(56, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int64) == *make_shared(64, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int72) == *make_shared(72, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int80) == *make_shared(80, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int88) == *make_shared(88, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int96) == *make_shared(96, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int104) == *make_shared(104, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int112) == *make_shared(112, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int120) == *make_shared(120, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int128) == *make_shared(128, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int136) == *make_shared(136, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int144) == *make_shared(144, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int152) == *make_shared(152, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int160) == *make_shared(160, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int168) == *make_shared(168, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int176) == *make_shared(176, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int184) == *make_shared(184, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int192) == *make_shared(192, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int200) == *make_shared(200, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int208) == *make_shared(208, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int216) == *make_shared(216, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int224) == *make_shared(224, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int232) == *make_shared(232, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int240) == *make_shared(240, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int248) == *make_shared(248, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int256) == *make_shared(256, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt) == *make_shared(256, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt8) == *make_shared(8, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt16) == *make_shared(16, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt24) == *make_shared(24, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt32) == *make_shared(32, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt40) == *make_shared(40, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt48) == *make_shared(48, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt56) == *make_shared(56, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt64) == *make_shared(64, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt72) == *make_shared(72, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt80) == *make_shared(80, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt88) == *make_shared(88, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt96) == *make_shared(96, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt104) == *make_shared(104, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt112) == *make_shared(112, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt120) == *make_shared(120, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt128) == *make_shared(128, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt136) == *make_shared(136, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt144) == *make_shared(144, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt152) == *make_shared(152, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt160) == *make_shared(160, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt168) == *make_shared(168, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt176) == *make_shared(176, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt184) == *make_shared(184, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt192) == *make_shared(192, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt200) == *make_shared(200, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt208) == *make_shared(208, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt216) == *make_shared(216, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt224) == *make_shared(224, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt232) == *make_shared(232, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt240) == *make_shared(240, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt248) == *make_shared(248, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt256) == *make_shared(256, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("int"), "")) == *make_shared(256, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "8")) == *make_shared(8, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "16")) == *make_shared(16, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "24")) == *make_shared(24, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "32")) == *make_shared(32, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "40")) == *make_shared(40, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "48")) == *make_shared(48, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "56")) == *make_shared(56, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "64")) == *make_shared(64, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "72")) == *make_shared(72, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "80")) == *make_shared(80, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "88")) == *make_shared(88, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "96")) == *make_shared(96, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "104")) == *make_shared(104, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "112")) == *make_shared(112, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "120")) == *make_shared(120, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "128")) == *make_shared(128, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "136")) == *make_shared(136, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "144")) == *make_shared(144, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "152")) == *make_shared(152, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "160")) == *make_shared(160, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "168")) == *make_shared(168, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "176")) == *make_shared(176, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "184")) == *make_shared(184, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "192")) == *make_shared(192, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "200")) == *make_shared(200, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "208")) == *make_shared(208, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "216")) == *make_shared(216, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "224")) == *make_shared(224, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "232")) == *make_shared(232, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "240")) == *make_shared(240, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "248")) == *make_shared(248, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "256")) == *make_shared(256, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Byte) == *make_shared(1)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes1) == *make_shared(1)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes2) == *make_shared(2)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes3) == *make_shared(3)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes4) == *make_shared(4)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes5) == *make_shared(5)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes6) == *make_shared(6)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes7) == *make_shared(7)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes8) == *make_shared(8)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes9) == *make_shared(9)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes10) == *make_shared(10)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes11) == *make_shared(11)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes12) == *make_shared(12)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes13) == *make_shared(13)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes14) == *make_shared(14)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes15) == *make_shared(15)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes16) == *make_shared(16)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes17) == *make_shared(17)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes18) == *make_shared(18)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes19) == *make_shared(19)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes20) == *make_shared(20)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes21) == *make_shared(21)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes22) == *make_shared(22)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes23) == *make_shared(23)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes24) == *make_shared(24)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes25) == *make_shared(25)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes26) == *make_shared(26)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes27) == *make_shared(27)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes28) == *make_shared(28)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes29) == *make_shared(29)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes30) == *make_shared(30)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes31) == *make_shared(31)); - BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes32) == *make_shared(32)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uint"), "")) == *make_shared(256, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")) == *make_shared(8, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "16")) == *make_shared(16, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "24")) == *make_shared(24, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "32")) == *make_shared(32, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "40")) == *make_shared(40, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "48")) == *make_shared(48, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "56")) == *make_shared(56, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "64")) == *make_shared(64, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "72")) == *make_shared(72, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "80")) == *make_shared(80, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "88")) == *make_shared(88, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "96")) == *make_shared(96, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "104")) == *make_shared(104, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "112")) == *make_shared(112, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "120")) == *make_shared(120, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "128")) == *make_shared(128, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "136")) == *make_shared(136, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "144")) == *make_shared(144, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "152")) == *make_shared(152, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "160")) == *make_shared(160, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "168")) == *make_shared(168, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "176")) == *make_shared(176, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "184")) == *make_shared(184, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "192")) == *make_shared(192, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "200")) == *make_shared(200, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "208")) == *make_shared(208, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "216")) == *make_shared(216, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "224")) == *make_shared(224, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "232")) == *make_shared(232, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "240")) == *make_shared(240, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "248")) == *make_shared(248, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "256")) == *make_shared(256, IntegerType::Modifier::Unsigned)); + + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("byte"), "")) == *make_shared(1)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "1")) == *make_shared(1)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "2")) == *make_shared(2)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "3")) == *make_shared(3)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "4")) == *make_shared(4)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "5")) == *make_shared(5)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "6")) == *make_shared(6)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "7")) == *make_shared(7)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "8")) == *make_shared(8)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "9")) == *make_shared(9)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "10")) == *make_shared(10)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "11")) == *make_shared(11)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "12")) == *make_shared(12)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "13")) == *make_shared(13)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "14")) == *make_shared(14)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "15")) == *make_shared(15)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "16")) == *make_shared(16)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "17")) == *make_shared(17)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "18")) == *make_shared(18)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "19")) == *make_shared(19)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "20")) == *make_shared(20)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "21")) == *make_shared(21)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "22")) == *make_shared(22)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "23")) == *make_shared(23)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "24")) == *make_shared(24)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "25")) == *make_shared(25)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "26")) == *make_shared(26)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "27")) == *make_shared(27)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "28")) == *make_shared(28)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "29")) == *make_shared(29)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "30")) == *make_shared(30)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "31")) == *make_shared(31)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "32")) == *make_shared(32)); } BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1) diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp index 87dda9c2e..eb858128d 100644 --- a/test/libsolidity/SolidityTypes.cpp +++ b/test/libsolidity/SolidityTypes.cpp @@ -37,9 +37,9 @@ BOOST_AUTO_TEST_SUITE(SolidityTypes) BOOST_AUTO_TEST_CASE(storage_layout_simple) { MemberList members(MemberList::MemberMap({ - {string("first"), Type::fromElementaryTypeName("uint128")}, - {string("second"), Type::fromElementaryTypeName("uint120")}, - {string("wraps"), Type::fromElementaryTypeName("uint16")} + {string("first"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "128"))}, + {string("second"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "120"))}, + {string("wraps"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "16"))} })); BOOST_REQUIRE_EQUAL(u256(2), members.storageSize()); BOOST_REQUIRE(members.memberStorageOffset("first") != nullptr); @@ -53,15 +53,15 @@ BOOST_AUTO_TEST_CASE(storage_layout_simple) BOOST_AUTO_TEST_CASE(storage_layout_mapping) { MemberList members(MemberList::MemberMap({ - {string("first"), Type::fromElementaryTypeName("uint128")}, + {string("first"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "128"))}, {string("second"), make_shared( - Type::fromElementaryTypeName("uint8"), - Type::fromElementaryTypeName("uint8") + Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")), + Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")) )}, - {string("third"), Type::fromElementaryTypeName("uint16")}, + {string("third"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "16"))}, {string("final"), make_shared( - Type::fromElementaryTypeName("uint8"), - Type::fromElementaryTypeName("uint8") + Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")), + Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")) )}, })); BOOST_REQUIRE_EQUAL(u256(4), members.storageSize()); From f4da1260184d5695287c30181734cff4d7e3d737 Mon Sep 17 00:00:00 2001 From: RJ Catalano Date: Tue, 9 Feb 2016 15:43:23 -0600 Subject: [PATCH 2/5] tests added and changes made fixed some silly problems in Token.cpp windows error fix --- libsolidity/ast/Types.cpp | 14 +- libsolidity/parsing/Parser.cpp | 2 +- libsolidity/parsing/Scanner.cpp | 31 +-- libsolidity/parsing/Token.cpp | 83 ++++--- libsolidity/parsing/Token.h | 30 +-- .../SolidityNameAndTypeResolution.cpp | 228 ++++++++++-------- test/libsolidity/SolidityTypes.cpp | 18 +- 7 files changed, 222 insertions(+), 184 deletions(-) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index df96d412f..774be5211 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -122,7 +122,7 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) "Expected an elementary type name but got " + tokenString); Token::Value token = _type.returnTok(); - unsigned int M = _type.returnM(); + unsigned int M = _type.firstNumber(); switch (token) { @@ -156,14 +156,10 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) TypePointer Type::fromElementaryTypeName(string const& _name) { - string keyword = _name.substr(0, _name.find_first_of("0123456789")); - string info = ""; - if (_name.find_first_of("0123456789") != string::npos) - { - keyword += "M"; - info = _name.substr(_name.find_first_of("0123456789")); - } - return fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword(keyword), info)); + string details; + Token::Value token; + tie(token, details) = Token::fromIdentifierOrKeyword(_name); + return fromElementaryTypeName(ElementaryTypeNameToken(token, details)); } TypePointer Type::forLiteral(Literal const& _literal) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 9f944a0c5..74ec5cda2 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -195,7 +195,6 @@ ASTPointer Parser::parseContractDefinition(bool _isLibrary) while (true) { Token::Value currentTokenValue = m_scanner->currentToken(); - string lit = m_scanner->currentLiteral(); if (currentTokenValue == Token::RBrace) break; else if (currentTokenValue == Token::Function) @@ -1138,6 +1137,7 @@ ASTPointer Parser::parsePrimaryExpression() default: if (Token::isElementaryTypeName(token)) { + //used for casts ElementaryTypeNameToken elementaryExpression(m_scanner->currentToken(), m_scanner->currentTokenInfo()); expression = nodeFactory.createNode(elementaryExpression); m_scanner->next(); diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp index 5d40e55b9..9307b100d 100644 --- a/libsolidity/parsing/Scanner.cpp +++ b/libsolidity/parsing/Scanner.cpp @@ -82,11 +82,14 @@ bool isWhiteSpace(char c) { return c == ' ' || c == '\n' || c == '\t' || c == '\r'; } -bool isIdentifierPart(char c) +bool isIdentifierStart(char c) { return c == '_' || c == '$' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); } - +bool isIdentifierPart(char c) +{ + return isIdentifierStart(c) || isDecimalDigit(c); +} int hexValue(char c) { if (c >= '0' && c <= '9') @@ -383,7 +386,7 @@ void Scanner::scanToken() m_nextSkippedComment.extendedTokenInfo.clear(); Token::Value token; - string tokenExtension = ""; + string tokenExtension; do { // Remember the position of the next token @@ -550,7 +553,7 @@ void Scanner::scanToken() token = selectToken(Token::BitNot); break; default: - if (isIdentifierPart(m_char)) + if (isIdentifierStart(m_char)) tie(token, tokenExtension) = scanIdentifierOrKeyword(); else if (isDecimalDigit(m_char)) token = scanNumber(); @@ -700,7 +703,7 @@ Token::Value Scanner::scanNumber(char _charSeen) // not be an identifier start or a decimal digit; see ECMA-262 // section 7.8.3, page 17 (note that we read only one decimal digit // if the value is 0). - if (isDecimalDigit(m_char) || isIdentifierPart(m_char)) + if (isDecimalDigit(m_char) || isIdentifierStart(m_char)) return Token::Illegal; literal.complete(); return Token::Number; @@ -708,26 +711,14 @@ Token::Value Scanner::scanNumber(char _charSeen) tuple Scanner::scanIdentifierOrKeyword() { - solAssert(isIdentifierPart(m_char), ""); + solAssert(isIdentifierStart(m_char), ""); LiteralScope literal(this, LITERAL_TYPE_STRING); addLiteralCharAndAdvance(); // Scan the rest of the identifier characters. - string keyword = ""; - string description = ""; - while (isIdentifierPart(m_char)) //get main keyword - addLiteralCharAndAdvance(); - keyword = m_nextToken.literal; - while (isDecimalDigit(m_char) || isIdentifierPart(m_char)) //get the description + while (isIdentifierPart(m_char)) //get full literal addLiteralCharAndAdvance(); literal.complete(); - if (m_nextToken.literal.find_first_of("0123456789") != string::npos) - { - description = m_nextToken.literal.substr(m_nextToken.literal.find_first_of("0123456789")); - keyword += "M"; - if (description.find('x') != string::npos) - keyword += "xN"; - } - return make_tuple(Token::fromIdentifierOrKeyword(keyword), description); + return Token::fromIdentifierOrKeyword(m_nextToken.literal); } char CharStream::advanceAndGet(size_t _chars) diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp index 7ea94112f..eaa653442 100644 --- a/libsolidity/parsing/Token.cpp +++ b/libsolidity/parsing/Token.cpp @@ -50,42 +50,36 @@ namespace dev namespace solidity { -bool ElementaryTypeNameToken::isElementaryTypeName(Token::Value _baseType, string const& _info) +tuple ElementaryTypeNameToken::parseDetails(Token::Value _baseType, string const& _details) { - if (!Token::isElementaryTypeName(_baseType)) - return false; + solAssert(Token::isElementaryTypeName(_baseType), ""); string baseType = Token::toString(_baseType); - if (baseType.find('M') == string::npos) - return true; - short m; - m = stoi(_info.substr(_info.find_first_of("0123456789"))); + if (_details.length() == 0) + return make_tuple(baseType, 0, 0); if (baseType == "bytesM") - return (0 < m && m <= 32) ? true : false; + { + for (unsigned m = 1; m <= 32; m++) + if (to_string(m) == _details) + return make_tuple(baseType.substr(0, baseType.size()-1) + to_string(m), m, 0); + } else if (baseType == "uintM" || baseType == "intM") - return (0 < m && m <= 256 && m % 8 == 0) ? true : false; + { + for (unsigned m = 8; m <= 256; m+=8) + if (to_string(m) == _details) + return make_tuple(baseType.substr(0, baseType.size()-1) + to_string(m), m, 0); + } else if (baseType == "ufixedMxN" || baseType == "fixedMxN") { - short n; - m = stoi(_info.substr(_info.find_first_of("0123456789"), _info.find_last_of("x") - 1)); - n = stoi(_info.substr(_info.find_last_of("x") + 1)); - return (0 < n + m && n + m <= 256 && ((n % 8 == 0) && (m % 8 == 0))); + for (unsigned m = 0; m <= 256; m+=8) + for (unsigned n = 8; m + n <= 256; n+=8) + if ((to_string(m) + "x" + to_string(n)) == _details) + return make_tuple(baseType.substr(0, baseType.size()-3) + to_string(m) + "x" + to_string(n), m, n); } - return false; -} - -tuple ElementaryTypeNameToken::setTypes(Token::Value _baseType, string const& _toSet) -{ - string baseType = Token::toString(_baseType); - if (_toSet.find_first_of("0123456789") == string::npos) - return make_tuple(baseType, 0, 0); - baseType = baseType.substr(0, baseType.find('M') - 1) + _toSet; - size_t index = _toSet.find('x') == string::npos ? string::npos : _toSet.find('x') - 1; - unsigned int m = stoi(_toSet.substr(0, index)); - unsigned int n = 0; - if (baseType == "fixed" || baseType == "ufixed") - n = stoi(_toSet.substr(_toSet.find('x') + 1)); - return make_tuple(baseType, m, n); + + BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << + errinfo_comment("Cannot create elementary type name token out of type " + baseType + " and size " + _details) + ); } #define T(name, string, precedence) #name, @@ -118,8 +112,35 @@ char const Token::m_tokenType[] = { TOKEN_LIST(KT, KK) }; -Token::Value Token::fromIdentifierOrKeyword(const string& _name) +tuple Token::fromIdentifierOrKeyword(const string& _literal) { + string token = _literal; + string details; + if (_literal == "uintM" || _literal == "intM" || _literal == "fixedMxN" || _literal == "ufixedMxN" || _literal == "bytesM") + return make_pair(Token::Identifier, details); + if (_literal.find_first_of("0123456789") != string::npos) + { + string baseType = _literal.substr(0, _literal.find_first_of("0123456789")); + short m = stoi(_literal.substr(_literal.find_first_of("0123456789"))); + if (baseType == "bytes") + { + details = (0 < m && m <= 32) ? to_string(m) : ""; + token = details.empty() ? _literal : baseType + "M"; + } + else if (baseType == "uint" || baseType == "int") + { + details = (0 < m && m <= 256 && m % 8 == 0) ? to_string(m) : ""; + token = details.empty() ? _literal : baseType + "M"; + } + else if (baseType == "ufixed" || baseType == "fixed") + { + m = stoi(to_string(m).substr(0, to_string(m).find_first_of("x") - 1)); + short n = stoi(_literal.substr(_literal.find_last_of("x") + 1)); + details = (0 < n + m && n + m <= 256 && ((n % 8 == 0) && (m % 8 == 0))) ? + to_string(m) + "x" + to_string(n) : ""; + token = details.empty() ? _literal : baseType + "MxN" ; + } + } // 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. #define KEYWORD(name, string, precedence) {string, Token::name}, @@ -127,8 +148,8 @@ Token::Value Token::fromIdentifierOrKeyword(const string& _name) static const map keywords({TOKEN_LIST(TOKEN, KEYWORD)}); #undef KEYWORD #undef TOKEN - auto it = keywords.find(_name); - return it == keywords.end() ? Token::Identifier : it->second; + auto it = keywords.find(token); + return it == keywords.end() ? make_pair(Token::Identifier, details) : make_pair(it->second, details); } #undef KT diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h index 5f8141ae3..55b801db9 100644 --- a/libsolidity/parsing/Token.h +++ b/libsolidity/parsing/Token.h @@ -302,7 +302,7 @@ public: return m_precedence[tok]; } - static Token::Value fromIdentifierOrKeyword(std::string const& _name); + static std::tuple fromIdentifierOrKeyword(std::string const& _name); private: static char const* const m_name[NUM_TOKENS]; @@ -314,25 +314,25 @@ private: class ElementaryTypeNameToken { public: - ElementaryTypeNameToken(Token::Value token, std::string const& description) + ElementaryTypeNameToken(Token::Value _token, std::string const& _detail) { - solAssert(isElementaryTypeName(token, description), ""); - std::tie(m_name, M, N) = setTypes(token, description); - tok = token; + std::tie(m_name, m_firstNumber, m_secondNumber) = parseDetails(_token, _detail); + m_token = _token; } - - std::string toString(bool const& tokValue = false) const& { return tokValue ? Token::toString(tok) : m_name; } - unsigned int const& returnM() const& { return M; } - unsigned int const& returnN() const& { return N; } - Token::Value const& returnTok() const& { return tok; } - static bool isElementaryTypeName(Token::Value _baseType, std::string const& _info); + + unsigned int const& firstNumber() const { return m_firstNumber; } + unsigned int const& secondNumber() const { return m_secondNumber; } + Token::Value const& returnTok() 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; } private: - Token::Value tok; + Token::Value m_token; std::string m_name; - unsigned int M; - unsigned int N; - std::tuple setTypes(Token::Value _baseType, std::string const& _toSet); + unsigned int m_firstNumber; + unsigned int m_secondNumber; + /// throws if _details is malformed + std::tuple parseDetails(Token::Value _baseType, std::string const& _details); }; } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 91bae168b..f5d8414c8 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1633,107 +1633,107 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName) { - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("int"), "")) == *make_shared(256, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "8")) == *make_shared(8, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "16")) == *make_shared(16, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "24")) == *make_shared(24, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "32")) == *make_shared(32, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "40")) == *make_shared(40, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "48")) == *make_shared(48, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "56")) == *make_shared(56, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "64")) == *make_shared(64, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "72")) == *make_shared(72, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "80")) == *make_shared(80, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "88")) == *make_shared(88, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "96")) == *make_shared(96, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "104")) == *make_shared(104, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "112")) == *make_shared(112, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "120")) == *make_shared(120, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "128")) == *make_shared(128, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "136")) == *make_shared(136, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "144")) == *make_shared(144, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "152")) == *make_shared(152, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "160")) == *make_shared(160, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "168")) == *make_shared(168, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "176")) == *make_shared(176, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "184")) == *make_shared(184, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "192")) == *make_shared(192, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "200")) == *make_shared(200, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "208")) == *make_shared(208, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "216")) == *make_shared(216, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "224")) == *make_shared(224, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "232")) == *make_shared(232, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "240")) == *make_shared(240, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "248")) == *make_shared(248, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("intM"), "256")) == *make_shared(256, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Int, "")) == *make_shared(256, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "8")) == *make_shared(8, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "16")) == *make_shared(16, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "24")) == *make_shared(24, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "32")) == *make_shared(32, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "40")) == *make_shared(40, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "48")) == *make_shared(48, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "56")) == *make_shared(56, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "64")) == *make_shared(64, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "72")) == *make_shared(72, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "80")) == *make_shared(80, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "88")) == *make_shared(88, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "96")) == *make_shared(96, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "104")) == *make_shared(104, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "112")) == *make_shared(112, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "120")) == *make_shared(120, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "128")) == *make_shared(128, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "136")) == *make_shared(136, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "144")) == *make_shared(144, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "152")) == *make_shared(152, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "160")) == *make_shared(160, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "168")) == *make_shared(168, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "176")) == *make_shared(176, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "184")) == *make_shared(184, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "192")) == *make_shared(192, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "200")) == *make_shared(200, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "208")) == *make_shared(208, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "216")) == *make_shared(216, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "224")) == *make_shared(224, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "232")) == *make_shared(232, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "240")) == *make_shared(240, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "248")) == *make_shared(248, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "256")) == *make_shared(256, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uint"), "")) == *make_shared(256, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")) == *make_shared(8, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "16")) == *make_shared(16, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "24")) == *make_shared(24, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "32")) == *make_shared(32, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "40")) == *make_shared(40, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "48")) == *make_shared(48, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "56")) == *make_shared(56, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "64")) == *make_shared(64, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "72")) == *make_shared(72, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "80")) == *make_shared(80, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "88")) == *make_shared(88, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "96")) == *make_shared(96, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "104")) == *make_shared(104, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "112")) == *make_shared(112, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "120")) == *make_shared(120, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "128")) == *make_shared(128, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "136")) == *make_shared(136, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "144")) == *make_shared(144, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "152")) == *make_shared(152, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "160")) == *make_shared(160, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "168")) == *make_shared(168, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "176")) == *make_shared(176, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "184")) == *make_shared(184, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "192")) == *make_shared(192, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "200")) == *make_shared(200, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "208")) == *make_shared(208, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "216")) == *make_shared(216, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "224")) == *make_shared(224, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "232")) == *make_shared(232, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "240")) == *make_shared(240, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "248")) == *make_shared(248, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "256")) == *make_shared(256, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UInt, "")) == *make_shared(256, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "8")) == *make_shared(8, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "16")) == *make_shared(16, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "24")) == *make_shared(24, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "32")) == *make_shared(32, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "40")) == *make_shared(40, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "48")) == *make_shared(48, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "56")) == *make_shared(56, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "64")) == *make_shared(64, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "72")) == *make_shared(72, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "80")) == *make_shared(80, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "88")) == *make_shared(88, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "96")) == *make_shared(96, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "104")) == *make_shared(104, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "112")) == *make_shared(112, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "120")) == *make_shared(120, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "128")) == *make_shared(128, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "136")) == *make_shared(136, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "144")) == *make_shared(144, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "152")) == *make_shared(152, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "160")) == *make_shared(160, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "168")) == *make_shared(168, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "176")) == *make_shared(176, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "184")) == *make_shared(184, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "192")) == *make_shared(192, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "200")) == *make_shared(200, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "208")) == *make_shared(208, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "216")) == *make_shared(216, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "224")) == *make_shared(224, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "232")) == *make_shared(232, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "240")) == *make_shared(240, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "248")) == *make_shared(248, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "256")) == *make_shared(256, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("byte"), "")) == *make_shared(1)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "1")) == *make_shared(1)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "2")) == *make_shared(2)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "3")) == *make_shared(3)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "4")) == *make_shared(4)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "5")) == *make_shared(5)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "6")) == *make_shared(6)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "7")) == *make_shared(7)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "8")) == *make_shared(8)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "9")) == *make_shared(9)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "10")) == *make_shared(10)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "11")) == *make_shared(11)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "12")) == *make_shared(12)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "13")) == *make_shared(13)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "14")) == *make_shared(14)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "15")) == *make_shared(15)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "16")) == *make_shared(16)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "17")) == *make_shared(17)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "18")) == *make_shared(18)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "19")) == *make_shared(19)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "20")) == *make_shared(20)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "21")) == *make_shared(21)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "22")) == *make_shared(22)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "23")) == *make_shared(23)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "24")) == *make_shared(24)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "25")) == *make_shared(25)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "26")) == *make_shared(26)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "27")) == *make_shared(27)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "28")) == *make_shared(28)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "29")) == *make_shared(29)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "30")) == *make_shared(30)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "31")) == *make_shared(31)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("bytesM"), "32")) == *make_shared(32)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Byte, "")) == *make_shared(1)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "1")) == *make_shared(1)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "2")) == *make_shared(2)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "3")) == *make_shared(3)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "4")) == *make_shared(4)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "5")) == *make_shared(5)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "6")) == *make_shared(6)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "7")) == *make_shared(7)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "8")) == *make_shared(8)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "9")) == *make_shared(9)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "10")) == *make_shared(10)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "11")) == *make_shared(11)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "12")) == *make_shared(12)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "13")) == *make_shared(13)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "14")) == *make_shared(14)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "15")) == *make_shared(15)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "16")) == *make_shared(16)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "17")) == *make_shared(17)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "18")) == *make_shared(18)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "19")) == *make_shared(19)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "20")) == *make_shared(20)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "21")) == *make_shared(21)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "22")) == *make_shared(22)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "23")) == *make_shared(23)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "24")) == *make_shared(24)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "25")) == *make_shared(25)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "26")) == *make_shared(26)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "27")) == *make_shared(27)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "28")) == *make_shared(28)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "29")) == *make_shared(29)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "30")) == *make_shared(30)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "31")) == *make_shared(31)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "32")) == *make_shared(32)); } BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1) @@ -3165,6 +3165,36 @@ BOOST_AUTO_TEST_CASE(index_access_for_bytes) BOOST_CHECK(success(text)); } +BOOST_AUTO_TEST_CASE(uint7_and_uintM_as_identifier) +{ + char const* text = R"( + contract test { + string uintM = "Hello 4 you"; + function f() { + uint8 uint7 = 3; + uint7 = 5; + string memory intM; + uint bytesM = 21; + } + } + )"; + BOOST_CHECK(success(text)); +} + +BOOST_AUTO_TEST_CASE(varM_disqualified_as_keyword) +{ + char const* text = R"( + contract test { + function f() { + uintM something = 3; + intM should = 4; + bytesM fail = "now"; + } + } + )"; + BOOST_CHECK(!success(text)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp index eb858128d..87dda9c2e 100644 --- a/test/libsolidity/SolidityTypes.cpp +++ b/test/libsolidity/SolidityTypes.cpp @@ -37,9 +37,9 @@ BOOST_AUTO_TEST_SUITE(SolidityTypes) BOOST_AUTO_TEST_CASE(storage_layout_simple) { MemberList members(MemberList::MemberMap({ - {string("first"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "128"))}, - {string("second"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "120"))}, - {string("wraps"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "16"))} + {string("first"), Type::fromElementaryTypeName("uint128")}, + {string("second"), Type::fromElementaryTypeName("uint120")}, + {string("wraps"), Type::fromElementaryTypeName("uint16")} })); BOOST_REQUIRE_EQUAL(u256(2), members.storageSize()); BOOST_REQUIRE(members.memberStorageOffset("first") != nullptr); @@ -53,15 +53,15 @@ BOOST_AUTO_TEST_CASE(storage_layout_simple) BOOST_AUTO_TEST_CASE(storage_layout_mapping) { MemberList members(MemberList::MemberMap({ - {string("first"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "128"))}, + {string("first"), Type::fromElementaryTypeName("uint128")}, {string("second"), make_shared( - Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")), - Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")) + Type::fromElementaryTypeName("uint8"), + Type::fromElementaryTypeName("uint8") )}, - {string("third"), Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "16"))}, + {string("third"), Type::fromElementaryTypeName("uint16")}, {string("final"), make_shared( - Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")), - Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::fromIdentifierOrKeyword("uintM"), "8")) + Type::fromElementaryTypeName("uint8"), + Type::fromElementaryTypeName("uint8") )}, })); BOOST_REQUIRE_EQUAL(u256(4), members.storageSize()); From 84f2eb461b62a2d36d6784068842b4aa0a5c220a Mon Sep 17 00:00:00 2001 From: RJ Catalano Date: Fri, 12 Feb 2016 15:01:27 -0600 Subject: [PATCH 3/5] added two functions in Token to handle long identifiers, redid fromIdentifierOrKeyword, and made complementary changes in scanner and parser --- libsolidity/ast/Types.cpp | 7 +- libsolidity/parsing/Parser.cpp | 26 ++- libsolidity/parsing/Scanner.cpp | 14 +- libsolidity/parsing/Scanner.h | 6 +- libsolidity/parsing/Token.cpp | 122 +++++++--- libsolidity/parsing/Token.h | 25 ++- .../SolidityNameAndTypeResolution.cpp | 210 +++++++++--------- 7 files changed, 253 insertions(+), 157 deletions(-) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 774be5211..f80508982 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -156,10 +156,11 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) TypePointer Type::fromElementaryTypeName(string const& _name) { - string details; + unsigned short firstNum; + unsigned short secondNum; Token::Value token; - tie(token, details) = Token::fromIdentifierOrKeyword(_name); - return fromElementaryTypeName(ElementaryTypeNameToken(token, details)); + tie(token, firstNum, secondNum) = Token::fromIdentifierOrKeyword(_name); + return fromElementaryTypeName(ElementaryTypeNameToken(token, firstNum, secondNum)); } TypePointer Type::forLiteral(Literal const& _literal) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 74ec5cda2..e579f18be 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -590,7 +590,10 @@ ASTPointer Parser::parseTypeName(bool _allowVar) Token::Value token = m_scanner->currentToken(); if (Token::isElementaryTypeName(token)) { - ElementaryTypeNameToken elemTypeName(token, m_scanner->currentTokenInfo()); + unsigned firstSize; + unsigned secondSize; + tie(firstSize, secondSize) = m_scanner->currentTokenInfo(); + ElementaryTypeNameToken elemTypeName(token, firstSize, secondSize); type = ASTNodeFactory(*this).createNode(elemTypeName); m_scanner->next(); } @@ -628,11 +631,14 @@ ASTPointer Parser::parseMapping() expectToken(Token::Mapping); expectToken(Token::LParen); ASTPointer keyType; - if (Token::isElementaryTypeName(m_scanner->currentToken())) - keyType = ASTNodeFactory(*this).createNode - (ElementaryTypeNameToken(m_scanner->currentToken(), m_scanner->currentTokenInfo())); - else + Token::Value token = m_scanner->currentToken(); + if (!Token::isElementaryTypeName(token)) fatalParserError(string("Expected elementary type name for mapping key type")); + unsigned firstSize; + unsigned secondSize; + tie(firstSize, secondSize) = m_scanner->currentTokenInfo(); + ElementaryTypeNameToken elemTypeName(token, firstSize, secondSize); + keyType = ASTNodeFactory(*this).createNode(elemTypeName); m_scanner->next(); expectToken(Token::Arrow); bool const allowVar = false; @@ -829,7 +835,10 @@ ASTPointer Parser::parseSimpleStatement(ASTPointer const& else { startedWithElementary = true; - ElementaryTypeNameToken elemToken(m_scanner->currentToken(), m_scanner->currentTokenInfo()); + unsigned firstNum; + unsigned secondNum; + tie(firstNum, secondNum) = m_scanner->currentTokenInfo(); + ElementaryTypeNameToken elemToken(m_scanner->currentToken(), firstNum, secondNum); path.push_back(ASTNodeFactory(*this).createNode(elemToken)); m_scanner->next(); } @@ -1138,7 +1147,10 @@ ASTPointer Parser::parsePrimaryExpression() if (Token::isElementaryTypeName(token)) { //used for casts - ElementaryTypeNameToken elementaryExpression(m_scanner->currentToken(), m_scanner->currentTokenInfo()); + unsigned firstSize; + unsigned secondSize; + tie(firstSize, secondSize) = m_scanner->currentTokenInfo(); + ElementaryTypeNameToken elementaryExpression(m_scanner->currentToken(), firstSize, secondSize); expression = nodeFactory.createNode(elementaryExpression); m_scanner->next(); } diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp index 9307b100d..510d283ef 100644 --- a/libsolidity/parsing/Scanner.cpp +++ b/libsolidity/parsing/Scanner.cpp @@ -381,12 +381,14 @@ Token::Value Scanner::scanSlash() void Scanner::scanToken() { m_nextToken.literal.clear(); - m_nextToken.extendedTokenInfo.clear(); + m_nextToken.extendedTokenInfo = make_tuple(0, 0); m_nextSkippedComment.literal.clear(); - m_nextSkippedComment.extendedTokenInfo.clear(); + m_nextSkippedComment.extendedTokenInfo = make_tuple(0, 0); Token::Value token; - string tokenExtension; + // M and N are for the purposes of grabbing different type sizes + unsigned M; + unsigned N; do { // Remember the position of the next token @@ -554,7 +556,7 @@ void Scanner::scanToken() break; default: if (isIdentifierStart(m_char)) - tie(token, tokenExtension) = scanIdentifierOrKeyword(); + tie(token, M, N) = scanIdentifierOrKeyword(); else if (isDecimalDigit(m_char)) token = scanNumber(); else if (skipWhitespace()) @@ -571,7 +573,7 @@ void Scanner::scanToken() while (token == Token::Whitespace); m_nextToken.location.end = sourcePos(); m_nextToken.token = token; - m_nextToken.extendedTokenInfo = tokenExtension; + m_nextToken.extendedTokenInfo = make_tuple(M,N); } bool Scanner::scanEscape() @@ -709,7 +711,7 @@ Token::Value Scanner::scanNumber(char _charSeen) return Token::Number; } -tuple Scanner::scanIdentifierOrKeyword() +tuple Scanner::scanIdentifierOrKeyword() { solAssert(isIdentifierStart(m_char), ""); LiteralScope literal(this, LITERAL_TYPE_STRING); diff --git a/libsolidity/parsing/Scanner.h b/libsolidity/parsing/Scanner.h index fa1f118bb..8dde922da 100644 --- a/libsolidity/parsing/Scanner.h +++ b/libsolidity/parsing/Scanner.h @@ -122,7 +122,7 @@ public: SourceLocation currentLocation() const { return m_currentToken.location; } std::string const& currentLiteral() const { return m_currentToken.literal; } - std::string const& currentTokenInfo() const { return m_currentToken.extendedTokenInfo; } + std::tuple const& currentTokenInfo() const { return m_currentToken.extendedTokenInfo; } ///@} ///@{ @@ -161,7 +161,7 @@ private: Token::Value token; SourceLocation location; std::string literal; - std::string extendedTokenInfo; + std::tuple extendedTokenInfo; }; ///@{ @@ -192,7 +192,7 @@ private: void scanDecimalDigits(); Token::Value scanNumber(char _charSeen = 0); - std::tuple scanIdentifierOrKeyword(); + std::tuple scanIdentifierOrKeyword(); Token::Value scanString(); Token::Value scanSingleLineDocComment(); diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp index eaa653442..b07b5c1be 100644 --- a/libsolidity/parsing/Token.cpp +++ b/libsolidity/parsing/Token.cpp @@ -50,36 +50,65 @@ namespace dev namespace solidity { -tuple ElementaryTypeNameToken::parseDetails(Token::Value _baseType, string const& _details) +void ElementaryTypeNameToken::parseDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second) { solAssert(Token::isElementaryTypeName(_baseType), ""); string baseType = Token::toString(_baseType); - if (_details.length() == 0) - return make_tuple(baseType, 0, 0); + if (_first == 0 && _second == 0) + { + m_name = baseType; + m_firstNumber = _first; + m_secondNumber = _second; + } if (baseType == "bytesM") { + solAssert(_second == 0, "There should not be a second size argument to type bytesM."); for (unsigned m = 1; m <= 32; m++) - if (to_string(m) == _details) - return make_tuple(baseType.substr(0, baseType.size()-1) + to_string(m), m, 0); + if (m == _first) + { + m_name = baseType.substr(0, baseType.size()-1) + to_string(_first); + m_firstNumber = _first; + m_secondNumber = _second; + } } else if (baseType == "uintM" || baseType == "intM") { + solAssert(_second == 0, "There should not be a second size argument to type " + baseType + "."); for (unsigned m = 8; m <= 256; m+=8) - if (to_string(m) == _details) - return make_tuple(baseType.substr(0, baseType.size()-1) + to_string(m), m, 0); + 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 ((to_string(m) + "x" + to_string(n)) == _details) - return make_tuple(baseType.substr(0, baseType.size()-3) + to_string(m) + "x" + to_string(n), m, n); + 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; + } } - BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << - errinfo_comment("Cannot create elementary type name token out of type " + baseType + " and size " + _details) - ); + 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) + ) + ); } #define T(name, string, precedence) #name, @@ -112,33 +141,68 @@ char const Token::m_tokenType[] = { TOKEN_LIST(KT, KK) }; -tuple Token::fromIdentifierOrKeyword(const string& _literal) +unsigned Token::extractM(string _literal) +{ + try + { + unsigned short m = stoi(_literal.substr(_literal.find_first_of("0123456789"))); + return m; + } + catch(out_of_range& e) + { + return 0; + } +} +pair 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::fromIdentifierOrKeyword(string const& _literal) { - string token = _literal; - string details; - if (_literal == "uintM" || _literal == "intM" || _literal == "fixedMxN" || _literal == "ufixedMxN" || _literal == "bytesM") - return make_pair(Token::Identifier, details); if (_literal.find_first_of("0123456789") != string::npos) { string baseType = _literal.substr(0, _literal.find_first_of("0123456789")); - short m = stoi(_literal.substr(_literal.find_first_of("0123456789"))); if (baseType == "bytes") { - details = (0 < m && m <= 32) ? to_string(m) : ""; - token = details.empty() ? _literal : baseType + "M"; + 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") { - details = (0 < m && m <= 256 && m % 8 == 0) ? to_string(m) : ""; - token = details.empty() ? _literal : baseType + "M"; + unsigned short m = extractM(_literal); + if (0 < m && m <= 256 && m % 8 == 0) + { + if (baseType == "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") { - m = stoi(to_string(m).substr(0, to_string(m).find_first_of("x") - 1)); - short n = stoi(_literal.substr(_literal.find_last_of("x") + 1)); - details = (0 < n + m && n + m <= 256 && ((n % 8 == 0) && (m % 8 == 0))) ? - to_string(m) + "x" + to_string(n) : ""; - token = details.empty() ? _literal : baseType + "MxN" ; + 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 @@ -148,8 +212,8 @@ tuple Token::fromIdentifierOrKeyword(const string& _litera static const map keywords({TOKEN_LIST(TOKEN, KEYWORD)}); #undef KEYWORD #undef TOKEN - auto it = keywords.find(token); - return it == keywords.end() ? make_pair(Token::Identifier, details) : make_pair(it->second, details); + auto it = keywords.find(_literal); + return it == keywords.end() ? make_tuple(Token::Identifier, 0, 0) : make_tuple(it->second, 0, 0); } #undef KT diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h index 55b801db9..7193627f6 100644 --- a/libsolidity/parsing/Token.h +++ b/libsolidity/parsing/Token.h @@ -189,19 +189,19 @@ namespace solidity K(After, "after", 0) \ /* type keywords*/ \ K(Int, "int", 0) \ - K(IntM, "intM", 0) \ + T(IntM, "intM", 0) \ K(UInt, "uint", 0) \ - K(UIntM, "uintM", 0) \ + T(UIntM, "uintM", 0) \ K(Bytes, "bytes", 0) \ - K(BytesM, "bytesM", 0) \ + T(BytesM, "bytesM", 0) \ K(Byte, "byte", 0) \ K(String, "string", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ K(Fixed, "fixed", 0) \ - K(FixedMxN, "fixedMxN", 0) \ + T(FixedMxN, "fixedMxN", 0) \ K(UFixed, "ufixed", 0) \ - K(UFixedMxN, "ufixedMxN", 0) \ + T(UFixedMxN, "ufixedMxN", 0) \ T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ \ /* Literals */ \ @@ -302,9 +302,14 @@ public: return m_precedence[tok]; } - static std::tuple fromIdentifierOrKeyword(std::string const& _name); + static std::tuple fromIdentifierOrKeyword(std::string const& _literal); private: + // extractM and extractMxN provide 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 extractMxN(std::string _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]; @@ -314,9 +319,9 @@ private: class ElementaryTypeNameToken { public: - ElementaryTypeNameToken(Token::Value _token, std::string const& _detail) + ElementaryTypeNameToken(Token::Value _token, unsigned const& _firstNumber, unsigned const& _secondNumber) { - std::tie(m_name, m_firstNumber, m_secondNumber) = parseDetails(_token, _detail); + parseDetails(_token, _firstNumber, _secondNumber); m_token = _token; } @@ -331,8 +336,8 @@ private: std::string m_name; unsigned int m_firstNumber; unsigned int m_secondNumber; - /// throws if _details is malformed - std::tuple parseDetails(Token::Value _baseType, std::string const& _details); + /// throws if type is not properly sized + void parseDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second); }; } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index f5d8414c8..3cbc813cc 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1633,107 +1633,107 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName) { - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Int, "")) == *make_shared(256, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "8")) == *make_shared(8, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "16")) == *make_shared(16, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "24")) == *make_shared(24, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "32")) == *make_shared(32, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "40")) == *make_shared(40, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "48")) == *make_shared(48, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "56")) == *make_shared(56, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "64")) == *make_shared(64, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "72")) == *make_shared(72, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "80")) == *make_shared(80, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "88")) == *make_shared(88, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "96")) == *make_shared(96, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "104")) == *make_shared(104, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "112")) == *make_shared(112, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "120")) == *make_shared(120, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "128")) == *make_shared(128, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "136")) == *make_shared(136, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "144")) == *make_shared(144, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "152")) == *make_shared(152, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "160")) == *make_shared(160, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "168")) == *make_shared(168, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "176")) == *make_shared(176, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "184")) == *make_shared(184, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "192")) == *make_shared(192, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "200")) == *make_shared(200, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "208")) == *make_shared(208, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "216")) == *make_shared(216, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "224")) == *make_shared(224, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "232")) == *make_shared(232, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "240")) == *make_shared(240, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "248")) == *make_shared(248, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, "256")) == *make_shared(256, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Int, 0, 0)) == *make_shared(256, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 8, 0)) == *make_shared(8, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 16, 0)) == *make_shared(16, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 24, 0)) == *make_shared(24, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 32, 0)) == *make_shared(32, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 40, 0)) == *make_shared(40, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 48, 0)) == *make_shared(48, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 56, 0)) == *make_shared(56, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 64, 0)) == *make_shared(64, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 72, 0)) == *make_shared(72, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 80, 0)) == *make_shared(80, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 88, 0)) == *make_shared(88, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 96, 0)) == *make_shared(96, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 104, 0)) == *make_shared(104, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 112, 0)) == *make_shared(112, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 120, 0)) == *make_shared(120, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 128, 0)) == *make_shared(128, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 136, 0)) == *make_shared(136, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 144, 0)) == *make_shared(144, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 152, 0)) == *make_shared(152, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 160, 0)) == *make_shared(160, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 168, 0)) == *make_shared(168, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 176, 0)) == *make_shared(176, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 184, 0)) == *make_shared(184, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 192, 0)) == *make_shared(192, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 200, 0)) == *make_shared(200, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 208, 0)) == *make_shared(208, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 216, 0)) == *make_shared(216, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 224, 0)) == *make_shared(224, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 232, 0)) == *make_shared(232, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 240, 0)) == *make_shared(240, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 248, 0)) == *make_shared(248, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 256, 0)) == *make_shared(256, IntegerType::Modifier::Signed)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UInt, "")) == *make_shared(256, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "8")) == *make_shared(8, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "16")) == *make_shared(16, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "24")) == *make_shared(24, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "32")) == *make_shared(32, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "40")) == *make_shared(40, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "48")) == *make_shared(48, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "56")) == *make_shared(56, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "64")) == *make_shared(64, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "72")) == *make_shared(72, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "80")) == *make_shared(80, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "88")) == *make_shared(88, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "96")) == *make_shared(96, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "104")) == *make_shared(104, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "112")) == *make_shared(112, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "120")) == *make_shared(120, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "128")) == *make_shared(128, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "136")) == *make_shared(136, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "144")) == *make_shared(144, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "152")) == *make_shared(152, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "160")) == *make_shared(160, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "168")) == *make_shared(168, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "176")) == *make_shared(176, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "184")) == *make_shared(184, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "192")) == *make_shared(192, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "200")) == *make_shared(200, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "208")) == *make_shared(208, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "216")) == *make_shared(216, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "224")) == *make_shared(224, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "232")) == *make_shared(232, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "240")) == *make_shared(240, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "248")) == *make_shared(248, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, "256")) == *make_shared(256, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UInt, 0, 0)) == *make_shared(256, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 8, 0)) == *make_shared(8, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 16, 0)) == *make_shared(16, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 24, 0)) == *make_shared(24, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 32, 0)) == *make_shared(32, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 40, 0)) == *make_shared(40, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 48, 0)) == *make_shared(48, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 56, 0)) == *make_shared(56, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 64, 0)) == *make_shared(64, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 72, 0)) == *make_shared(72, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 80, 0)) == *make_shared(80, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 88, 0)) == *make_shared(88, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 96, 0)) == *make_shared(96, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 104, 0)) == *make_shared(104, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 112, 0)) == *make_shared(112, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 120, 0)) == *make_shared(120, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 128, 0)) == *make_shared(128, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 136, 0)) == *make_shared(136, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 144, 0)) == *make_shared(144, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 152, 0)) == *make_shared(152, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 160, 0)) == *make_shared(160, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 168, 0)) == *make_shared(168, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 176, 0)) == *make_shared(176, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 184, 0)) == *make_shared(184, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 192, 0)) == *make_shared(192, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 200, 0)) == *make_shared(200, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 208, 0)) == *make_shared(208, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 216, 0)) == *make_shared(216, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 224, 0)) == *make_shared(224, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 232, 0)) == *make_shared(232, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 240, 0)) == *make_shared(240, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 248, 0)) == *make_shared(248, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 256, 0)) == *make_shared(256, IntegerType::Modifier::Unsigned)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Byte, "")) == *make_shared(1)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "1")) == *make_shared(1)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "2")) == *make_shared(2)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "3")) == *make_shared(3)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "4")) == *make_shared(4)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "5")) == *make_shared(5)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "6")) == *make_shared(6)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "7")) == *make_shared(7)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "8")) == *make_shared(8)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "9")) == *make_shared(9)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "10")) == *make_shared(10)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "11")) == *make_shared(11)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "12")) == *make_shared(12)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "13")) == *make_shared(13)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "14")) == *make_shared(14)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "15")) == *make_shared(15)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "16")) == *make_shared(16)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "17")) == *make_shared(17)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "18")) == *make_shared(18)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "19")) == *make_shared(19)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "20")) == *make_shared(20)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "21")) == *make_shared(21)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "22")) == *make_shared(22)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "23")) == *make_shared(23)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "24")) == *make_shared(24)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "25")) == *make_shared(25)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "26")) == *make_shared(26)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "27")) == *make_shared(27)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "28")) == *make_shared(28)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "29")) == *make_shared(29)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "30")) == *make_shared(30)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "31")) == *make_shared(31)); - BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, "32")) == *make_shared(32)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Byte, 0, 0)) == *make_shared(1)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 1, 0)) == *make_shared(1)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 2, 0)) == *make_shared(2)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 3, 0)) == *make_shared(3)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 4, 0)) == *make_shared(4)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 5, 0)) == *make_shared(5)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 6, 0)) == *make_shared(6)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 7, 0)) == *make_shared(7)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 8, 0)) == *make_shared(8)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 9, 0)) == *make_shared(9)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 10, 0)) == *make_shared(10)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 11, 0)) == *make_shared(11)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 12, 0)) == *make_shared(12)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 13, 0)) == *make_shared(13)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 14, 0)) == *make_shared(14)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 15, 0)) == *make_shared(15)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 16, 0)) == *make_shared(16)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 17, 0)) == *make_shared(17)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 18, 0)) == *make_shared(18)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 19, 0)) == *make_shared(19)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 20, 0)) == *make_shared(20)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 21, 0)) == *make_shared(21)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 22, 0)) == *make_shared(22)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 23, 0)) == *make_shared(23)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 24, 0)) == *make_shared(24)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 25, 0)) == *make_shared(25)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 26, 0)) == *make_shared(26)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 27, 0)) == *make_shared(27)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 28, 0)) == *make_shared(28)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 29, 0)) == *make_shared(29)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 30, 0)) == *make_shared(30)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 31, 0)) == *make_shared(31)); + BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 32, 0)) == *make_shared(32)); } BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1) @@ -3195,6 +3195,18 @@ BOOST_AUTO_TEST_CASE(varM_disqualified_as_keyword) BOOST_CHECK(!success(text)); } +BOOST_AUTO_TEST_CASE(long_uint_variable_fails) +{ + char const* text = R"( + contract test { + function f() { + uint99999999999999999999999999 something = 3; + } + } + )"; + BOOST_CHECK(!success(text)); +} + BOOST_AUTO_TEST_SUITE_END() } From d2c0712f36ce4a9148756458533a91bca1cfe44b Mon Sep 17 00:00:00 2001 From: RJ Catalano Date: Mon, 15 Feb 2016 10:34:45 -0600 Subject: [PATCH 4/5] added const correctness to extract functions in Token optimizations added in more elegant solution created for m declaration ubuntu wants to get rid of 0 <= first statement...so I will change returnToken to token --- libsolidity/ast/Types.cpp | 12 ++-- libsolidity/parsing/Scanner.cpp | 8 +-- libsolidity/parsing/Token.cpp | 111 +++++++------------------------- 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 f80508982..250ec1025 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(M, IntegerType::Modifier::Signed); + return make_shared(m, IntegerType::Modifier::Signed); case Token::UIntM: - return make_shared(M, IntegerType::Modifier::Unsigned); + return make_shared(m, IntegerType::Modifier::Unsigned); case Token::BytesM: - return make_shared(M); + return make_shared(m); case Token::Int: return make_shared(256, IntegerType::Modifier::Signed); case Token::UInt: diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp index 510d283ef..d630d0abf 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 b07b5c1be..693ed4208 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; - } + 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) + "." + ); } - 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; - } - } - - 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 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::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 7193627f6..3de204e01 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 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 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); }; } From 9b67969fd648fd5477e9b5d90870fddbd187e4d6 Mon Sep 17 00:00:00 2001 From: RJ Catalano Date: Thu, 18 Feb 2016 10:34:07 -0600 Subject: [PATCH 5/5] further optimization, splitting function into pieces generating strings on the fly, changed name, and added two tests --- libsolidity/ast/Types.cpp | 4 +-- libsolidity/parsing/Token.cpp | 30 ++++++++++--------- libsolidity/parsing/Token.h | 2 ++ .../SolidityNameAndTypeResolution.cpp | 25 ++++++++++++++++ 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 250ec1025..bca83d598 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -117,9 +117,9 @@ u256 const& MemberList::storageSize() const TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) { - string tokenString = _type.toString(); solAssert(Token::isElementaryTypeName(_type.token()), - "Expected an elementary type name but got " + tokenString); + "Expected an elementary type name but got " + _type.toString() + ); Token::Value token = _type.token(); unsigned int m = _type.firstNumber(); diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp index 693ed4208..78a905597 100644 --- a/libsolidity/parsing/Token.cpp +++ b/libsolidity/parsing/Token.cpp @@ -53,7 +53,6 @@ namespace solidity void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second) { solAssert(Token::isElementaryTypeName(_baseType), ""); - string tokenString = Token::toString(_baseType); if (_baseType == Token::BytesM) { solAssert(_second == 0, "There should not be a second size argument to type bytesM."); @@ -61,10 +60,10 @@ void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned con } else if (_baseType == Token::UIntM || _baseType == Token::IntM) { - solAssert(_second == 0, "There should not be a second size argument to type " + tokenString + "."); + solAssert(_second == 0, "There should not be a second size argument to type " + string(Token::toString(_baseType)) + "."); solAssert( _first <= 256 && _first % 8 == 0, - "No elementary type " + tokenString + to_string(_first) + "." + "No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "." ); } m_token = _baseType; @@ -120,26 +119,30 @@ tuple Token::fromIdentifierOrKeywo if (positionM != _literal.end()) { string baseType(_literal.begin(), positionM); - auto positionX = find(positionM, _literal.end(), 'x'); + auto positionX = find_if_not(positionM, _literal.end(), ::isdigit); unsigned short m = extractM(string(positionM, positionX)); - if (baseType == toString(Token::Bytes)) + Token::Value keyword = keywordByName(baseType); + if (keyword == Token::Bytes) { - if (0 < m && m <= 32) + if (0 < m && m <= 32 && positionX == _literal.end()) return make_tuple(Token::BytesM, m, 0); - return make_tuple(Token::Identifier, 0, 0); } - else if (baseType == toString(Token::UInt) || baseType == toString(Token::Int)) + else if (keyword == Token::UInt || keyword == Token::Int) { - if (0 < m && m <= 256 && m % 8 == 0) + if (0 < m && m <= 256 && m % 8 == 0 && positionX == _literal.end()) { - if (baseType == toString(Token::UInt)) + if (keyword == Token::UInt) return make_tuple(Token::UIntM, m, 0); else return make_tuple(Token::IntM, m, 0); } - return make_tuple(Token::Identifier, 0, 0); } + return make_tuple(Token::Identifier, 0, 0); } + return make_tuple(keywordByName(_literal), 0, 0); +} +Token::Value Token::keywordByName(string const& _name) +{ // 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. #define KEYWORD(name, string, precedence) {string, Token::name}, @@ -147,12 +150,11 @@ tuple Token::fromIdentifierOrKeywo static const map keywords({TOKEN_LIST(TOKEN, KEYWORD)}); #undef KEYWORD #undef TOKEN - auto it = keywords.find(_literal); - return it == keywords.end() ? make_tuple(Token::Identifier, 0, 0) : make_tuple(it->second, 0, 0); + auto it = keywords.find(_name); + return it == keywords.end() ? Token::Identifier : it->second; } #undef KT #undef KK - } } diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h index 3de204e01..a64eded56 100644 --- a/libsolidity/parsing/Token.h +++ b/libsolidity/parsing/Token.h @@ -307,6 +307,8 @@ private: // if out_of_range error is thrown, they returns 0s, therefore securing // the variable's identity as an identifier. static unsigned extractM(std::string const& _literal); + // @returns the keyword with name @a _name or Token::Identifier of no such keyword exists. + static Token::Value keywordByName(std::string const& _name); static char const* const m_name[NUM_TOKENS]; static char const* const m_string[NUM_TOKENS]; static int8_t const m_precedence[NUM_TOKENS]; diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 3cbc813cc..5f6c05356 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -3207,6 +3207,31 @@ BOOST_AUTO_TEST_CASE(long_uint_variable_fails) BOOST_CHECK(!success(text)); } +BOOST_AUTO_TEST_CASE(bytes10abc_is_identifier) +{ + char const* text = R"( + contract test { + function f() { + bytes32 bytes10abc = "abc"; + } + } + )"; + BOOST_CHECK(success(text)); +} + +BOOST_AUTO_TEST_CASE(int10abc_is_identifier) +{ + char const* text = R"( + contract test { + function f() { + uint uint10abc = 3; + int int10abc = 4; + } + } + )"; + BOOST_CHECK(success(text)); +} + BOOST_AUTO_TEST_SUITE_END() }