aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-02-19 02:25:44 +0800
committerchriseth <c@ethdev.com>2016-02-19 02:25:44 +0800
commit565d71748b3b359e705bbf56ced40ccd0b7dea5f (patch)
treef826c1b99fec02e0cde7770f6cd121e99e56b595 /libsolidity
parentfca27b9ea00eb580f771820e967f62b58478c9a2 (diff)
parent9b67969fd648fd5477e9b5d90870fddbd187e4d6 (diff)
downloaddexon-solidity-565d71748b3b359e705bbf56ced40ccd0b7dea5f.tar.gz
dexon-solidity-565d71748b3b359e705bbf56ced40ccd0b7dea5f.tar.zst
dexon-solidity-565d71748b3b359e705bbf56ced40ccd0b7dea5f.zip
Merge pull request #401 from VoR0220/elementaryTypeToken
Elementary type token
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/analysis/TypeChecker.cpp2
-rw-r--r--libsolidity/ast/AST.h25
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp4
-rw-r--r--libsolidity/ast/ASTPrinter.cpp4
-rw-r--r--libsolidity/ast/Types.cpp63
-rw-r--r--libsolidity/ast/Types.h2
-rw-r--r--libsolidity/parsing/Parser.cpp38
-rw-r--r--libsolidity/parsing/Scanner.cpp14
-rw-r--r--libsolidity/parsing/Scanner.h4
-rw-r--r--libsolidity/parsing/Token.cpp64
-rw-r--r--libsolidity/parsing/Token.h139
11 files changed, 191 insertions, 168 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 857d5530..44f4629b 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<TypeType>(Type::fromElementaryTypeName(_expr.typeToken()));
+ _expr.annotation().type = make_shared<TypeType>(Type::fromElementaryTypeName(_expr.typeName()));
}
void TypeChecker::endVisit(Literal const& _literal)
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index e1063467..d32d76a4 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 df836afe..163e22f4 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 bc981f7d..283bc8f9 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 c889e6a0..bca83d59 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -115,51 +115,52 @@ 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)) : ""));
+ solAssert(Token::isElementaryTypeName(_type.token()),
+ "Expected an elementary type name but got " + _type.toString()
+ );
+
+ Token::Value token = _type.token();
+ unsigned int m = _type.firstNumber();
- if (Token::Int <= _typeToken && _typeToken <= Token::Bytes32)
+ 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<IntegerType>(bytes * 8, IntegerType::Modifier::Signed);
- case 1:
- return make_shared<IntegerType>(bytes * 8, IntegerType::Modifier::Unsigned);
- case 2:
- return make_shared<FixedBytesType>(bytes + 1);
- default:
- solAssert(false, "Unexpected modifier value. Should never happen");
- return TypePointer();
- }
- }
- else if (_typeToken == Token::Byte)
+ case Token::IntM:
+ return make_shared<IntegerType>(m, IntegerType::Modifier::Signed);
+ case Token::UIntM:
+ return make_shared<IntegerType>(m, IntegerType::Modifier::Unsigned);
+ case Token::BytesM:
+ return make_shared<FixedBytesType>(m);
+ case Token::Int:
+ return make_shared<IntegerType>(256, IntegerType::Modifier::Signed);
+ case Token::UInt:
+ return make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned);
+ case Token::Byte:
return make_shared<FixedBytesType>(1);
- else if (_typeToken == Token::Address)
+ case Token::Address:
return make_shared<IntegerType>(0, IntegerType::Modifier::Address);
- else if (_typeToken == Token::Bool)
+ case Token::Bool:
return make_shared<BoolType>();
- else if (_typeToken == Token::Bytes)
+ case Token::Bytes:
return make_shared<ArrayType>(DataLocation::Storage);
- else if (_typeToken == Token::String)
+ case Token::String:
return make_shared<ArrayType>(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));
+ 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)
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 90a0509b..b4a2d573 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 d9ec1a49..e579f18b 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -194,7 +194,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
expectToken(Token::LBrace);
while (true)
{
- Token::Value currentTokenValue= m_scanner->currentToken();
+ Token::Value currentTokenValue = m_scanner->currentToken();
if (currentTokenValue == Token::RBrace)
break;
else if (currentTokenValue == Token::Function)
@@ -590,7 +590,11 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
Token::Value token = m_scanner->currentToken();
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();
}
else if (token == Token::Var)
@@ -626,10 +630,15 @@ ASTPointer<Mapping> 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<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();
expectToken(Token::Arrow);
bool const allowVar = false;
@@ -815,12 +824,10 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> 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<ASTPointer<PrimaryExpression>> path;
bool startedWithElementary = false;
if (m_scanner->currentToken() == Token::Identifier)
@@ -828,7 +835,11 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const&
else
{
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();
}
while (!startedWithElementary && m_scanner->currentToken() == Token::Period)
@@ -1066,6 +1077,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
ASTNodeFactory nodeFactory(*this);
Token::Value token = m_scanner->currentToken();
ASTPointer<Expression> expression;
+
switch (token)
{
case Token::TrueLiteral:
@@ -1134,8 +1146,12 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
default:
if (Token::isElementaryTypeName(token))
{
- // used for casts
- expression = nodeFactory.createNode<ElementaryTypeNameExpression>(token);
+ //used for casts
+ 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();
}
else
@@ -1226,7 +1242,7 @@ ASTPointer<TypeName> Parser::typeNameIndexAccessStructure(
if (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_path.front().get()))
{
solAssert(_path.size() == 1, "");
- type = nodeFactory.createNode<ElementaryTypeName>(typeName->typeToken());
+ type = nodeFactory.createNode<ElementaryTypeName>(typeName->typeName());
}
else
{
diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp
index fe0807d5..d630d0ab 100644
--- a/libsolidity/parsing/Scanner.cpp
+++ b/libsolidity/parsing/Scanner.cpp
@@ -90,7 +90,6 @@ bool isIdentifierPart(char c)
{
return isIdentifierStart(c) || isDecimalDigit(c);
}
-
int hexValue(char c)
{
if (c >= '0' && c <= '9')
@@ -382,8 +381,14 @@ Token::Value Scanner::scanSlash()
void Scanner::scanToken()
{
m_nextToken.literal.clear();
+ m_nextToken.extendedTokenInfo = make_tuple(0, 0);
m_nextSkippedComment.literal.clear();
+ m_nextSkippedComment.extendedTokenInfo = make_tuple(0, 0);
+
Token::Value token;
+ // M and N are for the purposes of grabbing different type sizes
+ unsigned m;
+ unsigned n;
do
{
// Remember the position of the next token
@@ -551,7 +556,7 @@ void Scanner::scanToken()
break;
default:
if (isIdentifierStart(m_char))
- token = scanIdentifierOrKeyword();
+ tie(token, m, n) = scanIdentifierOrKeyword();
else if (isDecimalDigit(m_char))
token = scanNumber();
else if (skipWhitespace())
@@ -568,6 +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);
}
bool Scanner::scanEscape()
@@ -705,13 +711,13 @@ Token::Value Scanner::scanNumber(char _charSeen)
return Token::Number;
}
-Token::Value Scanner::scanIdentifierOrKeyword()
+tuple<Token::Value, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
{
solAssert(isIdentifierStart(m_char), "");
LiteralScope literal(this, LITERAL_TYPE_STRING);
addLiteralCharAndAdvance();
// Scan the rest of the identifier characters.
- while (isIdentifierPart(m_char))
+ while (isIdentifierPart(m_char)) //get full literal
addLiteralCharAndAdvance();
literal.complete();
return Token::fromIdentifierOrKeyword(m_nextToken.literal);
diff --git a/libsolidity/parsing/Scanner.h b/libsolidity/parsing/Scanner.h
index a1a5c9c1..8dde922d 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::tuple<unsigned, unsigned> const& currentTokenInfo() const { return m_currentToken.extendedTokenInfo; }
///@}
///@{
@@ -160,6 +161,7 @@ private:
Token::Value token;
SourceLocation location;
std::string literal;
+ std::tuple<unsigned, unsigned> extendedTokenInfo;
};
///@{
@@ -190,7 +192,7 @@ private:
void scanDecimalDigits();
Token::Value scanNumber(char _charSeen = 0);
- Token::Value scanIdentifierOrKeyword();
+ std::tuple<Token::Value, unsigned, unsigned> scanIdentifierOrKeyword();
Token::Value scanString();
Token::Value scanSingleLineDocComment();
diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp
index cda639fb..78a90559 100644
--- a/libsolidity/parsing/Token.cpp
+++ b/libsolidity/parsing/Token.cpp
@@ -50,6 +50,27 @@ namespace dev
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,
char const* const Token::m_name[NUM_TOKENS] =
{
@@ -80,7 +101,47 @@ char const Token::m_tokenType[] =
{
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
// and keywords to be put inside the keywords variable.
@@ -95,6 +156,5 @@ Token::Value Token::fromIdentifierOrKeyword(const std::string& _name)
#undef KT
#undef KK
-
}
}
diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h
index 88e77345..a64eded5 100644
--- a/libsolidity/parsing/Token.h
+++ b/libsolidity/parsing/Token.h
@@ -187,107 +187,13 @@ 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) \
+ T(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) \
+ T(UIntM, "uintM", 0) \
K(Bytes, "bytes", 0) \
+ T(BytesM, "bytesM", 0) \
K(Byte, "byte", 0) \
K(String, "string", 0) \
K(Address, "address", 0) \
@@ -394,14 +300,49 @@ public:
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:
+ // 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_string[NUM_TOKENS];
static int8_t const m_precedence[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);
+};
+
}
}