Merge pull request #401 from VoR0220/elementaryTypeToken

Elementary type token
This commit is contained in:
chriseth 2016-02-18 19:25:44 +01:00
commit 565d71748b
13 changed files with 367 additions and 276 deletions

View File

@ -1394,7 +1394,7 @@ bool TypeChecker::visit(Identifier const& _identifier)
void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr) void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr)
{ {
_expr.annotation().type = make_shared<TypeType>(Type::fromElementaryTypeName(_expr.typeToken())); _expr.annotation().type = make_shared<TypeType>(Type::fromElementaryTypeName(_expr.typeName()));
} }
void TypeChecker::endVisit(Literal const& _literal) void TypeChecker::endVisit(Literal const& _literal)

View File

@ -756,18 +756,17 @@ public:
class ElementaryTypeName: public TypeName class ElementaryTypeName: public TypeName
{ {
public: public:
ElementaryTypeName(SourceLocation const& _location, Token::Value _type): ElementaryTypeName(SourceLocation const& _location, ElementaryTypeNameToken const& _elem):
TypeName(_location), m_type(_type) TypeName(_location), m_type(_elem)
{ {}
solAssert(Token::isElementaryTypeName(_type), "");
}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
Token::Value typeName() const { return m_type; } ElementaryTypeNameToken const& typeName() const { return m_type; }
private: private:
Token::Value m_type; ElementaryTypeNameToken m_type;
}; };
/** /**
@ -1408,18 +1407,16 @@ private:
class ElementaryTypeNameExpression: public PrimaryExpression class ElementaryTypeNameExpression: public PrimaryExpression
{ {
public: public:
ElementaryTypeNameExpression(SourceLocation const& _location, Token::Value _typeToken): ElementaryTypeNameExpression(SourceLocation const& _location, ElementaryTypeNameToken const& _type):
PrimaryExpression(_location), m_typeToken(_typeToken) PrimaryExpression(_location), m_typeToken(_type)
{ {}
solAssert(Token::isElementaryTypeName(_typeToken), "");
}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
Token::Value typeToken() const { return m_typeToken; } ElementaryTypeNameToken const& typeName() const { return m_typeToken; }
private: private:
Token::Value m_typeToken; ElementaryTypeNameToken m_typeToken;
}; };
/** /**

View File

@ -139,7 +139,7 @@ bool ASTJsonConverter::visit(TypeName const&)
bool ASTJsonConverter::visit(ElementaryTypeName const& _node) 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; return true;
} }
@ -297,7 +297,7 @@ bool ASTJsonConverter::visit(Identifier const& _node)
bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node)
{ {
addJsonNode("ElementaryTypenameExpression", 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; return true;
} }

View File

@ -145,7 +145,7 @@ bool ASTPrinter::visit(TypeName const& _node)
bool ASTPrinter::visit(ElementaryTypeName const& _node) bool ASTPrinter::visit(ElementaryTypeName const& _node)
{ {
writeLine(string("ElementaryTypeName ") + Token::toString(_node.typeName())); writeLine(string("ElementaryTypeName ") + _node.typeName().toString());
printSourcePart(_node); printSourcePart(_node);
return goDeeper(); return goDeeper();
} }
@ -331,7 +331,7 @@ bool ASTPrinter::visit(Identifier const& _node)
bool ASTPrinter::visit(ElementaryTypeNameExpression const& _node) bool ASTPrinter::visit(ElementaryTypeNameExpression const& _node)
{ {
writeLine(string("ElementaryTypeNameExpression ") + Token::toString(_node.typeToken())); writeLine(string("ElementaryTypeNameExpression ") + _node.typeName().toString());
printType(_node); printType(_node);
printSourcePart(_node); printSourcePart(_node);
return goDeeper(); return goDeeper();

View File

@ -115,51 +115,52 @@ u256 const& MemberList::storageSize() const
return m_storageOffsets->storageSize(); 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(_type.token()),
solAssert(Token::isElementaryTypeName(_typeToken), "Expected an elementary type name but got " + _type.toString()
"Expected an elementary type name but got " + ((tokenCstr) ? string(Token::toString(_typeToken)) : "")); );
if (Token::Int <= _typeToken && _typeToken <= Token::Bytes32) Token::Value token = _type.token();
unsigned int m = _type.firstNumber();
switch (token)
{ {
int offset = _typeToken - Token::Int; case Token::IntM:
int bytes = offset % 33; return make_shared<IntegerType>(m, IntegerType::Modifier::Signed);
if (bytes == 0 && _typeToken != Token::Bytes1) case Token::UIntM:
bytes = 32; return make_shared<IntegerType>(m, IntegerType::Modifier::Unsigned);
int modifier = offset / 33; case Token::BytesM:
switch(modifier) return make_shared<FixedBytesType>(m);
{ case Token::Int:
case 0: return make_shared<IntegerType>(256, IntegerType::Modifier::Signed);
return make_shared<IntegerType>(bytes * 8, IntegerType::Modifier::Signed); case Token::UInt:
case 1: return make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned);
return make_shared<IntegerType>(bytes * 8, IntegerType::Modifier::Unsigned); case Token::Byte:
case 2:
return make_shared<FixedBytesType>(bytes + 1);
default:
solAssert(false, "Unexpected modifier value. Should never happen");
return TypePointer();
}
}
else if (_typeToken == Token::Byte)
return make_shared<FixedBytesType>(1); return make_shared<FixedBytesType>(1);
else if (_typeToken == Token::Address) case Token::Address:
return make_shared<IntegerType>(0, IntegerType::Modifier::Address); return make_shared<IntegerType>(0, IntegerType::Modifier::Address);
else if (_typeToken == Token::Bool) case Token::Bool:
return make_shared<BoolType>(); return make_shared<BoolType>();
else if (_typeToken == Token::Bytes) case Token::Bytes:
return make_shared<ArrayType>(DataLocation::Storage); return make_shared<ArrayType>(DataLocation::Storage);
else if (_typeToken == Token::String) case Token::String:
return make_shared<ArrayType>(DataLocation::Storage, true); return make_shared<ArrayType>(DataLocation::Storage, true);
else //no types found
default:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment( 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) TypePointer Type::fromElementaryTypeName(string const& _name)
{ {
return fromElementaryTypeName(Token::fromIdentifierOrKeyword(_name)); unsigned short firstNum;
unsigned short secondNum;
Token::Value token;
tie(token, firstNum, secondNum) = Token::fromIdentifierOrKeyword(_name);
return fromElementaryTypeName(ElementaryTypeNameToken(token, firstNum, secondNum));
} }
TypePointer Type::forLiteral(Literal const& _literal) TypePointer Type::forLiteral(Literal const& _literal)

View File

@ -140,7 +140,7 @@ public:
/// @{ /// @{
/// @name Factory functions /// @name Factory functions
/// Factory functions that convert an AST @ref TypeName to a Type. /// 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); static TypePointer fromElementaryTypeName(std::string const& _name);
/// @} /// @}

View File

@ -194,7 +194,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
expectToken(Token::LBrace); expectToken(Token::LBrace);
while (true) while (true)
{ {
Token::Value currentTokenValue= m_scanner->currentToken(); Token::Value currentTokenValue = m_scanner->currentToken();
if (currentTokenValue == Token::RBrace) if (currentTokenValue == Token::RBrace)
break; break;
else if (currentTokenValue == Token::Function) else if (currentTokenValue == Token::Function)
@ -590,7 +590,11 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
Token::Value token = m_scanner->currentToken(); Token::Value token = m_scanner->currentToken();
if (Token::isElementaryTypeName(token)) if (Token::isElementaryTypeName(token))
{ {
type = ASTNodeFactory(*this).createNode<ElementaryTypeName>(token); unsigned firstSize;
unsigned secondSize;
tie(firstSize, secondSize) = m_scanner->currentTokenInfo();
ElementaryTypeNameToken elemTypeName(token, firstSize, secondSize);
type = ASTNodeFactory(*this).createNode<ElementaryTypeName>(elemTypeName);
m_scanner->next(); m_scanner->next();
} }
else if (token == Token::Var) else if (token == Token::Var)
@ -626,10 +630,15 @@ ASTPointer<Mapping> Parser::parseMapping()
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
expectToken(Token::Mapping); expectToken(Token::Mapping);
expectToken(Token::LParen); expectToken(Token::LParen);
if (!Token::isElementaryTypeName(m_scanner->currentToken()))
fatalParserError(string("Expected elementary type name for mapping key type"));
ASTPointer<ElementaryTypeName> keyType; ASTPointer<ElementaryTypeName> keyType;
keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(m_scanner->currentToken()); 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<ElementaryTypeName>(elemTypeName);
m_scanner->next(); m_scanner->next();
expectToken(Token::Arrow); expectToken(Token::Arrow);
bool const allowVar = false; bool const allowVar = false;
@ -815,12 +824,10 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const&
default: default:
break; break;
} }
// At this point, we have 'Identifier "["' or 'Identifier "." Identifier' or 'ElementoryTypeName "["'. // At this point, we have 'Identifier "["' or 'Identifier "." Identifier' or 'ElementoryTypeName "["'.
// We parse '(Identifier ("." Identifier)* |ElementaryTypeName) ( "[" Expression "]" )+' // We parse '(Identifier ("." Identifier)* |ElementaryTypeName) ( "[" Expression "]" )+'
// until we can decide whether to hand this over to ExpressionStatement or create a // until we can decide whether to hand this over to ExpressionStatement or create a
// VariableDeclarationStatement out of it. // VariableDeclarationStatement out of it.
vector<ASTPointer<PrimaryExpression>> path; vector<ASTPointer<PrimaryExpression>> path;
bool startedWithElementary = false; bool startedWithElementary = false;
if (m_scanner->currentToken() == Token::Identifier) if (m_scanner->currentToken() == Token::Identifier)
@ -828,7 +835,11 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const&
else else
{ {
startedWithElementary = true; startedWithElementary = true;
path.push_back(ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(m_scanner->currentToken())); unsigned firstNum;
unsigned secondNum;
tie(firstNum, secondNum) = m_scanner->currentTokenInfo();
ElementaryTypeNameToken elemToken(m_scanner->currentToken(), firstNum, secondNum);
path.push_back(ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(elemToken));
m_scanner->next(); m_scanner->next();
} }
while (!startedWithElementary && m_scanner->currentToken() == Token::Period) while (!startedWithElementary && m_scanner->currentToken() == Token::Period)
@ -1066,6 +1077,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
Token::Value token = m_scanner->currentToken(); Token::Value token = m_scanner->currentToken();
ASTPointer<Expression> expression; ASTPointer<Expression> expression;
switch (token) switch (token)
{ {
case Token::TrueLiteral: case Token::TrueLiteral:
@ -1134,8 +1146,12 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
default: default:
if (Token::isElementaryTypeName(token)) if (Token::isElementaryTypeName(token))
{ {
// used for casts //used for casts
expression = nodeFactory.createNode<ElementaryTypeNameExpression>(token); unsigned firstSize;
unsigned secondSize;
tie(firstSize, secondSize) = m_scanner->currentTokenInfo();
ElementaryTypeNameToken elementaryExpression(m_scanner->currentToken(), firstSize, secondSize);
expression = nodeFactory.createNode<ElementaryTypeNameExpression>(elementaryExpression);
m_scanner->next(); m_scanner->next();
} }
else else
@ -1226,7 +1242,7 @@ ASTPointer<TypeName> Parser::typeNameIndexAccessStructure(
if (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_path.front().get())) if (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_path.front().get()))
{ {
solAssert(_path.size() == 1, ""); solAssert(_path.size() == 1, "");
type = nodeFactory.createNode<ElementaryTypeName>(typeName->typeToken()); type = nodeFactory.createNode<ElementaryTypeName>(typeName->typeName());
} }
else else
{ {

View File

@ -90,7 +90,6 @@ bool isIdentifierPart(char c)
{ {
return isIdentifierStart(c) || isDecimalDigit(c); return isIdentifierStart(c) || isDecimalDigit(c);
} }
int hexValue(char c) int hexValue(char c)
{ {
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9')
@ -382,8 +381,14 @@ Token::Value Scanner::scanSlash()
void Scanner::scanToken() void Scanner::scanToken()
{ {
m_nextToken.literal.clear(); m_nextToken.literal.clear();
m_nextToken.extendedTokenInfo = make_tuple(0, 0);
m_nextSkippedComment.literal.clear(); m_nextSkippedComment.literal.clear();
m_nextSkippedComment.extendedTokenInfo = make_tuple(0, 0);
Token::Value token; Token::Value token;
// M and N are for the purposes of grabbing different type sizes
unsigned m;
unsigned n;
do do
{ {
// Remember the position of the next token // Remember the position of the next token
@ -551,7 +556,7 @@ void Scanner::scanToken()
break; break;
default: default:
if (isIdentifierStart(m_char)) if (isIdentifierStart(m_char))
token = scanIdentifierOrKeyword(); tie(token, m, n) = scanIdentifierOrKeyword();
else if (isDecimalDigit(m_char)) else if (isDecimalDigit(m_char))
token = scanNumber(); token = scanNumber();
else if (skipWhitespace()) else if (skipWhitespace())
@ -568,6 +573,7 @@ void Scanner::scanToken()
while (token == Token::Whitespace); while (token == Token::Whitespace);
m_nextToken.location.end = sourcePos(); m_nextToken.location.end = sourcePos();
m_nextToken.token = token; m_nextToken.token = token;
m_nextToken.extendedTokenInfo = make_tuple(m, n);
} }
bool Scanner::scanEscape() bool Scanner::scanEscape()
@ -705,13 +711,13 @@ Token::Value Scanner::scanNumber(char _charSeen)
return Token::Number; return Token::Number;
} }
Token::Value Scanner::scanIdentifierOrKeyword() tuple<Token::Value, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
{ {
solAssert(isIdentifierStart(m_char), ""); solAssert(isIdentifierStart(m_char), "");
LiteralScope literal(this, LITERAL_TYPE_STRING); LiteralScope literal(this, LITERAL_TYPE_STRING);
addLiteralCharAndAdvance(); addLiteralCharAndAdvance();
// Scan the rest of the identifier characters. // Scan the rest of the identifier characters.
while (isIdentifierPart(m_char)) while (isIdentifierPart(m_char)) //get full literal
addLiteralCharAndAdvance(); addLiteralCharAndAdvance();
literal.complete(); literal.complete();
return Token::fromIdentifierOrKeyword(m_nextToken.literal); return Token::fromIdentifierOrKeyword(m_nextToken.literal);

View File

@ -122,6 +122,7 @@ public:
SourceLocation currentLocation() const { return m_currentToken.location; } SourceLocation currentLocation() const { return m_currentToken.location; }
std::string const& currentLiteral() const { return m_currentToken.literal; } std::string const& currentLiteral() const { return m_currentToken.literal; }
std::tuple<unsigned, unsigned> const& currentTokenInfo() const { return m_currentToken.extendedTokenInfo; }
///@} ///@}
///@{ ///@{
@ -160,6 +161,7 @@ private:
Token::Value token; Token::Value token;
SourceLocation location; SourceLocation location;
std::string literal; std::string literal;
std::tuple<unsigned, unsigned> extendedTokenInfo;
}; };
///@{ ///@{
@ -190,7 +192,7 @@ private:
void scanDecimalDigits(); void scanDecimalDigits();
Token::Value scanNumber(char _charSeen = 0); Token::Value scanNumber(char _charSeen = 0);
Token::Value scanIdentifierOrKeyword(); std::tuple<Token::Value, unsigned, unsigned> scanIdentifierOrKeyword();
Token::Value scanString(); Token::Value scanString();
Token::Value scanSingleLineDocComment(); Token::Value scanSingleLineDocComment();

View File

@ -50,6 +50,27 @@ namespace dev
namespace solidity namespace solidity
{ {
void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second)
{
solAssert(Token::isElementaryTypeName(_baseType), "");
if (_baseType == Token::BytesM)
{
solAssert(_second == 0, "There should not be a second size argument to type bytesM.");
solAssert(_first <= 32, "No elementary type bytes" + to_string(_first) + ".");
}
else if (_baseType == Token::UIntM || _baseType == Token::IntM)
{
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 " + string(Token::toString(_baseType)) + to_string(_first) + "."
);
}
m_token = _baseType;
m_firstNumber = _first;
m_secondNumber = _second;
}
#define T(name, string, precedence) #name, #define T(name, string, precedence) #name,
char const* const Token::m_name[NUM_TOKENS] = char const* const Token::m_name[NUM_TOKENS] =
{ {
@ -80,7 +101,47 @@ char const Token::m_tokenType[] =
{ {
TOKEN_LIST(KT, KK) TOKEN_LIST(KT, KK)
}; };
Token::Value Token::fromIdentifierOrKeyword(const std::string& _name) unsigned Token::extractM(string const& _literal)
{
try
{
unsigned short m = stoi(_literal);
return m;
}
catch(out_of_range& e)
{
return 0;
}
}
tuple<Token::Value, unsigned short, unsigned short> Token::fromIdentifierOrKeyword(string const& _literal)
{
auto positionM = find_if(_literal.begin(), _literal.end(), ::isdigit);
if (positionM != _literal.end())
{
string baseType(_literal.begin(), positionM);
auto positionX = find_if_not(positionM, _literal.end(), ::isdigit);
unsigned short m = extractM(string(positionM, positionX));
Token::Value keyword = keywordByName(baseType);
if (keyword == Token::Bytes)
{
if (0 < m && m <= 32 && positionX == _literal.end())
return make_tuple(Token::BytesM, m, 0);
}
else if (keyword == Token::UInt || keyword == Token::Int)
{
if (0 < m && m <= 256 && m % 8 == 0 && positionX == _literal.end())
{
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(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 // 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. // and keywords to be put inside the keywords variable.
@ -95,6 +156,5 @@ Token::Value Token::fromIdentifierOrKeyword(const std::string& _name)
#undef KT #undef KT
#undef KK #undef KK
} }
} }

View File

@ -187,107 +187,13 @@ namespace solidity
K(SubWeek, "weeks", 0) \ K(SubWeek, "weeks", 0) \
K(SubYear, "years", 0) \ K(SubYear, "years", 0) \
K(After, "after", 0) \ K(After, "after", 0) \
/* type keywords, keep them in this order, keep int as first keyword /* type keywords*/ \
* the implementation in Types.cpp has to be synced to this here */\
K(Int, "int", 0) \ K(Int, "int", 0) \
K(Int8, "int8", 0) \ T(IntM, "intM", 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(UInt, "uint", 0) \ K(UInt, "uint", 0) \
K(UInt8, "uint8", 0) \ T(UIntM, "uintM", 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(Bytes, "bytes", 0) \ K(Bytes, "bytes", 0) \
T(BytesM, "bytesM", 0) \
K(Byte, "byte", 0) \ K(Byte, "byte", 0) \
K(String, "string", 0) \ K(String, "string", 0) \
K(Address, "address", 0) \ K(Address, "address", 0) \
@ -394,14 +300,49 @@ public:
return m_precedence[tok]; return m_precedence[tok];
} }
static Token::Value fromIdentifierOrKeyword(std::string const& _name); static std::tuple<Token::Value, unsigned short, unsigned short> fromIdentifierOrKeyword(std::string const& _literal);
private: private:
// 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 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_name[NUM_TOKENS];
static char const* const m_string[NUM_TOKENS]; static char const* const m_string[NUM_TOKENS];
static int8_t const m_precedence[NUM_TOKENS]; static int8_t const m_precedence[NUM_TOKENS];
static char const m_tokenType[NUM_TOKENS]; static char const m_tokenType[NUM_TOKENS];
}; };
class ElementaryTypeNameToken
{
public:
ElementaryTypeNameToken(Token::Value _token, unsigned const& _firstNumber, unsigned const& _secondNumber)
{
assertDetails(_token, _firstNumber, _secondNumber);
}
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& 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;
unsigned int m_firstNumber;
unsigned int m_secondNumber;
/// throws if type is not properly sized
void assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second);
};
} }
} }

