aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/parsing/Token.h
diff options
context:
space:
mode:
authorChristian Parpart <christian@ethereum.org>2018-10-22 22:48:21 +0800
committerChristian Parpart <christian@ethereum.org>2018-10-22 23:00:51 +0800
commitf112377dd44e8281bff092639bb546ec8a6a39ac (patch)
tree4b6b8b3816a0a1620e73a30de687ff3557a10098 /libsolidity/parsing/Token.h
parentc13b5280c1b44f18a2a1fb61ef5556e91c5678e7 (diff)
downloaddexon-solidity-f112377dd44e8281bff092639bb546ec8a6a39ac.tar
dexon-solidity-f112377dd44e8281bff092639bb546ec8a6a39ac.tar.gz
dexon-solidity-f112377dd44e8281bff092639bb546ec8a6a39ac.tar.bz2
dexon-solidity-f112377dd44e8281bff092639bb546ec8a6a39ac.tar.lz
dexon-solidity-f112377dd44e8281bff092639bb546ec8a6a39ac.tar.xz
dexon-solidity-f112377dd44e8281bff092639bb546ec8a6a39ac.tar.zst
dexon-solidity-f112377dd44e8281bff092639bb546ec8a6a39ac.zip
Refactor `solidity::Token` into an `enum class` with `TokenTraits` helper namespace
Diffstat (limited to 'libsolidity/parsing/Token.h')
-rw-r--r--libsolidity/parsing/Token.h145
1 files changed, 61 insertions, 84 deletions
diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h
index 8ecc850a..81e8dd98 100644
--- a/libsolidity/parsing/Token.h
+++ b/libsolidity/parsing/Token.h
@@ -45,6 +45,7 @@
#include <libdevcore/Common.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/parsing/UndefMacros.h>
+#include <iosfwd>
namespace dev
{
@@ -267,119 +268,95 @@ namespace solidity
/* Scanner-internal use only. */ \
T(Whitespace, NULL, 0)
-
-class Token
-{
-public:
- // All token values.
- // attention! msvc issue:
- // http://stackoverflow.com/questions/9567868/compile-errors-after-adding-v8-to-my-project-c2143-c2059
- // @todo: avoid TOKEN_LIST macro
+// All token values.
+// attention! msvc issue:
+// http://stackoverflow.com/questions/9567868/compile-errors-after-adding-v8-to-my-project-c2143-c2059
+// @todo: avoid TOKEN_LIST macro
+enum class Token : unsigned int {
#define T(name, string, precedence) name,
- enum Value
- {
- TOKEN_LIST(T, T)
- NUM_TOKENS
- };
+ TOKEN_LIST(T, T)
+ NUM_TOKENS
#undef T
+};
- // @returns a string corresponding to the C++ token name
- // (e.g. "LT" for the token LT).
- static char const* name(Value tok)
- {
- solAssert(tok < NUM_TOKENS, "");
- return m_name[tok];
- }
+namespace TokenTraits
+{
+ constexpr size_t count() { return static_cast<size_t>(Token::NUM_TOKENS); }
// Predicates
- static bool isElementaryTypeName(Value tok) { return Int <= tok && tok < TypesEnd; }
- static bool isAssignmentOp(Value tok) { return Assign <= tok && tok <= AssignMod; }
- static bool isBinaryOp(Value op) { return Comma <= op && op <= Exp; }
- static bool isCommutativeOp(Value op) { return op == BitOr || op == BitXor || op == BitAnd ||
- op == Add || op == Mul || op == Equal || op == NotEqual; }
- static bool isArithmeticOp(Value op) { return Add <= op && op <= Exp; }
- static bool isCompareOp(Value op) { return Equal <= op && op <= GreaterThanOrEqual; }
+ constexpr bool isElementaryTypeName(Token tok) { return Token::Int <= tok && tok < Token::TypesEnd; }
+ constexpr bool isAssignmentOp(Token tok) { return Token::Assign <= tok && tok <= Token::AssignMod; }
+ constexpr bool isBinaryOp(Token op) { return Token::Comma <= op && op <= Token::Exp; }
+ constexpr bool isCommutativeOp(Token op) { return op == Token::BitOr || op == Token::BitXor || op == Token::BitAnd ||
+ op == Token::Add || op == Token::Mul || op == Token::Equal || op == Token::NotEqual; }
+ constexpr bool isArithmeticOp(Token op) { return Token::Add <= op && op <= Token::Exp; }
+ constexpr bool isCompareOp(Token op) { return Token::Equal <= op && op <= Token::GreaterThanOrEqual; }
- static Value AssignmentToBinaryOp(Value op)
- {
- solAssert(isAssignmentOp(op) && op != Assign, "");
- return Value(op + (BitOr - AssignBitOr));
- }
+ constexpr bool isBitOp(Token op) { return (Token::BitOr <= op && op <= Token::BitAnd) || op == Token::BitNot; }
+ constexpr bool isBooleanOp(Token op) { return (Token::Or <= op && op <= Token::And) || op == Token::Not; }
+ constexpr bool isUnaryOp(Token op) { return (Token::Not <= op && op <= Token::Delete) || op == Token::Add || op == Token::Sub; }
+ constexpr bool isCountOp(Token op) { return op == Token::Inc || op == Token::Dec; }
+ constexpr bool isShiftOp(Token op) { return (Token::SHL <= op) && (op <= Token::SHR); }
+ constexpr bool isVariableVisibilitySpecifier(Token op) { return op == Token::Public || op == Token::Private || op == Token::Internal; }
+ constexpr bool isVisibilitySpecifier(Token op) { return isVariableVisibilitySpecifier(op) || op == Token::External; }
+ constexpr bool isLocationSpecifier(Token op) { return op == Token::Memory || op == Token::Storage || op == Token::CallData; }
- static bool isBitOp(Value op) { return (BitOr <= op && op <= BitAnd) || op == BitNot; }
- static bool isBooleanOp(Value op) { return (Or <= op && op <= And) || op == Not; }
- static bool isUnaryOp(Value op) { return (Not <= op && op <= Delete) || op == Add || op == Sub; }
- static bool isCountOp(Value op) { return op == Inc || op == Dec; }
- static bool isShiftOp(Value op) { return (SHL <= op) && (op <= SHR); }
- static bool isVisibilitySpecifier(Value op) { return isVariableVisibilitySpecifier(op) || op == External; }
- static bool isVariableVisibilitySpecifier(Value op) { return op == Public || op == Private || op == Internal; }
- static bool isLocationSpecifier(Value op) { return op == Memory || op == Storage || op == CallData; }
- static bool isStateMutabilitySpecifier(Value op, bool _allowConstant = true)
+ constexpr bool isStateMutabilitySpecifier(Token op, bool _allowConstant = true)
{
- if (op == Constant && _allowConstant)
- return true;
- return op == Pure || op == View || op == Payable;
+ return (op == Token::Constant && _allowConstant)
+ || op == Token::Pure || op == Token::View || op == Token::Payable;
}
- static bool isEtherSubdenomination(Value op) { return op == SubWei || op == SubSzabo || op == SubFinney || op == SubEther; }
- static bool isTimeSubdenomination(Value op) { return op == SubSecond || op == SubMinute || op == SubHour || op == SubDay || op == SubWeek || op == SubYear; }
- static bool isReservedKeyword(Value op) { return (Abstract <= op && op <= Unchecked); }
- // @returns a string corresponding to the JS token string
- // (.e., "<" for the token LT) or NULL if the token doesn't
- // have a (unique) string (e.g. an IDENTIFIER).
- static char const* toString(Value tok)
- {
- solAssert(tok < NUM_TOKENS, "");
- return m_string[tok];
- }
+ constexpr bool isEtherSubdenomination(Token op) { return op == Token::SubWei || op == Token::SubSzabo || op == Token::SubFinney || op == Token::SubEther; }
+ constexpr bool isTimeSubdenomination(Token op) { return op == Token::SubSecond || op == Token::SubMinute || op == Token::SubHour || op == Token::SubDay || op == Token::SubWeek || op == Token::SubYear; }
+ constexpr bool isReservedKeyword(Token op) { return (Token::Abstract <= op && op <= Token::Unchecked); }
- static std::string friendlyName(Value tok)
+ inline Token AssignmentToBinaryOp(Token op)
{
- char const* ret = toString(tok);
- if (ret == nullptr)
- {
- ret = name(tok);
- solAssert(ret != nullptr, "");
- }
- return std::string(ret);
+ solAssert(isAssignmentOp(op) && op != Token::Assign, "");
+ return static_cast<Token>(static_cast<int>(op) + (static_cast<int>(Token::BitOr) - static_cast<int>(Token::AssignBitOr)));
}
// @returns the precedence > 0 for binary and compare
// operators; returns 0 otherwise.
- static int precedence(Value tok)
- {
- solAssert(tok < NUM_TOKENS, "");
- return m_precedence[tok];
- }
+ int precedence(Token tok);
- static std::tuple<Token::Value, unsigned int, unsigned int> fromIdentifierOrKeyword(std::string const& _literal);
+ std::tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(std::string const& _literal);
-private:
- // @returns -1 on error (invalid digit or number too large)
- static int parseSize(std::string::const_iterator _begin, std::string::const_iterator _end);
- // @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];
-};
+ // @returns a string corresponding to the C++ token name
+ // (e.g. "LT" for the token LT).
+ char const* name(Token tok);
+
+ // @returns a string corresponding to the JS token string
+ // (.e., "<" for the token LT) or NULL if the token doesn't
+ // have a (unique) string (e.g. an IDENTIFIER).
+ char const* toString(Token tok);
+
+ std::string friendlyName(Token tok);
+}
+
+inline std::ostream& operator<<(std::ostream& os, Token token)
+{
+ os << TokenTraits::friendlyName(token);
+ return os;
+}
class ElementaryTypeNameToken
{
public:
- ElementaryTypeNameToken(Token::Value _token, unsigned const& _firstNumber, unsigned const& _secondNumber)
+ ElementaryTypeNameToken(Token _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; }
+ Token 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);
+ std::string name = TokenTraits::toString(m_token);
if (tokenValue || (firstNumber() == 0 && secondNumber() == 0))
return name;
solAssert(name.size() >= 3, "Token name size should be greater than 3. Should not reach here.");
@@ -390,11 +367,11 @@ public:
}
private:
- Token::Value m_token;
+ Token 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);
+ void assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second);
};
}