View File

@ -726,7 +726,7 @@ BOOST_AUTO_TEST_CASE(small_signed_types)
BOOST_AUTO_TEST_CASE(strings) BOOST_AUTO_TEST_CASE(strings)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"
" function fixed() returns(bytes32 ret) {\n" " function fixedBytes() returns(bytes32 ret) {\n"
" return \"abc\\x00\\xff__\";\n" " return \"abc\\x00\\xff__\";\n"
" }\n" " }\n"
" function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) {\n" " function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) {\n"
@ -735,7 +735,7 @@ BOOST_AUTO_TEST_CASE(strings)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); 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)); BOOST_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true));
} }

View File

@ -1632,107 +1632,108 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName) BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName)
{ {
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int) == *make_shared<IntegerType>(256, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int8) == *make_shared<IntegerType>(8, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int16) == *make_shared<IntegerType>(16, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int24) == *make_shared<IntegerType>(24, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int32) == *make_shared<IntegerType>(32, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int40) == *make_shared<IntegerType>(40, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int48) == *make_shared<IntegerType>(48, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int56) == *make_shared<IntegerType>(56, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int64) == *make_shared<IntegerType>(64, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int72) == *make_shared<IntegerType>(72, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int80) == *make_shared<IntegerType>(80, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int88) == *make_shared<IntegerType>(88, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int96) == *make_shared<IntegerType>(96, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int104) == *make_shared<IntegerType>(104, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int112) == *make_shared<IntegerType>(112, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int120) == *make_shared<IntegerType>(120, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int128) == *make_shared<IntegerType>(128, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int136) == *make_shared<IntegerType>(136, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int144) == *make_shared<IntegerType>(144, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int152) == *make_shared<IntegerType>(152, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int160) == *make_shared<IntegerType>(160, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int168) == *make_shared<IntegerType>(168, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int176) == *make_shared<IntegerType>(176, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int184) == *make_shared<IntegerType>(184, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int192) == *make_shared<IntegerType>(192, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int200) == *make_shared<IntegerType>(200, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int208) == *make_shared<IntegerType>(208, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int216) == *make_shared<IntegerType>(216, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int224) == *make_shared<IntegerType>(224, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int232) == *make_shared<IntegerType>(232, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int240) == *make_shared<IntegerType>(240, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int248) == *make_shared<IntegerType>(248, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int256) == *make_shared<IntegerType>(256, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt) == *make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Int, 0, 0)) == *make_shared<IntegerType>(256, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt8) == *make_shared<IntegerType>(8, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 8, 0)) == *make_shared<IntegerType>(8, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt16) == *make_shared<IntegerType>(16, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 16, 0)) == *make_shared<IntegerType>(16, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt24) == *make_shared<IntegerType>(24, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 24, 0)) == *make_shared<IntegerType>(24, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt32) == *make_shared<IntegerType>(32, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 32, 0)) == *make_shared<IntegerType>(32, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt40) == *make_shared<IntegerType>(40, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 40, 0)) == *make_shared<IntegerType>(40, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt48) == *make_shared<IntegerType>(48, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 48, 0)) == *make_shared<IntegerType>(48, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt56) == *make_shared<IntegerType>(56, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 56, 0)) == *make_shared<IntegerType>(56, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt64) == *make_shared<IntegerType>(64, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 64, 0)) == *make_shared<IntegerType>(64, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt72) == *make_shared<IntegerType>(72, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 72, 0)) == *make_shared<IntegerType>(72, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt80) == *make_shared<IntegerType>(80, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 80, 0)) == *make_shared<IntegerType>(80, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt88) == *make_shared<IntegerType>(88, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 88, 0)) == *make_shared<IntegerType>(88, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt96) == *make_shared<IntegerType>(96, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 96, 0)) == *make_shared<IntegerType>(96, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt104) == *make_shared<IntegerType>(104, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 104, 0)) == *make_shared<IntegerType>(104, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt112) == *make_shared<IntegerType>(112, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 112, 0)) == *make_shared<IntegerType>(112, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt120) == *make_shared<IntegerType>(120, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 120, 0)) == *make_shared<IntegerType>(120, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt128) == *make_shared<IntegerType>(128, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 128, 0)) == *make_shared<IntegerType>(128, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt136) == *make_shared<IntegerType>(136, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 136, 0)) == *make_shared<IntegerType>(136, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt144) == *make_shared<IntegerType>(144, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 144, 0)) == *make_shared<IntegerType>(144, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt152) == *make_shared<IntegerType>(152, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 152, 0)) == *make_shared<IntegerType>(152, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt160) == *make_shared<IntegerType>(160, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 160, 0)) == *make_shared<IntegerType>(160, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt168) == *make_shared<IntegerType>(168, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 168, 0)) == *make_shared<IntegerType>(168, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt176) == *make_shared<IntegerType>(176, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 176, 0)) == *make_shared<IntegerType>(176, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt184) == *make_shared<IntegerType>(184, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 184, 0)) == *make_shared<IntegerType>(184, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt192) == *make_shared<IntegerType>(192, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 192, 0)) == *make_shared<IntegerType>(192, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt200) == *make_shared<IntegerType>(200, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 200, 0)) == *make_shared<IntegerType>(200, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt208) == *make_shared<IntegerType>(208, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 208, 0)) == *make_shared<IntegerType>(208, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt216) == *make_shared<IntegerType>(216, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 216, 0)) == *make_shared<IntegerType>(216, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt224) == *make_shared<IntegerType>(224, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 224, 0)) == *make_shared<IntegerType>(224, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt232) == *make_shared<IntegerType>(232, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 232, 0)) == *make_shared<IntegerType>(232, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt240) == *make_shared<IntegerType>(240, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 240, 0)) == *make_shared<IntegerType>(240, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt248) == *make_shared<IntegerType>(248, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 248, 0)) == *make_shared<IntegerType>(248, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt256) == *make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, 256, 0)) == *make_shared<IntegerType>(256, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Byte) == *make_shared<FixedBytesType>(1)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UInt, 0, 0)) == *make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes1) == *make_shared<FixedBytesType>(1)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 8, 0)) == *make_shared<IntegerType>(8, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes2) == *make_shared<FixedBytesType>(2)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 16, 0)) == *make_shared<IntegerType>(16, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes3) == *make_shared<FixedBytesType>(3)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 24, 0)) == *make_shared<IntegerType>(24, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes4) == *make_shared<FixedBytesType>(4)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 32, 0)) == *make_shared<IntegerType>(32, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes5) == *make_shared<FixedBytesType>(5)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 40, 0)) == *make_shared<IntegerType>(40, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes6) == *make_shared<FixedBytesType>(6)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 48, 0)) == *make_shared<IntegerType>(48, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes7) == *make_shared<FixedBytesType>(7)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 56, 0)) == *make_shared<IntegerType>(56, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes8) == *make_shared<FixedBytesType>(8)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 64, 0)) == *make_shared<IntegerType>(64, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes9) == *make_shared<FixedBytesType>(9)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 72, 0)) == *make_shared<IntegerType>(72, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes10) == *make_shared<FixedBytesType>(10)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 80, 0)) == *make_shared<IntegerType>(80, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes11) == *make_shared<FixedBytesType>(11)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 88, 0)) == *make_shared<IntegerType>(88, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes12) == *make_shared<FixedBytesType>(12)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 96, 0)) == *make_shared<IntegerType>(96, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes13) == *make_shared<FixedBytesType>(13)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 104, 0)) == *make_shared<IntegerType>(104, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes14) == *make_shared<FixedBytesType>(14)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 112, 0)) == *make_shared<IntegerType>(112, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes15) == *make_shared<FixedBytesType>(15)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 120, 0)) == *make_shared<IntegerType>(120, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes16) == *make_shared<FixedBytesType>(16)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 128, 0)) == *make_shared<IntegerType>(128, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes17) == *make_shared<FixedBytesType>(17)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 136, 0)) == *make_shared<IntegerType>(136, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes18) == *make_shared<FixedBytesType>(18)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 144, 0)) == *make_shared<IntegerType>(144, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes19) == *make_shared<FixedBytesType>(19)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 152, 0)) == *make_shared<IntegerType>(152, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes20) == *make_shared<FixedBytesType>(20)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 160, 0)) == *make_shared<IntegerType>(160, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes21) == *make_shared<FixedBytesType>(21)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 168, 0)) == *make_shared<IntegerType>(168, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes22) == *make_shared<FixedBytesType>(22)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 176, 0)) == *make_shared<IntegerType>(176, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes23) == *make_shared<FixedBytesType>(23)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 184, 0)) == *make_shared<IntegerType>(184, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes24) == *make_shared<FixedBytesType>(24)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 192, 0)) == *make_shared<IntegerType>(192, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes25) == *make_shared<FixedBytesType>(25)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 200, 0)) == *make_shared<IntegerType>(200, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes26) == *make_shared<FixedBytesType>(26)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 208, 0)) == *make_shared<IntegerType>(208, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes27) == *make_shared<FixedBytesType>(27)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 216, 0)) == *make_shared<IntegerType>(216, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes28) == *make_shared<FixedBytesType>(28)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 224, 0)) == *make_shared<IntegerType>(224, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes29) == *make_shared<FixedBytesType>(29)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 232, 0)) == *make_shared<IntegerType>(232, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes30) == *make_shared<FixedBytesType>(30)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 240, 0)) == *make_shared<IntegerType>(240, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes31) == *make_shared<FixedBytesType>(31)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 248, 0)) == *make_shared<IntegerType>(248, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes32) == *make_shared<FixedBytesType>(32)); BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, 256, 0)) == *make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Byte, 0, 0)) == *make_shared<FixedBytesType>(1));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 1, 0)) == *make_shared<FixedBytesType>(1));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 2, 0)) == *make_shared<FixedBytesType>(2));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 3, 0)) == *make_shared<FixedBytesType>(3));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 4, 0)) == *make_shared<FixedBytesType>(4));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 5, 0)) == *make_shared<FixedBytesType>(5));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 6, 0)) == *make_shared<FixedBytesType>(6));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 7, 0)) == *make_shared<FixedBytesType>(7));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 8, 0)) == *make_shared<FixedBytesType>(8));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 9, 0)) == *make_shared<FixedBytesType>(9));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 10, 0)) == *make_shared<FixedBytesType>(10));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 11, 0)) == *make_shared<FixedBytesType>(11));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 12, 0)) == *make_shared<FixedBytesType>(12));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 13, 0)) == *make_shared<FixedBytesType>(13));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 14, 0)) == *make_shared<FixedBytesType>(14));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 15, 0)) == *make_shared<FixedBytesType>(15));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 16, 0)) == *make_shared<FixedBytesType>(16));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 17, 0)) == *make_shared<FixedBytesType>(17));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 18, 0)) == *make_shared<FixedBytesType>(18));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 19, 0)) == *make_shared<FixedBytesType>(19));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 20, 0)) == *make_shared<FixedBytesType>(20));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 21, 0)) == *make_shared<FixedBytesType>(21));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 22, 0)) == *make_shared<FixedBytesType>(22));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 23, 0)) == *make_shared<FixedBytesType>(23));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 24, 0)) == *make_shared<FixedBytesType>(24));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 25, 0)) == *make_shared<FixedBytesType>(25));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 26, 0)) == *make_shared<FixedBytesType>(26));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 27, 0)) == *make_shared<FixedBytesType>(27));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 28, 0)) == *make_shared<FixedBytesType>(28));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 29, 0)) == *make_shared<FixedBytesType>(29));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 30, 0)) == *make_shared<FixedBytesType>(30));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 31, 0)) == *make_shared<FixedBytesType>(31));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 32, 0)) == *make_shared<FixedBytesType>(32));
} }
BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1) BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1)
@ -3164,6 +3165,73 @@ BOOST_AUTO_TEST_CASE(index_access_for_bytes)
BOOST_CHECK(success(text)); 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_CASE(long_uint_variable_fails)
{
char const* text = R"(
contract test {
function f() {
uint99999999999999999999999999 something = 3;
}
}
)";
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() BOOST_AUTO_TEST_SUITE_END()
} }