mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #5286 from ethereum/refactor-token-as-enum-class
refactor `libsolidity::Token` into a strongly typed enum
This commit is contained in:
commit
a2f5087d13
@ -46,7 +46,7 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation)
|
|||||||
m_errorReporter.fatalTypeError(
|
m_errorReporter.fatalTypeError(
|
||||||
_operation.location(),
|
_operation.location(),
|
||||||
"Operator " +
|
"Operator " +
|
||||||
string(Token::toString(_operation.getOperator())) +
|
string(TokenTraits::toString(_operation.getOperator())) +
|
||||||
" not compatible with types " +
|
" not compatible with types " +
|
||||||
left->toString() +
|
left->toString() +
|
||||||
" and " +
|
" and " +
|
||||||
@ -54,7 +54,7 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation)
|
|||||||
);
|
);
|
||||||
setType(
|
setType(
|
||||||
_operation,
|
_operation,
|
||||||
Token::isCompareOp(_operation.getOperator()) ?
|
TokenTraits::isCompareOp(_operation.getOperator()) ?
|
||||||
make_shared<BoolType>() :
|
make_shared<BoolType>() :
|
||||||
commonType
|
commonType
|
||||||
);
|
);
|
||||||
|
@ -199,7 +199,7 @@ void SemVerMatchExpressionParser::parseMatchExpression()
|
|||||||
SemVerMatchExpression::MatchComponent SemVerMatchExpressionParser::parseMatchComponent()
|
SemVerMatchExpression::MatchComponent SemVerMatchExpressionParser::parseMatchComponent()
|
||||||
{
|
{
|
||||||
SemVerMatchExpression::MatchComponent component;
|
SemVerMatchExpression::MatchComponent component;
|
||||||
Token::Value token = currentToken();
|
Token token = currentToken();
|
||||||
|
|
||||||
switch (token)
|
switch (token)
|
||||||
{
|
{
|
||||||
@ -280,7 +280,7 @@ char SemVerMatchExpressionParser::nextChar()
|
|||||||
return currentChar();
|
return currentChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value SemVerMatchExpressionParser::currentToken() const
|
Token SemVerMatchExpressionParser::currentToken() const
|
||||||
{
|
{
|
||||||
if (m_pos < m_tokens.size())
|
if (m_pos < m_tokens.size())
|
||||||
return m_tokens[m_pos];
|
return m_tokens[m_pos];
|
||||||
|
@ -61,7 +61,7 @@ struct SemVerMatchExpression
|
|||||||
struct MatchComponent
|
struct MatchComponent
|
||||||
{
|
{
|
||||||
/// Prefix from < > <= >= ~ ^
|
/// Prefix from < > <= >= ~ ^
|
||||||
Token::Value prefix = Token::Illegal;
|
Token prefix = Token::Illegal;
|
||||||
/// Version, where unsigned(-1) in major, minor or patch denotes '*', 'x' or 'X'
|
/// Version, where unsigned(-1) in major, minor or patch denotes '*', 'x' or 'X'
|
||||||
SemVerVersion version;
|
SemVerVersion version;
|
||||||
/// Whether we have 1, 1.2 or 1.2.4
|
/// Whether we have 1, 1.2 or 1.2.4
|
||||||
@ -81,7 +81,7 @@ struct SemVerMatchExpression
|
|||||||
class SemVerMatchExpressionParser
|
class SemVerMatchExpressionParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SemVerMatchExpressionParser(std::vector<Token::Value> const& _tokens, std::vector<std::string> const& _literals):
|
SemVerMatchExpressionParser(std::vector<Token> const& _tokens, std::vector<std::string> const& _literals):
|
||||||
m_tokens(_tokens), m_literals(_literals)
|
m_tokens(_tokens), m_literals(_literals)
|
||||||
{}
|
{}
|
||||||
SemVerMatchExpression parse();
|
SemVerMatchExpression parse();
|
||||||
@ -95,10 +95,10 @@ private:
|
|||||||
|
|
||||||
char currentChar() const;
|
char currentChar() const;
|
||||||
char nextChar();
|
char nextChar();
|
||||||
Token::Value currentToken() const;
|
Token currentToken() const;
|
||||||
void nextToken();
|
void nextToken();
|
||||||
|
|
||||||
std::vector<Token::Value> m_tokens;
|
std::vector<Token> m_tokens;
|
||||||
std::vector<std::string> m_literals;
|
std::vector<std::string> m_literals;
|
||||||
|
|
||||||
unsigned m_pos = 0;
|
unsigned m_pos = 0;
|
||||||
|
@ -106,7 +106,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
|
|||||||
}
|
}
|
||||||
else if (_pragma.literals()[0] == "solidity")
|
else if (_pragma.literals()[0] == "solidity")
|
||||||
{
|
{
|
||||||
vector<Token::Value> tokens(_pragma.tokens().begin() + 1, _pragma.tokens().end());
|
vector<Token> tokens(_pragma.tokens().begin() + 1, _pragma.tokens().end());
|
||||||
vector<string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
|
vector<string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
|
||||||
SemVerMatchExpressionParser parser(tokens, literals);
|
SemVerMatchExpressionParser parser(tokens, literals);
|
||||||
auto matchExpression = parser.parse();
|
auto matchExpression = parser.parse();
|
||||||
|
@ -1499,14 +1499,14 @@ bool TypeChecker::visit(Assignment const& _assignment)
|
|||||||
// compound assignment
|
// compound assignment
|
||||||
_assignment.rightHandSide().accept(*this);
|
_assignment.rightHandSide().accept(*this);
|
||||||
TypePointer resultType = t->binaryOperatorResult(
|
TypePointer resultType = t->binaryOperatorResult(
|
||||||
Token::AssignmentToBinaryOp(_assignment.assignmentOperator()),
|
TokenTraits::AssignmentToBinaryOp(_assignment.assignmentOperator()),
|
||||||
type(_assignment.rightHandSide())
|
type(_assignment.rightHandSide())
|
||||||
);
|
);
|
||||||
if (!resultType || *resultType != *t)
|
if (!resultType || *resultType != *t)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
_assignment.location(),
|
_assignment.location(),
|
||||||
"Operator " +
|
"Operator " +
|
||||||
string(Token::toString(_assignment.assignmentOperator())) +
|
string(TokenTraits::toString(_assignment.assignmentOperator())) +
|
||||||
" not compatible with types " +
|
" not compatible with types " +
|
||||||
t->toString() +
|
t->toString() +
|
||||||
" and " +
|
" and " +
|
||||||
@ -1607,8 +1607,8 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
|
|||||||
bool TypeChecker::visit(UnaryOperation const& _operation)
|
bool TypeChecker::visit(UnaryOperation const& _operation)
|
||||||
{
|
{
|
||||||
// Inc, Dec, Add, Sub, Not, BitNot, Delete
|
// Inc, Dec, Add, Sub, Not, BitNot, Delete
|
||||||
Token::Value op = _operation.getOperator();
|
Token op = _operation.getOperator();
|
||||||
bool const modifying = (op == Token::Value::Inc || op == Token::Value::Dec || op == Token::Value::Delete);
|
bool const modifying = (op == Token::Inc || op == Token::Dec || op == Token::Delete);
|
||||||
if (modifying)
|
if (modifying)
|
||||||
requireLValue(_operation.subExpression());
|
requireLValue(_operation.subExpression());
|
||||||
else
|
else
|
||||||
@ -1620,7 +1620,7 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
|
|||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
_operation.location(),
|
_operation.location(),
|
||||||
"Unary operator " +
|
"Unary operator " +
|
||||||
string(Token::toString(op)) +
|
string(TokenTraits::toString(op)) +
|
||||||
" cannot be applied to type " +
|
" cannot be applied to type " +
|
||||||
subExprType->toString()
|
subExprType->toString()
|
||||||
);
|
);
|
||||||
@ -1641,7 +1641,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
|
|||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
_operation.location(),
|
_operation.location(),
|
||||||
"Operator " +
|
"Operator " +
|
||||||
string(Token::toString(_operation.getOperator())) +
|
string(TokenTraits::toString(_operation.getOperator())) +
|
||||||
" not compatible with types " +
|
" not compatible with types " +
|
||||||
leftType->toString() +
|
leftType->toString() +
|
||||||
" and " +
|
" and " +
|
||||||
@ -1651,7 +1651,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
|
|||||||
}
|
}
|
||||||
_operation.annotation().commonType = commonType;
|
_operation.annotation().commonType = commonType;
|
||||||
_operation.annotation().type =
|
_operation.annotation().type =
|
||||||
Token::isCompareOp(_operation.getOperator()) ?
|
TokenTraits::isCompareOp(_operation.getOperator()) ?
|
||||||
make_shared<BoolType>() :
|
make_shared<BoolType>() :
|
||||||
commonType;
|
commonType;
|
||||||
_operation.annotation().isPure =
|
_operation.annotation().isPure =
|
||||||
|
@ -237,7 +237,7 @@ class PragmaDirective: public ASTNode
|
|||||||
public:
|
public:
|
||||||
PragmaDirective(
|
PragmaDirective(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
std::vector<Token::Value> const& _tokens,
|
std::vector<Token> const& _tokens,
|
||||||
std::vector<ASTString> const& _literals
|
std::vector<ASTString> const& _literals
|
||||||
): ASTNode(_location), m_tokens(_tokens), m_literals(_literals)
|
): ASTNode(_location), m_tokens(_tokens), m_literals(_literals)
|
||||||
{}
|
{}
|
||||||
@ -245,13 +245,13 @@ public:
|
|||||||
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;
|
||||||
|
|
||||||
std::vector<Token::Value> const& tokens() const { return m_tokens; }
|
std::vector<Token> const& tokens() const { return m_tokens; }
|
||||||
std::vector<ASTString> const& literals() const { return m_literals; }
|
std::vector<ASTString> const& literals() const { return m_literals; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// Sequence of tokens following the "pragma" keyword.
|
/// Sequence of tokens following the "pragma" keyword.
|
||||||
std::vector<Token::Value> m_tokens;
|
std::vector<Token> m_tokens;
|
||||||
/// Sequence of literals following the "pragma" keyword.
|
/// Sequence of literals following the "pragma" keyword.
|
||||||
std::vector<ASTString> m_literals;
|
std::vector<ASTString> m_literals;
|
||||||
};
|
};
|
||||||
@ -1379,7 +1379,7 @@ public:
|
|||||||
Assignment(
|
Assignment(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
ASTPointer<Expression> const& _leftHandSide,
|
ASTPointer<Expression> const& _leftHandSide,
|
||||||
Token::Value _assignmentOperator,
|
Token _assignmentOperator,
|
||||||
ASTPointer<Expression> const& _rightHandSide
|
ASTPointer<Expression> const& _rightHandSide
|
||||||
):
|
):
|
||||||
Expression(_location),
|
Expression(_location),
|
||||||
@ -1387,18 +1387,18 @@ public:
|
|||||||
m_assigmentOperator(_assignmentOperator),
|
m_assigmentOperator(_assignmentOperator),
|
||||||
m_rightHandSide(_rightHandSide)
|
m_rightHandSide(_rightHandSide)
|
||||||
{
|
{
|
||||||
solAssert(Token::isAssignmentOp(_assignmentOperator), "");
|
solAssert(TokenTraits::isAssignmentOp(_assignmentOperator), "");
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|
||||||
Expression const& leftHandSide() const { return *m_leftHandSide; }
|
Expression const& leftHandSide() const { return *m_leftHandSide; }
|
||||||
Token::Value assignmentOperator() const { return m_assigmentOperator; }
|
Token assignmentOperator() const { return m_assigmentOperator; }
|
||||||
Expression const& rightHandSide() const { return *m_rightHandSide; }
|
Expression const& rightHandSide() const { return *m_rightHandSide; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ASTPointer<Expression> m_leftHandSide;
|
ASTPointer<Expression> m_leftHandSide;
|
||||||
Token::Value m_assigmentOperator;
|
Token m_assigmentOperator;
|
||||||
ASTPointer<Expression> m_rightHandSide;
|
ASTPointer<Expression> m_rightHandSide;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1441,7 +1441,7 @@ class UnaryOperation: public Expression
|
|||||||
public:
|
public:
|
||||||
UnaryOperation(
|
UnaryOperation(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
Token::Value _operator,
|
Token _operator,
|
||||||
ASTPointer<Expression> const& _subExpression,
|
ASTPointer<Expression> const& _subExpression,
|
||||||
bool _isPrefix
|
bool _isPrefix
|
||||||
):
|
):
|
||||||
@ -1450,17 +1450,17 @@ public:
|
|||||||
m_subExpression(_subExpression),
|
m_subExpression(_subExpression),
|
||||||
m_isPrefix(_isPrefix)
|
m_isPrefix(_isPrefix)
|
||||||
{
|
{
|
||||||
solAssert(Token::isUnaryOp(_operator), "");
|
solAssert(TokenTraits::isUnaryOp(_operator), "");
|
||||||
}
|
}
|
||||||
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 getOperator() const { return m_operator; }
|
Token getOperator() const { return m_operator; }
|
||||||
bool isPrefixOperation() const { return m_isPrefix; }
|
bool isPrefixOperation() const { return m_isPrefix; }
|
||||||
Expression const& subExpression() const { return *m_subExpression; }
|
Expression const& subExpression() const { return *m_subExpression; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value m_operator;
|
Token m_operator;
|
||||||
ASTPointer<Expression> m_subExpression;
|
ASTPointer<Expression> m_subExpression;
|
||||||
bool m_isPrefix;
|
bool m_isPrefix;
|
||||||
};
|
};
|
||||||
@ -1475,25 +1475,25 @@ public:
|
|||||||
BinaryOperation(
|
BinaryOperation(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
ASTPointer<Expression> const& _left,
|
ASTPointer<Expression> const& _left,
|
||||||
Token::Value _operator,
|
Token _operator,
|
||||||
ASTPointer<Expression> const& _right
|
ASTPointer<Expression> const& _right
|
||||||
):
|
):
|
||||||
Expression(_location), m_left(_left), m_operator(_operator), m_right(_right)
|
Expression(_location), m_left(_left), m_operator(_operator), m_right(_right)
|
||||||
{
|
{
|
||||||
solAssert(Token::isBinaryOp(_operator) || Token::isCompareOp(_operator), "");
|
solAssert(TokenTraits::isBinaryOp(_operator) || TokenTraits::isCompareOp(_operator), "");
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|
||||||
Expression const& leftExpression() const { return *m_left; }
|
Expression const& leftExpression() const { return *m_left; }
|
||||||
Expression const& rightExpression() const { return *m_right; }
|
Expression const& rightExpression() const { return *m_right; }
|
||||||
Token::Value getOperator() const { return m_operator; }
|
Token getOperator() const { return m_operator; }
|
||||||
|
|
||||||
BinaryOperationAnnotation& annotation() const override;
|
BinaryOperationAnnotation& annotation() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ASTPointer<Expression> m_left;
|
ASTPointer<Expression> m_left;
|
||||||
Token::Value m_operator;
|
Token m_operator;
|
||||||
ASTPointer<Expression> m_right;
|
ASTPointer<Expression> m_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1653,21 +1653,21 @@ class Literal: public PrimaryExpression
|
|||||||
public:
|
public:
|
||||||
enum class SubDenomination
|
enum class SubDenomination
|
||||||
{
|
{
|
||||||
None = Token::Illegal,
|
None = static_cast<int>(Token::Illegal),
|
||||||
Wei = Token::SubWei,
|
Wei = static_cast<int>(Token::SubWei),
|
||||||
Szabo = Token::SubSzabo,
|
Szabo = static_cast<int>(Token::SubSzabo),
|
||||||
Finney = Token::SubFinney,
|
Finney = static_cast<int>(Token::SubFinney),
|
||||||
Ether = Token::SubEther,
|
Ether = static_cast<int>(Token::SubEther),
|
||||||
Second = Token::SubSecond,
|
Second = static_cast<int>(Token::SubSecond),
|
||||||
Minute = Token::SubMinute,
|
Minute = static_cast<int>(Token::SubMinute),
|
||||||
Hour = Token::SubHour,
|
Hour = static_cast<int>(Token::SubHour),
|
||||||
Day = Token::SubDay,
|
Day = static_cast<int>(Token::SubDay),
|
||||||
Week = Token::SubWeek,
|
Week = static_cast<int>(Token::SubWeek),
|
||||||
Year = Token::SubYear
|
Year = static_cast<int>(Token::SubYear)
|
||||||
};
|
};
|
||||||
Literal(
|
Literal(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
Token::Value _token,
|
Token _token,
|
||||||
ASTPointer<ASTString> const& _value,
|
ASTPointer<ASTString> const& _value,
|
||||||
SubDenomination _sub = SubDenomination::None
|
SubDenomination _sub = SubDenomination::None
|
||||||
):
|
):
|
||||||
@ -1675,7 +1675,7 @@ public:
|
|||||||
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 token() const { return m_token; }
|
Token token() const { return m_token; }
|
||||||
/// @returns the non-parsed value of the literal
|
/// @returns the non-parsed value of the literal
|
||||||
ASTString const& value() const { return *m_value; }
|
ASTString const& value() const { return *m_value; }
|
||||||
|
|
||||||
@ -1694,7 +1694,7 @@ public:
|
|||||||
std::string getChecksummedAddress() const;
|
std::string getChecksummedAddress() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value m_token;
|
Token m_token;
|
||||||
ASTPointer<ASTString> m_value;
|
ASTPointer<ASTString> m_value;
|
||||||
SubDenomination m_subDenomination;
|
SubDenomination m_subDenomination;
|
||||||
};
|
};
|
||||||
|
@ -589,7 +589,7 @@ bool ASTJsonConverter::visit(Conditional const& _node)
|
|||||||
bool ASTJsonConverter::visit(Assignment const& _node)
|
bool ASTJsonConverter::visit(Assignment const& _node)
|
||||||
{
|
{
|
||||||
std::vector<pair<string, Json::Value>> attributes = {
|
std::vector<pair<string, Json::Value>> attributes = {
|
||||||
make_pair("operator", Token::toString(_node.assignmentOperator())),
|
make_pair("operator", TokenTraits::toString(_node.assignmentOperator())),
|
||||||
make_pair("leftHandSide", toJson(_node.leftHandSide())),
|
make_pair("leftHandSide", toJson(_node.leftHandSide())),
|
||||||
make_pair("rightHandSide", toJson(_node.rightHandSide()))
|
make_pair("rightHandSide", toJson(_node.rightHandSide()))
|
||||||
};
|
};
|
||||||
@ -613,7 +613,7 @@ bool ASTJsonConverter::visit(UnaryOperation const& _node)
|
|||||||
{
|
{
|
||||||
std::vector<pair<string, Json::Value>> attributes = {
|
std::vector<pair<string, Json::Value>> attributes = {
|
||||||
make_pair("prefix", _node.isPrefixOperation()),
|
make_pair("prefix", _node.isPrefixOperation()),
|
||||||
make_pair("operator", Token::toString(_node.getOperator())),
|
make_pair("operator", TokenTraits::toString(_node.getOperator())),
|
||||||
make_pair("subExpression", toJson(_node.subExpression()))
|
make_pair("subExpression", toJson(_node.subExpression()))
|
||||||
};
|
};
|
||||||
appendExpressionAttributes(attributes, _node.annotation());
|
appendExpressionAttributes(attributes, _node.annotation());
|
||||||
@ -624,7 +624,7 @@ bool ASTJsonConverter::visit(UnaryOperation const& _node)
|
|||||||
bool ASTJsonConverter::visit(BinaryOperation const& _node)
|
bool ASTJsonConverter::visit(BinaryOperation const& _node)
|
||||||
{
|
{
|
||||||
std::vector<pair<string, Json::Value>> attributes = {
|
std::vector<pair<string, Json::Value>> attributes = {
|
||||||
make_pair("operator", Token::toString(_node.getOperator())),
|
make_pair("operator", TokenTraits::toString(_node.getOperator())),
|
||||||
make_pair("leftExpression", toJson(_node.leftExpression())),
|
make_pair("leftExpression", toJson(_node.leftExpression())),
|
||||||
make_pair("rightExpression", toJson(_node.rightExpression())),
|
make_pair("rightExpression", toJson(_node.rightExpression())),
|
||||||
make_pair("commonType", typePointerToJson(_node.annotation().commonType)),
|
make_pair("commonType", typePointerToJson(_node.annotation().commonType)),
|
||||||
@ -719,7 +719,7 @@ bool ASTJsonConverter::visit(Literal const& _node)
|
|||||||
Json::Value value{_node.value()};
|
Json::Value value{_node.value()};
|
||||||
if (!dev::validateUTF8(_node.value()))
|
if (!dev::validateUTF8(_node.value()))
|
||||||
value = Json::nullValue;
|
value = Json::nullValue;
|
||||||
Token::Value subdenomination = Token::Value(_node.subDenomination());
|
Token subdenomination = Token(_node.subDenomination());
|
||||||
std::vector<pair<string, Json::Value>> attributes = {
|
std::vector<pair<string, Json::Value>> attributes = {
|
||||||
make_pair(m_legacy ? "token" : "kind", literalTokenKind(_node.token())),
|
make_pair(m_legacy ? "token" : "kind", literalTokenKind(_node.token())),
|
||||||
make_pair("value", value),
|
make_pair("value", value),
|
||||||
@ -728,7 +728,7 @@ bool ASTJsonConverter::visit(Literal const& _node)
|
|||||||
"subdenomination",
|
"subdenomination",
|
||||||
subdenomination == Token::Illegal ?
|
subdenomination == Token::Illegal ?
|
||||||
Json::nullValue :
|
Json::nullValue :
|
||||||
Json::Value{Token::toString(subdenomination)}
|
Json::Value{TokenTraits::toString(subdenomination)}
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
appendExpressionAttributes(attributes, _node.annotation());
|
appendExpressionAttributes(attributes, _node.annotation());
|
||||||
@ -790,7 +790,7 @@ string ASTJsonConverter::functionCallKind(FunctionCallKind _kind)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string ASTJsonConverter::literalTokenKind(Token::Value _token)
|
string ASTJsonConverter::literalTokenKind(Token _token)
|
||||||
{
|
{
|
||||||
switch (_token)
|
switch (_token)
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ private:
|
|||||||
static std::string location(VariableDeclaration::Location _location);
|
static std::string location(VariableDeclaration::Location _location);
|
||||||
static std::string contractKind(ContractDefinition::ContractKind _kind);
|
static std::string contractKind(ContractDefinition::ContractKind _kind);
|
||||||
static std::string functionCallKind(FunctionCallKind _kind);
|
static std::string functionCallKind(FunctionCallKind _kind);
|
||||||
static std::string literalTokenKind(Token::Value _token);
|
static std::string literalTokenKind(Token _token);
|
||||||
static std::string type(Expression const& _expression);
|
static std::string type(Expression const& _expression);
|
||||||
static std::string type(VariableDeclaration const& _varDecl);
|
static std::string type(VariableDeclaration const& _varDecl);
|
||||||
static int nodeId(ASTNode const& _node)
|
static int nodeId(ASTNode const& _node)
|
||||||
|
@ -289,7 +289,7 @@ bool ASTPrinter::visit(Conditional const& _node)
|
|||||||
|
|
||||||
bool ASTPrinter::visit(Assignment const& _node)
|
bool ASTPrinter::visit(Assignment const& _node)
|
||||||
{
|
{
|
||||||
writeLine(string("Assignment using operator ") + Token::toString(_node.assignmentOperator()));
|
writeLine(string("Assignment using operator ") + TokenTraits::toString(_node.assignmentOperator()));
|
||||||
printType(_node);
|
printType(_node);
|
||||||
printSourcePart(_node);
|
printSourcePart(_node);
|
||||||
return goDeeper();
|
return goDeeper();
|
||||||
@ -306,7 +306,7 @@ bool ASTPrinter::visit(TupleExpression const& _node)
|
|||||||
bool ASTPrinter::visit(UnaryOperation const& _node)
|
bool ASTPrinter::visit(UnaryOperation const& _node)
|
||||||
{
|
{
|
||||||
writeLine(string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") +
|
writeLine(string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") +
|
||||||
") " + Token::toString(_node.getOperator()));
|
") " + TokenTraits::toString(_node.getOperator()));
|
||||||
printType(_node);
|
printType(_node);
|
||||||
printSourcePart(_node);
|
printSourcePart(_node);
|
||||||
return goDeeper();
|
return goDeeper();
|
||||||
@ -314,7 +314,7 @@ bool ASTPrinter::visit(UnaryOperation const& _node)
|
|||||||
|
|
||||||
bool ASTPrinter::visit(BinaryOperation const& _node)
|
bool ASTPrinter::visit(BinaryOperation const& _node)
|
||||||
{
|
{
|
||||||
writeLine(string("BinaryOperation using operator ") + Token::toString(_node.getOperator()));
|
writeLine(string("BinaryOperation using operator ") + TokenTraits::toString(_node.getOperator()));
|
||||||
printType(_node);
|
printType(_node);
|
||||||
printSourcePart(_node);
|
printSourcePart(_node);
|
||||||
return goDeeper();
|
return goDeeper();
|
||||||
@ -370,7 +370,7 @@ bool ASTPrinter::visit(ElementaryTypeNameExpression const& _node)
|
|||||||
|
|
||||||
bool ASTPrinter::visit(Literal const& _node)
|
bool ASTPrinter::visit(Literal const& _node)
|
||||||
{
|
{
|
||||||
char const* tokenString = Token::toString(_node.token());
|
char const* tokenString = TokenTraits::toString(_node.token());
|
||||||
if (!tokenString)
|
if (!tokenString)
|
||||||
tokenString = "[no token]";
|
tokenString = "[no token]";
|
||||||
writeLine(string("Literal, token: ") + tokenString + " value: " + _node.value());
|
writeLine(string("Literal, token: ") + tokenString + " value: " + _node.value());
|
||||||
|
@ -268,11 +268,11 @@ string Type::identifier() const
|
|||||||
|
|
||||||
TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
|
TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
|
||||||
{
|
{
|
||||||
solAssert(Token::isElementaryTypeName(_type.token()),
|
solAssert(TokenTraits::isElementaryTypeName(_type.token()),
|
||||||
"Expected an elementary type name but got " + _type.toString()
|
"Expected an elementary type name but got " + _type.toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
Token::Value token = _type.token();
|
Token token = _type.token();
|
||||||
unsigned m = _type.firstNumber();
|
unsigned m = _type.firstNumber();
|
||||||
unsigned n = _type.secondNumber();
|
unsigned n = _type.secondNumber();
|
||||||
|
|
||||||
@ -320,9 +320,9 @@ TypePointer Type::fromElementaryTypeName(string const& _name)
|
|||||||
vector<string> nameParts;
|
vector<string> nameParts;
|
||||||
boost::split(nameParts, _name, boost::is_any_of(" "));
|
boost::split(nameParts, _name, boost::is_any_of(" "));
|
||||||
solAssert(nameParts.size() == 1 || nameParts.size() == 2, "Cannot parse elementary type: " + _name);
|
solAssert(nameParts.size() == 1 || nameParts.size() == 2, "Cannot parse elementary type: " + _name);
|
||||||
Token::Value token;
|
Token token;
|
||||||
unsigned short firstNum, secondNum;
|
unsigned short firstNum, secondNum;
|
||||||
tie(token, firstNum, secondNum) = Token::fromIdentifierOrKeyword(nameParts[0]);
|
tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(nameParts[0]);
|
||||||
auto t = fromElementaryTypeName(ElementaryTypeNameToken(token, firstNum, secondNum));
|
auto t = fromElementaryTypeName(ElementaryTypeNameToken(token, firstNum, secondNum));
|
||||||
if (auto* ref = dynamic_cast<ReferenceType const*>(t.get()))
|
if (auto* ref = dynamic_cast<ReferenceType const*>(t.get()))
|
||||||
{
|
{
|
||||||
@ -502,16 +502,16 @@ u256 AddressType::literalValue(Literal const* _literal) const
|
|||||||
return u256(_literal->valueWithoutUnderscores());
|
return u256(_literal->valueWithoutUnderscores());
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer AddressType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer AddressType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TypePointer AddressType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
TypePointer AddressType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||||
{
|
{
|
||||||
// Addresses can only be compared.
|
// Addresses can only be compared.
|
||||||
if (!Token::isCompareOp(_operator))
|
if (!TokenTraits::isCompareOp(_operator))
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
|
|
||||||
return Type::commonType(shared_from_this(), _other);
|
return Type::commonType(shared_from_this(), _other);
|
||||||
@ -545,7 +545,7 @@ MemberList::MemberMap AddressType::nativeMembers(ContractDefinition const*) cons
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
bool isValidShiftAndAmountType(Token::Value _operator, Type const& _shiftAmountType)
|
bool isValidShiftAndAmountType(Token _operator, Type const& _shiftAmountType)
|
||||||
{
|
{
|
||||||
// Disable >>> here.
|
// Disable >>> here.
|
||||||
if (_operator == Token::SHR)
|
if (_operator == Token::SHR)
|
||||||
@ -605,7 +605,7 @@ bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
_convertTo.category() == Category::FixedPoint;
|
_convertTo.category() == Category::FixedPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer IntegerType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
// "delete" is ok for all integer types
|
// "delete" is ok for all integer types
|
||||||
if (_operator == Token::Delete)
|
if (_operator == Token::Delete)
|
||||||
@ -649,7 +649,7 @@ bigint IntegerType::maxValue() const
|
|||||||
return (bigint(1) << m_bits) - 1;
|
return (bigint(1) << m_bits) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
TypePointer IntegerType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
_other->category() != Category::RationalNumber &&
|
_other->category() != Category::RationalNumber &&
|
||||||
@ -657,7 +657,7 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
|
|||||||
_other->category() != category()
|
_other->category() != category()
|
||||||
)
|
)
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
if (Token::isShiftOp(_operator))
|
if (TokenTraits::isShiftOp(_operator))
|
||||||
{
|
{
|
||||||
// Shifts are not symmetric with respect to the type
|
// Shifts are not symmetric with respect to the type
|
||||||
if (isValidShiftAndAmountType(_operator, *_other))
|
if (isValidShiftAndAmountType(_operator, *_other))
|
||||||
@ -671,9 +671,9 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
|
|
||||||
// All integer types can be compared
|
// All integer types can be compared
|
||||||
if (Token::isCompareOp(_operator))
|
if (TokenTraits::isCompareOp(_operator))
|
||||||
return commonType;
|
return commonType;
|
||||||
if (Token::isBooleanOp(_operator))
|
if (TokenTraits::isBooleanOp(_operator))
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
if (auto intType = dynamic_pointer_cast<IntegerType const>(commonType))
|
if (auto intType = dynamic_pointer_cast<IntegerType const>(commonType))
|
||||||
{
|
{
|
||||||
@ -720,7 +720,7 @@ bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
return _convertTo.category() == category() || _convertTo.category() == Category::Integer;
|
return _convertTo.category() == category() || _convertTo.category() == Category::Integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer FixedPointType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer FixedPointType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
switch(_operator)
|
switch(_operator)
|
||||||
{
|
{
|
||||||
@ -769,7 +769,7 @@ bigint FixedPointType::minIntegerValue() const
|
|||||||
return bigint(0);
|
return bigint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
TypePointer FixedPointType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||||
{
|
{
|
||||||
auto commonType = Type::commonType(shared_from_this(), _other);
|
auto commonType = Type::commonType(shared_from_this(), _other);
|
||||||
|
|
||||||
@ -777,9 +777,9 @@ TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePoi
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
|
|
||||||
// All fixed types can be compared
|
// All fixed types can be compared
|
||||||
if (Token::isCompareOp(_operator))
|
if (TokenTraits::isCompareOp(_operator))
|
||||||
return commonType;
|
return commonType;
|
||||||
if (Token::isBitOp(_operator) || Token::isBooleanOp(_operator) || _operator == Token::Exp)
|
if (TokenTraits::isBitOp(_operator) || TokenTraits::isBooleanOp(_operator) || _operator == Token::Exp)
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
return commonType;
|
return commonType;
|
||||||
}
|
}
|
||||||
@ -1006,7 +1006,7 @@ bool RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer RationalNumberType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer RationalNumberType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
rational value;
|
rational value;
|
||||||
switch (_operator)
|
switch (_operator)
|
||||||
@ -1030,7 +1030,7 @@ TypePointer RationalNumberType::unaryOperatorResult(Token::Value _operator) cons
|
|||||||
return make_shared<RationalNumberType>(value);
|
return make_shared<RationalNumberType>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||||
{
|
{
|
||||||
if (_other->category() == Category::Integer || _other->category() == Category::FixedPoint)
|
if (_other->category() == Category::Integer || _other->category() == Category::FixedPoint)
|
||||||
{
|
{
|
||||||
@ -1043,7 +1043,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
|
|
||||||
RationalNumberType const& other = dynamic_cast<RationalNumberType const&>(*_other);
|
RationalNumberType const& other = dynamic_cast<RationalNumberType const&>(*_other);
|
||||||
if (Token::isCompareOp(_operator))
|
if (TokenTraits::isCompareOp(_operator))
|
||||||
{
|
{
|
||||||
// Since we do not have a "BoolConstantType", we have to do the actual comparison
|
// Since we do not have a "BoolConstantType", we have to do the actual comparison
|
||||||
// at runtime and convert to mobile typse first. Such a comparison is not a very common
|
// at runtime and convert to mobile typse first. Such a comparison is not a very common
|
||||||
@ -1423,7 +1423,7 @@ bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
_convertTo.category() == category();
|
_convertTo.category() == category();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer FixedBytesType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
// "delete" and "~" is okay for FixedBytesType
|
// "delete" and "~" is okay for FixedBytesType
|
||||||
if (_operator == Token::Delete)
|
if (_operator == Token::Delete)
|
||||||
@ -1434,9 +1434,9 @@ TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
TypePointer FixedBytesType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||||
{
|
{
|
||||||
if (Token::isShiftOp(_operator))
|
if (TokenTraits::isShiftOp(_operator))
|
||||||
{
|
{
|
||||||
if (isValidShiftAndAmountType(_operator, *_other))
|
if (isValidShiftAndAmountType(_operator, *_other))
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
@ -1449,7 +1449,7 @@ TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePoi
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
|
|
||||||
// FixedBytes can be compared and have bitwise operators applied to them
|
// FixedBytes can be compared and have bitwise operators applied to them
|
||||||
if (Token::isCompareOp(_operator) || Token::isBitOp(_operator))
|
if (TokenTraits::isCompareOp(_operator) || TokenTraits::isBitOp(_operator))
|
||||||
return commonType;
|
return commonType;
|
||||||
|
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
@ -1484,14 +1484,14 @@ u256 BoolType::literalValue(Literal const* _literal) const
|
|||||||
solAssert(false, "Bool type constructed from non-boolean literal.");
|
solAssert(false, "Bool type constructed from non-boolean literal.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer BoolType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer BoolType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
if (_operator == Token::Delete)
|
if (_operator == Token::Delete)
|
||||||
return make_shared<TupleType>();
|
return make_shared<TupleType>();
|
||||||
return (_operator == Token::Not) ? shared_from_this() : TypePointer();
|
return (_operator == Token::Not) ? shared_from_this() : TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer BoolType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
TypePointer BoolType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||||
{
|
{
|
||||||
if (category() != _other->category())
|
if (category() != _other->category())
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
@ -1531,14 +1531,14 @@ bool ContractType::isPayable() const
|
|||||||
return fallbackFunction && fallbackFunction->isPayable();
|
return fallbackFunction && fallbackFunction->isPayable();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer ContractType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
if (isSuper())
|
if (isSuper())
|
||||||
return TypePointer{};
|
return TypePointer{};
|
||||||
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer ReferenceType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer ReferenceType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
if (_operator != Token::Delete)
|
if (_operator != Token::Delete)
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
@ -2237,7 +2237,7 @@ bool StructType::recursive() const
|
|||||||
return *m_recursive;
|
return *m_recursive;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer EnumType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer EnumType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
||||||
}
|
}
|
||||||
@ -2668,14 +2668,14 @@ bool FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer FunctionType::unaryOperatorResult(Token::Value _operator) const
|
TypePointer FunctionType::unaryOperatorResult(Token _operator) const
|
||||||
{
|
{
|
||||||
if (_operator == Token::Value::Delete)
|
if (_operator == Token::Delete)
|
||||||
return make_shared<TupleType>();
|
return make_shared<TupleType>();
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer FunctionType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
TypePointer FunctionType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||||
{
|
{
|
||||||
if (_other->category() != category() || !(_operator == Token::Equal || _operator == Token::NotEqual))
|
if (_other->category() != category() || !(_operator == Token::Equal || _operator == Token::NotEqual))
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
|
@ -188,13 +188,13 @@ public:
|
|||||||
/// @returns the resulting type of applying the given unary operator or an empty pointer if
|
/// @returns the resulting type of applying the given unary operator or an empty pointer if
|
||||||
/// this is not possible.
|
/// this is not possible.
|
||||||
/// The default implementation does not allow any unary operator.
|
/// The default implementation does not allow any unary operator.
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value) const { return TypePointer(); }
|
virtual TypePointer unaryOperatorResult(Token) const { return TypePointer(); }
|
||||||
/// @returns the resulting type of applying the given binary operator or an empty pointer if
|
/// @returns the resulting type of applying the given binary operator or an empty pointer if
|
||||||
/// this is not possible.
|
/// this is not possible.
|
||||||
/// The default implementation allows comparison operators if a common type exists
|
/// The default implementation allows comparison operators if a common type exists
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||||
{
|
{
|
||||||
return Token::isCompareOp(_operator) ? commonType(shared_from_this(), _other) : TypePointer();
|
return TokenTraits::isCompareOp(_operator) ? commonType(shared_from_this(), _other) : TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator==(Type const& _other) const { return category() == _other.category(); }
|
virtual bool operator==(Type const& _other) const { return category() == _other.category(); }
|
||||||
@ -329,8 +329,8 @@ public:
|
|||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||||
|
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
|
|
||||||
@ -372,8 +372,8 @@ public:
|
|||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||||
|
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
|
|
||||||
@ -414,8 +414,8 @@ public:
|
|||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||||
|
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
|
|
||||||
@ -468,8 +468,8 @@ public:
|
|||||||
|
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||||
|
|
||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
@ -526,7 +526,7 @@ public:
|
|||||||
explicit StringLiteralType(Literal const& _literal);
|
explicit StringLiteralType(Literal const& _literal);
|
||||||
|
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override
|
||||||
{
|
{
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
@ -563,8 +563,8 @@ public:
|
|||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||||
|
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; }
|
virtual unsigned calldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; }
|
||||||
virtual unsigned storageBytes() const override { return m_bytes; }
|
virtual unsigned storageBytes() const override { return m_bytes; }
|
||||||
@ -590,8 +590,8 @@ public:
|
|||||||
BoolType() {}
|
BoolType() {}
|
||||||
virtual Category category() const override { return Category::Bool; }
|
virtual Category category() const override { return Category::Bool; }
|
||||||
virtual std::string richIdentifier() const override { return "t_bool"; }
|
virtual std::string richIdentifier() const override { return "t_bool"; }
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||||
|
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override{ return _padded ? 32 : 1; }
|
virtual unsigned calldataEncodedSize(bool _padded) const override{ return _padded ? 32 : 1; }
|
||||||
virtual unsigned storageBytes() const override { return 1; }
|
virtual unsigned storageBytes() const override { return 1; }
|
||||||
@ -613,8 +613,8 @@ public:
|
|||||||
explicit ReferenceType(DataLocation _location): m_location(_location) {}
|
explicit ReferenceType(DataLocation _location): m_location(_location) {}
|
||||||
DataLocation location() const { return m_location; }
|
DataLocation location() const { return m_location; }
|
||||||
|
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override
|
||||||
{
|
{
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
@ -749,7 +749,7 @@ public:
|
|||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
/// Contracts can only be explicitly converted to address types and base contracts.
|
/// Contracts can only be explicitly converted to address types and base contracts.
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded ) const override
|
virtual unsigned calldataEncodedSize(bool _padded ) const override
|
||||||
@ -865,7 +865,7 @@ class EnumType: public Type
|
|||||||
public:
|
public:
|
||||||
virtual Category category() const override { return Category::Enum; }
|
virtual Category category() const override { return Category::Enum; }
|
||||||
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
|
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override
|
virtual unsigned calldataEncodedSize(bool _padded) const override
|
||||||
@ -909,7 +909,7 @@ public:
|
|||||||
virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
|
||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||||
virtual std::string toString(bool) const override;
|
virtual std::string toString(bool) const override;
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
virtual u256 storageSize() const override;
|
virtual u256 storageSize() const override;
|
||||||
@ -1056,8 +1056,8 @@ public:
|
|||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override;
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override;
|
||||||
virtual std::string canonicalName() const override;
|
virtual std::string canonicalName() const override;
|
||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override;
|
virtual unsigned calldataEncodedSize(bool _padded) const override;
|
||||||
@ -1187,7 +1187,7 @@ public:
|
|||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
virtual std::string canonicalName() const override;
|
virtual std::string canonicalName() const override;
|
||||||
virtual bool canLiveOutsideStorage() const override { return false; }
|
virtual bool canLiveOutsideStorage() const override { return false; }
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||||
virtual TypePointer encodingType() const override
|
virtual TypePointer encodingType() const override
|
||||||
{
|
{
|
||||||
return std::make_shared<IntegerType>(256);
|
return std::make_shared<IntegerType>(256);
|
||||||
@ -1220,7 +1220,7 @@ public:
|
|||||||
explicit TypeType(TypePointer const& _actualType): m_actualType(_actualType) {}
|
explicit TypeType(TypePointer const& _actualType): m_actualType(_actualType) {}
|
||||||
TypePointer const& actualType() const { return m_actualType; }
|
TypePointer const& actualType() const { return m_actualType; }
|
||||||
|
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
@ -1245,7 +1245,7 @@ public:
|
|||||||
virtual Category category() const override { return Category::Modifier; }
|
virtual Category category() const override { return Category::Modifier; }
|
||||||
explicit ModifierType(ModifierDefinition const& _modifier);
|
explicit ModifierType(ModifierDefinition const& _modifier);
|
||||||
|
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
virtual u256 storageSize() const override;
|
virtual u256 storageSize() const override;
|
||||||
virtual bool canLiveOutsideStorage() const override { return false; }
|
virtual bool canLiveOutsideStorage() const override { return false; }
|
||||||
@ -1271,7 +1271,7 @@ public:
|
|||||||
|
|
||||||
explicit ModuleType(SourceUnit const& _source): m_sourceUnit(_source) {}
|
explicit ModuleType(SourceUnit const& _source): m_sourceUnit(_source) {}
|
||||||
|
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||||
virtual std::string richIdentifier() const override;
|
virtual std::string richIdentifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
@ -1298,7 +1298,7 @@ public:
|
|||||||
|
|
||||||
explicit MagicType(Kind _kind): m_kind(_kind) {}
|
explicit MagicType(Kind _kind): m_kind(_kind) {}
|
||||||
|
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override
|
||||||
{
|
{
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
@ -1331,7 +1331,7 @@ public:
|
|||||||
virtual std::string richIdentifier() const override { return "t_inaccessible"; }
|
virtual std::string richIdentifier() const override { return "t_inaccessible"; }
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const&) const override { return false; }
|
virtual bool isImplicitlyConvertibleTo(Type const&) const override { return false; }
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const&) const override { return false; }
|
virtual bool isExplicitlyConvertibleTo(Type const&) const override { return false; }
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; }
|
virtual unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; }
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
virtual bool canLiveOutsideStorage() const override { return false; }
|
virtual bool canLiveOutsideStorage() const override { return false; }
|
||||||
|
@ -206,8 +206,8 @@ bool ExpressionCompiler::visit(Conditional const& _condition)
|
|||||||
bool ExpressionCompiler::visit(Assignment const& _assignment)
|
bool ExpressionCompiler::visit(Assignment const& _assignment)
|
||||||
{
|
{
|
||||||
CompilerContext::LocationSetter locationSetter(m_context, _assignment);
|
CompilerContext::LocationSetter locationSetter(m_context, _assignment);
|
||||||
Token::Value op = _assignment.assignmentOperator();
|
Token op = _assignment.assignmentOperator();
|
||||||
Token::Value binOp = op == Token::Assign ? op : Token::AssignmentToBinaryOp(op);
|
Token binOp = op == Token::Assign ? op : TokenTraits::AssignmentToBinaryOp(op);
|
||||||
Type const& leftType = *_assignment.leftHandSide().annotation().type;
|
Type const& leftType = *_assignment.leftHandSide().annotation().type;
|
||||||
if (leftType.category() == Type::Category::Tuple)
|
if (leftType.category() == Type::Category::Tuple)
|
||||||
{
|
{
|
||||||
@ -223,7 +223,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
|
|||||||
// Perform some conversion already. This will convert storage types to memory and literals
|
// Perform some conversion already. This will convert storage types to memory and literals
|
||||||
// to their actual type, but will not convert e.g. memory to storage.
|
// to their actual type, but will not convert e.g. memory to storage.
|
||||||
TypePointer rightIntermediateType;
|
TypePointer rightIntermediateType;
|
||||||
if (op != Token::Assign && Token::isShiftOp(binOp))
|
if (op != Token::Assign && TokenTraits::isShiftOp(binOp))
|
||||||
rightIntermediateType = _assignment.rightHandSide().annotation().type->mobileType();
|
rightIntermediateType = _assignment.rightHandSide().annotation().type->mobileType();
|
||||||
else
|
else
|
||||||
rightIntermediateType = _assignment.rightHandSide().annotation().type->closestTemporaryType(
|
rightIntermediateType = _assignment.rightHandSide().annotation().type->closestTemporaryType(
|
||||||
@ -251,7 +251,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
|
|||||||
m_currentLValue->retrieveValue(_assignment.location(), true);
|
m_currentLValue->retrieveValue(_assignment.location(), true);
|
||||||
utils().convertType(leftType, leftType, cleanupNeeded);
|
utils().convertType(leftType, leftType, cleanupNeeded);
|
||||||
|
|
||||||
if (Token::isShiftOp(binOp))
|
if (TokenTraits::isShiftOp(binOp))
|
||||||
appendShiftOperatorCode(binOp, leftType, *rightIntermediateType);
|
appendShiftOperatorCode(binOp, leftType, *rightIntermediateType);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -384,7 +384,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
|
|||||||
m_context << u256(0) << Instruction::SUB;
|
m_context << u256(0) << Instruction::SUB;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
solAssert(false, "Invalid unary operator: " + string(Token::toString(_unaryOperation.getOperator())));
|
solAssert(false, "Invalid unary operator: " + string(TokenTraits::toString(_unaryOperation.getOperator())));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -396,7 +396,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
|||||||
Expression const& rightExpression = _binaryOperation.rightExpression();
|
Expression const& rightExpression = _binaryOperation.rightExpression();
|
||||||
solAssert(!!_binaryOperation.annotation().commonType, "");
|
solAssert(!!_binaryOperation.annotation().commonType, "");
|
||||||
TypePointer const& commonType = _binaryOperation.annotation().commonType;
|
TypePointer const& commonType = _binaryOperation.annotation().commonType;
|
||||||
Token::Value const c_op = _binaryOperation.getOperator();
|
Token const c_op = _binaryOperation.getOperator();
|
||||||
|
|
||||||
if (c_op == Token::And || c_op == Token::Or) // special case: short-circuiting
|
if (c_op == Token::And || c_op == Token::Or) // special case: short-circuiting
|
||||||
appendAndOrOperatorCode(_binaryOperation);
|
appendAndOrOperatorCode(_binaryOperation);
|
||||||
@ -407,7 +407,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
|||||||
bool cleanupNeeded = cleanupNeededForOp(commonType->category(), c_op);
|
bool cleanupNeeded = cleanupNeededForOp(commonType->category(), c_op);
|
||||||
|
|
||||||
TypePointer leftTargetType = commonType;
|
TypePointer leftTargetType = commonType;
|
||||||
TypePointer rightTargetType = Token::isShiftOp(c_op) ? rightExpression.annotation().type->mobileType() : commonType;
|
TypePointer rightTargetType = TokenTraits::isShiftOp(c_op) ? rightExpression.annotation().type->mobileType() : commonType;
|
||||||
solAssert(rightTargetType, "");
|
solAssert(rightTargetType, "");
|
||||||
|
|
||||||
// for commutative operators, push the literal as late as possible to allow improved optimization
|
// for commutative operators, push the literal as late as possible to allow improved optimization
|
||||||
@ -415,7 +415,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
|||||||
{
|
{
|
||||||
return dynamic_cast<Literal const*>(&_e) || _e.annotation().type->category() == Type::Category::RationalNumber;
|
return dynamic_cast<Literal const*>(&_e) || _e.annotation().type->category() == Type::Category::RationalNumber;
|
||||||
};
|
};
|
||||||
bool swap = m_optimize && Token::isCommutativeOp(c_op) && isLiteral(rightExpression) && !isLiteral(leftExpression);
|
bool swap = m_optimize && TokenTraits::isCommutativeOp(c_op) && isLiteral(rightExpression) && !isLiteral(leftExpression);
|
||||||
if (swap)
|
if (swap)
|
||||||
{
|
{
|
||||||
leftExpression.accept(*this);
|
leftExpression.accept(*this);
|
||||||
@ -430,10 +430,10 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
|||||||
leftExpression.accept(*this);
|
leftExpression.accept(*this);
|
||||||
utils().convertType(*leftExpression.annotation().type, *leftTargetType, cleanupNeeded);
|
utils().convertType(*leftExpression.annotation().type, *leftTargetType, cleanupNeeded);
|
||||||
}
|
}
|
||||||
if (Token::isShiftOp(c_op))
|
if (TokenTraits::isShiftOp(c_op))
|
||||||
// shift only cares about the signedness of both sides
|
// shift only cares about the signedness of both sides
|
||||||
appendShiftOperatorCode(c_op, *leftTargetType, *rightTargetType);
|
appendShiftOperatorCode(c_op, *leftTargetType, *rightTargetType);
|
||||||
else if (Token::isCompareOp(c_op))
|
else if (TokenTraits::isCompareOp(c_op))
|
||||||
appendCompareOperatorCode(c_op, *commonType);
|
appendCompareOperatorCode(c_op, *commonType);
|
||||||
else
|
else
|
||||||
appendOrdinaryBinaryOperatorCode(c_op, *commonType);
|
appendOrdinaryBinaryOperatorCode(c_op, *commonType);
|
||||||
@ -1602,7 +1602,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal)
|
|||||||
|
|
||||||
void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryOperation)
|
void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryOperation)
|
||||||
{
|
{
|
||||||
Token::Value const c_op = _binaryOperation.getOperator();
|
Token const c_op = _binaryOperation.getOperator();
|
||||||
solAssert(c_op == Token::Or || c_op == Token::And, "");
|
solAssert(c_op == Token::Or || c_op == Token::And, "");
|
||||||
|
|
||||||
_binaryOperation.leftExpression().accept(*this);
|
_binaryOperation.leftExpression().accept(*this);
|
||||||
@ -1615,7 +1615,7 @@ void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryO
|
|||||||
m_context << endLabel;
|
m_context << endLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionCompiler::appendCompareOperatorCode(Token::Value _operator, Type const& _type)
|
void ExpressionCompiler::appendCompareOperatorCode(Token _operator, Type const& _type)
|
||||||
{
|
{
|
||||||
solAssert(_type.sizeOnStack() == 1, "Comparison of multi-slot types.");
|
solAssert(_type.sizeOnStack() == 1, "Comparison of multi-slot types.");
|
||||||
if (_operator == Token::Equal || _operator == Token::NotEqual)
|
if (_operator == Token::Equal || _operator == Token::NotEqual)
|
||||||
@ -1665,17 +1665,17 @@ void ExpressionCompiler::appendCompareOperatorCode(Token::Value _operator, Type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionCompiler::appendOrdinaryBinaryOperatorCode(Token::Value _operator, Type const& _type)
|
void ExpressionCompiler::appendOrdinaryBinaryOperatorCode(Token _operator, Type const& _type)
|
||||||
{
|
{
|
||||||
if (Token::isArithmeticOp(_operator))
|
if (TokenTraits::isArithmeticOp(_operator))
|
||||||
appendArithmeticOperatorCode(_operator, _type);
|
appendArithmeticOperatorCode(_operator, _type);
|
||||||
else if (Token::isBitOp(_operator))
|
else if (TokenTraits::isBitOp(_operator))
|
||||||
appendBitOperatorCode(_operator);
|
appendBitOperatorCode(_operator);
|
||||||
else
|
else
|
||||||
solAssert(false, "Unknown binary operator.");
|
solAssert(false, "Unknown binary operator.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Type const& _type)
|
void ExpressionCompiler::appendArithmeticOperatorCode(Token _operator, Type const& _type)
|
||||||
{
|
{
|
||||||
if (_type.category() == Type::Category::FixedPoint)
|
if (_type.category() == Type::Category::FixedPoint)
|
||||||
solUnimplemented("Not yet implemented - FixedPointType.");
|
solUnimplemented("Not yet implemented - FixedPointType.");
|
||||||
@ -1715,7 +1715,7 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionCompiler::appendBitOperatorCode(Token::Value _operator)
|
void ExpressionCompiler::appendBitOperatorCode(Token _operator)
|
||||||
{
|
{
|
||||||
switch (_operator)
|
switch (_operator)
|
||||||
{
|
{
|
||||||
@ -1733,7 +1733,7 @@ void ExpressionCompiler::appendBitOperatorCode(Token::Value _operator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionCompiler::appendShiftOperatorCode(Token::Value _operator, Type const& _valueType, Type const& _shiftAmountType)
|
void ExpressionCompiler::appendShiftOperatorCode(Token _operator, Type const& _valueType, Type const& _shiftAmountType)
|
||||||
{
|
{
|
||||||
// stack: shift_amount value_to_shift
|
// stack: shift_amount value_to_shift
|
||||||
|
|
||||||
@ -2140,9 +2140,9 @@ void ExpressionCompiler::setLValueToStorageItem(Expression const& _expression)
|
|||||||
setLValue<StorageItem>(_expression, *_expression.annotation().type);
|
setLValue<StorageItem>(_expression, *_expression.annotation().type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExpressionCompiler::cleanupNeededForOp(Type::Category _type, Token::Value _op)
|
bool ExpressionCompiler::cleanupNeededForOp(Type::Category _type, Token _op)
|
||||||
{
|
{
|
||||||
if (Token::isCompareOp(_op) || Token::isShiftOp(_op))
|
if (TokenTraits::isCompareOp(_op) || TokenTraits::isShiftOp(_op))
|
||||||
return true;
|
return true;
|
||||||
else if (_type == Type::Category::Integer && (_op == Token::Div || _op == Token::Mod || _op == Token::Exp))
|
else if (_type == Type::Category::Integer && (_op == Token::Div || _op == Token::Mod || _op == Token::Exp))
|
||||||
// We need cleanup for EXP because 0**0 == 1, but 0**0x100 == 0
|
// We need cleanup for EXP because 0**0 == 1, but 0**0x100 == 0
|
||||||
|
@ -86,12 +86,12 @@ private:
|
|||||||
///@{
|
///@{
|
||||||
///@name Append code for various operator types
|
///@name Append code for various operator types
|
||||||
void appendAndOrOperatorCode(BinaryOperation const& _binaryOperation);
|
void appendAndOrOperatorCode(BinaryOperation const& _binaryOperation);
|
||||||
void appendCompareOperatorCode(Token::Value _operator, Type const& _type);
|
void appendCompareOperatorCode(Token _operator, Type const& _type);
|
||||||
void appendOrdinaryBinaryOperatorCode(Token::Value _operator, Type const& _type);
|
void appendOrdinaryBinaryOperatorCode(Token _operator, Type const& _type);
|
||||||
|
|
||||||
void appendArithmeticOperatorCode(Token::Value _operator, Type const& _type);
|
void appendArithmeticOperatorCode(Token _operator, Type const& _type);
|
||||||
void appendBitOperatorCode(Token::Value _operator);
|
void appendBitOperatorCode(Token _operator);
|
||||||
void appendShiftOperatorCode(Token::Value _operator, Type const& _valueType, Type const& _shiftAmountType);
|
void appendShiftOperatorCode(Token _operator, Type const& _valueType, Type const& _shiftAmountType);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// Appends code to call a function of the given type with the given arguments.
|
/// Appends code to call a function of the given type with the given arguments.
|
||||||
@ -119,7 +119,7 @@ private:
|
|||||||
|
|
||||||
/// @returns true if the operator applied to the given type requires a cleanup prior to the
|
/// @returns true if the operator applied to the given type requires a cleanup prior to the
|
||||||
/// operation.
|
/// operation.
|
||||||
static bool cleanupNeededForOp(Type::Category _type, Token::Value _op);
|
static bool cleanupNeededForOp(Type::Category _type, Token _op);
|
||||||
|
|
||||||
/// @returns the CompilerUtils object containing the current context.
|
/// @returns the CompilerUtils object containing the current context.
|
||||||
CompilerUtils utils();
|
CompilerUtils utils();
|
||||||
|
@ -212,7 +212,7 @@ void SMTChecker::endVisit(VariableDeclarationStatement const& _varDecl)
|
|||||||
|
|
||||||
void SMTChecker::endVisit(Assignment const& _assignment)
|
void SMTChecker::endVisit(Assignment const& _assignment)
|
||||||
{
|
{
|
||||||
if (_assignment.assignmentOperator() != Token::Value::Assign)
|
if (_assignment.assignmentOperator() != Token::Assign)
|
||||||
m_errorReporter.warning(
|
m_errorReporter.warning(
|
||||||
_assignment.location(),
|
_assignment.location(),
|
||||||
"Assertion checker does not yet implement compound assignment."
|
"Assertion checker does not yet implement compound assignment."
|
||||||
@ -331,11 +331,11 @@ void SMTChecker::endVisit(UnaryOperation const& _op)
|
|||||||
|
|
||||||
void SMTChecker::endVisit(BinaryOperation const& _op)
|
void SMTChecker::endVisit(BinaryOperation const& _op)
|
||||||
{
|
{
|
||||||
if (Token::isArithmeticOp(_op.getOperator()))
|
if (TokenTraits::isArithmeticOp(_op.getOperator()))
|
||||||
arithmeticOperation(_op);
|
arithmeticOperation(_op);
|
||||||
else if (Token::isCompareOp(_op.getOperator()))
|
else if (TokenTraits::isCompareOp(_op.getOperator()))
|
||||||
compareOperation(_op);
|
compareOperation(_op);
|
||||||
else if (Token::isBooleanOp(_op.getOperator()))
|
else if (TokenTraits::isBooleanOp(_op.getOperator()))
|
||||||
booleanOperation(_op);
|
booleanOperation(_op);
|
||||||
else
|
else
|
||||||
m_errorReporter.warning(
|
m_errorReporter.warning(
|
||||||
@ -530,7 +530,7 @@ void SMTChecker::arithmeticOperation(BinaryOperation const& _op)
|
|||||||
auto const& intType = dynamic_cast<IntegerType const&>(*_op.annotation().commonType);
|
auto const& intType = dynamic_cast<IntegerType const&>(*_op.annotation().commonType);
|
||||||
smt::Expression left(expr(_op.leftExpression()));
|
smt::Expression left(expr(_op.leftExpression()));
|
||||||
smt::Expression right(expr(_op.rightExpression()));
|
smt::Expression right(expr(_op.rightExpression()));
|
||||||
Token::Value op = _op.getOperator();
|
Token op = _op.getOperator();
|
||||||
smt::Expression value(
|
smt::Expression value(
|
||||||
op == Token::Add ? left + right :
|
op == Token::Add ? left + right :
|
||||||
op == Token::Sub ? left - right :
|
op == Token::Sub ? left - right :
|
||||||
@ -564,7 +564,7 @@ void SMTChecker::compareOperation(BinaryOperation const& _op)
|
|||||||
{
|
{
|
||||||
smt::Expression left(expr(_op.leftExpression()));
|
smt::Expression left(expr(_op.leftExpression()));
|
||||||
smt::Expression right(expr(_op.rightExpression()));
|
smt::Expression right(expr(_op.rightExpression()));
|
||||||
Token::Value op = _op.getOperator();
|
Token op = _op.getOperator();
|
||||||
shared_ptr<smt::Expression> value;
|
shared_ptr<smt::Expression> value;
|
||||||
if (isNumber(_op.annotation().commonType->category()))
|
if (isNumber(_op.annotation().commonType->category()))
|
||||||
{
|
{
|
||||||
|
@ -112,17 +112,17 @@ ASTPointer<PragmaDirective> Parser::parsePragmaDirective()
|
|||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::Pragma);
|
expectToken(Token::Pragma);
|
||||||
vector<string> literals;
|
vector<string> literals;
|
||||||
vector<Token::Value> tokens;
|
vector<Token> tokens;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
if (token == Token::Illegal)
|
if (token == Token::Illegal)
|
||||||
parserError("Token incompatible with Solidity parser as part of pragma directive.");
|
parserError("Token incompatible with Solidity parser as part of pragma directive.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string literal = m_scanner->currentLiteral();
|
string literal = m_scanner->currentLiteral();
|
||||||
if (literal.empty() && Token::toString(token))
|
if (literal.empty() && TokenTraits::toString(token))
|
||||||
literal = Token::toString(token);
|
literal = TokenTraits::toString(token);
|
||||||
literals.push_back(literal);
|
literals.push_back(literal);
|
||||||
tokens.push_back(token);
|
tokens.push_back(token);
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
expectToken(Token::LBrace);
|
expectToken(Token::LBrace);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Token::Value currentTokenValue = m_scanner->currentToken();
|
Token currentTokenValue = m_scanner->currentToken();
|
||||||
if (currentTokenValue == Token::RBrace)
|
if (currentTokenValue == Token::RBrace)
|
||||||
break;
|
break;
|
||||||
else if (currentTokenValue == Token::Function || currentTokenValue == Token::Constructor)
|
else if (currentTokenValue == Token::Function || currentTokenValue == Token::Constructor)
|
||||||
@ -254,7 +254,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
else if (
|
else if (
|
||||||
currentTokenValue == Token::Identifier ||
|
currentTokenValue == Token::Identifier ||
|
||||||
currentTokenValue == Token::Mapping ||
|
currentTokenValue == Token::Mapping ||
|
||||||
Token::isElementaryTypeName(currentTokenValue)
|
TokenTraits::isElementaryTypeName(currentTokenValue)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VarDeclParserOptions options;
|
VarDeclParserOptions options;
|
||||||
@ -304,7 +304,7 @@ ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
|
|||||||
Declaration::Visibility Parser::parseVisibilitySpecifier()
|
Declaration::Visibility Parser::parseVisibilitySpecifier()
|
||||||
{
|
{
|
||||||
Declaration::Visibility visibility(Declaration::Visibility::Default);
|
Declaration::Visibility visibility(Declaration::Visibility::Default);
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
switch (token)
|
switch (token)
|
||||||
{
|
{
|
||||||
case Token::Public:
|
case Token::Public:
|
||||||
@ -329,7 +329,7 @@ Declaration::Visibility Parser::parseVisibilitySpecifier()
|
|||||||
StateMutability Parser::parseStateMutability()
|
StateMutability Parser::parseStateMutability()
|
||||||
{
|
{
|
||||||
StateMutability stateMutability(StateMutability::NonPayable);
|
StateMutability stateMutability(StateMutability::NonPayable);
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
switch(token)
|
switch(token)
|
||||||
{
|
{
|
||||||
case Token::Payable:
|
case Token::Payable:
|
||||||
@ -386,7 +386,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN
|
|||||||
result.parameters = parseParameterList(options);
|
result.parameters = parseParameterList(options);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
if (_allowModifiers && token == Token::Identifier)
|
if (_allowModifiers && token == Token::Identifier)
|
||||||
{
|
{
|
||||||
// If the name is empty (and this is not a constructor),
|
// If the name is empty (and this is not a constructor),
|
||||||
@ -401,7 +401,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN
|
|||||||
else
|
else
|
||||||
result.modifiers.push_back(parseModifierInvocation());
|
result.modifiers.push_back(parseModifierInvocation());
|
||||||
}
|
}
|
||||||
else if (Token::isVisibilitySpecifier(token))
|
else if (TokenTraits::isVisibilitySpecifier(token))
|
||||||
{
|
{
|
||||||
if (result.visibility != Declaration::Visibility::Default)
|
if (result.visibility != Declaration::Visibility::Default)
|
||||||
{
|
{
|
||||||
@ -423,7 +423,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN
|
|||||||
else
|
else
|
||||||
result.visibility = parseVisibilitySpecifier();
|
result.visibility = parseVisibilitySpecifier();
|
||||||
}
|
}
|
||||||
else if (Token::isStateMutabilitySpecifier(token))
|
else if (TokenTraits::isStateMutabilitySpecifier(token))
|
||||||
{
|
{
|
||||||
if (result.stateMutability != StateMutability::NonPayable)
|
if (result.stateMutability != StateMutability::NonPayable)
|
||||||
{
|
{
|
||||||
@ -587,8 +587,8 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
if (_options.isStateVariable && Token::isVariableVisibilitySpecifier(token))
|
if (_options.isStateVariable && TokenTraits::isVariableVisibilitySpecifier(token))
|
||||||
{
|
{
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
if (visibility != Declaration::Visibility::Default)
|
if (visibility != Declaration::Visibility::Default)
|
||||||
@ -609,7 +609,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
isIndexed = true;
|
isIndexed = true;
|
||||||
else if (token == Token::Constant)
|
else if (token == Token::Constant)
|
||||||
isDeclaredConst = true;
|
isDeclaredConst = true;
|
||||||
else if (_options.allowLocationSpecifier && Token::isLocationSpecifier(token))
|
else if (_options.allowLocationSpecifier && TokenTraits::isLocationSpecifier(token))
|
||||||
{
|
{
|
||||||
if (location != VariableDeclaration::Location::Unspecified)
|
if (location != VariableDeclaration::Location::Unspecified)
|
||||||
parserError(string("Location already specified."));
|
parserError(string("Location already specified."));
|
||||||
@ -806,8 +806,8 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
|||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ASTPointer<TypeName> type;
|
ASTPointer<TypeName> type;
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
if (Token::isElementaryTypeName(token))
|
if (TokenTraits::isElementaryTypeName(token))
|
||||||
{
|
{
|
||||||
unsigned firstSize;
|
unsigned firstSize;
|
||||||
unsigned secondSize;
|
unsigned secondSize;
|
||||||
@ -817,7 +817,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
|||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
auto stateMutability = boost::make_optional(elemTypeName.token() == Token::Address, StateMutability::NonPayable);
|
auto stateMutability = boost::make_optional(elemTypeName.token() == Token::Address, StateMutability::NonPayable);
|
||||||
if (Token::isStateMutabilitySpecifier(m_scanner->currentToken(), false))
|
if (TokenTraits::isStateMutabilitySpecifier(m_scanner->currentToken(), false))
|
||||||
{
|
{
|
||||||
if (elemTypeName.token() == Token::Address)
|
if (elemTypeName.token() == Token::Address)
|
||||||
{
|
{
|
||||||
@ -874,8 +874,8 @@ ASTPointer<Mapping> Parser::parseMapping()
|
|||||||
expectToken(Token::Mapping);
|
expectToken(Token::Mapping);
|
||||||
expectToken(Token::LParen);
|
expectToken(Token::LParen);
|
||||||
ASTPointer<ElementaryTypeName> keyType;
|
ASTPointer<ElementaryTypeName> keyType;
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
if (!Token::isElementaryTypeName(token))
|
if (!TokenTraits::isElementaryTypeName(token))
|
||||||
fatalParserError(string("Expected elementary type name for mapping key type"));
|
fatalParserError(string("Expected elementary type name for mapping key type"));
|
||||||
unsigned firstSize;
|
unsigned firstSize;
|
||||||
unsigned secondSize;
|
unsigned secondSize;
|
||||||
@ -1252,7 +1252,7 @@ pair<Parser::LookAheadInfo, Parser::IndexAccessedPath> Parser::tryParseIndexAcce
|
|||||||
// VariableDeclarationStatement out of it.
|
// VariableDeclarationStatement out of it.
|
||||||
IndexAccessedPath iap = parseIndexAccessedPath();
|
IndexAccessedPath iap = parseIndexAccessedPath();
|
||||||
|
|
||||||
if (m_scanner->currentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->currentToken()))
|
if (m_scanner->currentToken() == Token::Identifier || TokenTraits::isLocationSpecifier(m_scanner->currentToken()))
|
||||||
return make_pair(LookAheadInfo::VariableDeclaration, move(iap));
|
return make_pair(LookAheadInfo::VariableDeclaration, move(iap));
|
||||||
else
|
else
|
||||||
return make_pair(LookAheadInfo::Expression, move(iap));
|
return make_pair(LookAheadInfo::Expression, move(iap));
|
||||||
@ -1342,16 +1342,16 @@ ASTPointer<Expression> Parser::parseExpression(
|
|||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTPointer<Expression> expression = parseBinaryExpression(4, _partiallyParsedExpression);
|
ASTPointer<Expression> expression = parseBinaryExpression(4, _partiallyParsedExpression);
|
||||||
if (Token::isAssignmentOp(m_scanner->currentToken()))
|
if (TokenTraits::isAssignmentOp(m_scanner->currentToken()))
|
||||||
{
|
{
|
||||||
Token::Value assignmentOperator = m_scanner->currentToken();
|
Token assignmentOperator = m_scanner->currentToken();
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
ASTPointer<Expression> rightHandSide = parseExpression();
|
ASTPointer<Expression> rightHandSide = parseExpression();
|
||||||
ASTNodeFactory nodeFactory(*this, expression);
|
ASTNodeFactory nodeFactory(*this, expression);
|
||||||
nodeFactory.setEndPositionFromNode(rightHandSide);
|
nodeFactory.setEndPositionFromNode(rightHandSide);
|
||||||
return nodeFactory.createNode<Assignment>(expression, assignmentOperator, rightHandSide);
|
return nodeFactory.createNode<Assignment>(expression, assignmentOperator, rightHandSide);
|
||||||
}
|
}
|
||||||
else if (m_scanner->currentToken() == Token::Value::Conditional)
|
else if (m_scanner->currentToken() == Token::Conditional)
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
ASTPointer<Expression> trueExpression = parseExpression();
|
ASTPointer<Expression> trueExpression = parseExpression();
|
||||||
@ -1373,11 +1373,11 @@ ASTPointer<Expression> Parser::parseBinaryExpression(
|
|||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTPointer<Expression> expression = parseUnaryExpression(_partiallyParsedExpression);
|
ASTPointer<Expression> expression = parseUnaryExpression(_partiallyParsedExpression);
|
||||||
ASTNodeFactory nodeFactory(*this, expression);
|
ASTNodeFactory nodeFactory(*this, expression);
|
||||||
int precedence = Token::precedence(m_scanner->currentToken());
|
int precedence = TokenTraits::precedence(m_scanner->currentToken());
|
||||||
for (; precedence >= _minPrecedence; --precedence)
|
for (; precedence >= _minPrecedence; --precedence)
|
||||||
while (Token::precedence(m_scanner->currentToken()) == precedence)
|
while (TokenTraits::precedence(m_scanner->currentToken()) == precedence)
|
||||||
{
|
{
|
||||||
Token::Value op = m_scanner->currentToken();
|
Token op = m_scanner->currentToken();
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
ASTPointer<Expression> right = parseBinaryExpression(precedence + 1);
|
ASTPointer<Expression> right = parseBinaryExpression(precedence + 1);
|
||||||
nodeFactory.setEndPositionFromNode(right);
|
nodeFactory.setEndPositionFromNode(right);
|
||||||
@ -1393,8 +1393,8 @@ ASTPointer<Expression> Parser::parseUnaryExpression(
|
|||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory = _partiallyParsedExpression ?
|
ASTNodeFactory nodeFactory = _partiallyParsedExpression ?
|
||||||
ASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this);
|
ASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this);
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
if (!_partiallyParsedExpression && (Token::isUnaryOp(token) || Token::isCountOp(token)))
|
if (!_partiallyParsedExpression && (TokenTraits::isUnaryOp(token) || TokenTraits::isCountOp(token)))
|
||||||
{
|
{
|
||||||
// prefix expression
|
// prefix expression
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -1407,7 +1407,7 @@ ASTPointer<Expression> Parser::parseUnaryExpression(
|
|||||||
// potential postfix expression
|
// potential postfix expression
|
||||||
ASTPointer<Expression> subExpression = parseLeftHandSideExpression(_partiallyParsedExpression);
|
ASTPointer<Expression> subExpression = parseLeftHandSideExpression(_partiallyParsedExpression);
|
||||||
token = m_scanner->currentToken();
|
token = m_scanner->currentToken();
|
||||||
if (!Token::isCountOp(token))
|
if (!TokenTraits::isCountOp(token))
|
||||||
return subExpression;
|
return subExpression;
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -1482,7 +1482,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
ASTPointer<Expression> expression;
|
ASTPointer<Expression> expression;
|
||||||
|
|
||||||
switch (token)
|
switch (token)
|
||||||
@ -1493,7 +1493,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
|
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
|
||||||
break;
|
break;
|
||||||
case Token::Number:
|
case Token::Number:
|
||||||
if (Token::isEtherSubdenomination(m_scanner->peekNextToken()))
|
if (TokenTraits::isEtherSubdenomination(m_scanner->peekNextToken()))
|
||||||
{
|
{
|
||||||
ASTPointer<ASTString> literal = getLiteralAndAdvance();
|
ASTPointer<ASTString> literal = getLiteralAndAdvance();
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
@ -1501,7 +1501,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
expression = nodeFactory.createNode<Literal>(token, literal, subdenomination);
|
expression = nodeFactory.createNode<Literal>(token, literal, subdenomination);
|
||||||
}
|
}
|
||||||
else if (Token::isTimeSubdenomination(m_scanner->peekNextToken()))
|
else if (TokenTraits::isTimeSubdenomination(m_scanner->peekNextToken()))
|
||||||
{
|
{
|
||||||
ASTPointer<ASTString> literal = getLiteralAndAdvance();
|
ASTPointer<ASTString> literal = getLiteralAndAdvance();
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
@ -1531,7 +1531,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
// (x,) is one-dimensional tuple, elements in arrays cannot be left out, only in tuples.
|
// (x,) is one-dimensional tuple, elements in arrays cannot be left out, only in tuples.
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
vector<ASTPointer<Expression>> components;
|
vector<ASTPointer<Expression>> components;
|
||||||
Token::Value oppositeToken = (token == Token::LParen ? Token::RParen : Token::RBrack);
|
Token oppositeToken = (token == Token::LParen ? Token::RParen : Token::RBrack);
|
||||||
bool isArray = (token == Token::LBrack);
|
bool isArray = (token == Token::LBrack);
|
||||||
|
|
||||||
if (m_scanner->currentToken() != oppositeToken)
|
if (m_scanner->currentToken() != oppositeToken)
|
||||||
@ -1558,7 +1558,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
fatalParserError("Expected even number of hex-nibbles within double-quotes.");
|
fatalParserError("Expected even number of hex-nibbles within double-quotes.");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (Token::isElementaryTypeName(token))
|
if (TokenTraits::isElementaryTypeName(token))
|
||||||
{
|
{
|
||||||
//used for casts
|
//used for casts
|
||||||
unsigned firstSize;
|
unsigned firstSize;
|
||||||
@ -1595,7 +1595,7 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
|
|||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
|
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
|
||||||
Token::Value token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
if (token == Token::LBrace)
|
if (token == Token::LBrace)
|
||||||
{
|
{
|
||||||
// call({arg1 : 1, arg2 : 2 })
|
// call({arg1 : 1, arg2 : 2 })
|
||||||
@ -1638,21 +1638,21 @@ Parser::LookAheadInfo Parser::peekStatementType() const
|
|||||||
// or a mutability specifier, we also have a variable declaration.
|
// or a mutability specifier, we also have a variable declaration.
|
||||||
// If we get an identifier followed by a "[" or ".", it can be both ("lib.type[9] a;" or "variable.el[9] = 7;").
|
// If we get an identifier followed by a "[" or ".", it can be both ("lib.type[9] a;" or "variable.el[9] = 7;").
|
||||||
// In all other cases, we have an expression statement.
|
// In all other cases, we have an expression statement.
|
||||||
Token::Value token(m_scanner->currentToken());
|
Token token(m_scanner->currentToken());
|
||||||
bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier);
|
bool mightBeTypeName = (TokenTraits::isElementaryTypeName(token) || token == Token::Identifier);
|
||||||
|
|
||||||
if (token == Token::Mapping || token == Token::Function || token == Token::Var)
|
if (token == Token::Mapping || token == Token::Function || token == Token::Var)
|
||||||
return LookAheadInfo::VariableDeclaration;
|
return LookAheadInfo::VariableDeclaration;
|
||||||
if (mightBeTypeName)
|
if (mightBeTypeName)
|
||||||
{
|
{
|
||||||
Token::Value next = m_scanner->peekNextToken();
|
Token next = m_scanner->peekNextToken();
|
||||||
// So far we only allow ``address payable`` in variable declaration statements and in no other
|
// So far we only allow ``address payable`` in variable declaration statements and in no other
|
||||||
// kind of statement. This means, for example, that we do not allow type expressions of the form
|
// kind of statement. This means, for example, that we do not allow type expressions of the form
|
||||||
// ``address payable;``.
|
// ``address payable;``.
|
||||||
// If we want to change this in the future, we need to consider another scanner token here.
|
// If we want to change this in the future, we need to consider another scanner token here.
|
||||||
if (Token::isElementaryTypeName(token) && Token::isStateMutabilitySpecifier(next, false))
|
if (TokenTraits::isElementaryTypeName(token) && TokenTraits::isStateMutabilitySpecifier(next, false))
|
||||||
return LookAheadInfo::VariableDeclaration;
|
return LookAheadInfo::VariableDeclaration;
|
||||||
if (next == Token::Identifier || Token::isLocationSpecifier(next))
|
if (next == Token::Identifier || TokenTraits::isLocationSpecifier(next))
|
||||||
return LookAheadInfo::VariableDeclaration;
|
return LookAheadInfo::VariableDeclaration;
|
||||||
if (next == Token::LBrack || next == Token::Period)
|
if (next == Token::LBrack || next == Token::Period)
|
||||||
return LookAheadInfo::IndexAccessStructure;
|
return LookAheadInfo::IndexAccessStructure;
|
||||||
|
@ -43,12 +43,12 @@ int ParserBase::endPosition() const
|
|||||||
return m_scanner->currentLocation().end;
|
return m_scanner->currentLocation().end;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value ParserBase::currentToken() const
|
Token ParserBase::currentToken() const
|
||||||
{
|
{
|
||||||
return m_scanner->currentToken();
|
return m_scanner->currentToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value ParserBase::peekNextToken() const
|
Token ParserBase::peekNextToken() const
|
||||||
{
|
{
|
||||||
return m_scanner->peekNextToken();
|
return m_scanner->peekNextToken();
|
||||||
}
|
}
|
||||||
@ -58,31 +58,31 @@ std::string ParserBase::currentLiteral() const
|
|||||||
return m_scanner->currentLiteral();
|
return m_scanner->currentLiteral();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value ParserBase::advance()
|
Token ParserBase::advance()
|
||||||
{
|
{
|
||||||
return m_scanner->next();
|
return m_scanner->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParserBase::expectToken(Token::Value _value, bool _advance)
|
void ParserBase::expectToken(Token _value, bool _advance)
|
||||||
{
|
{
|
||||||
Token::Value tok = m_scanner->currentToken();
|
Token tok = m_scanner->currentToken();
|
||||||
if (tok != _value)
|
if (tok != _value)
|
||||||
{
|
{
|
||||||
auto tokenName = [this](Token::Value _token)
|
auto tokenName = [this](Token _token)
|
||||||
{
|
{
|
||||||
if (_token == Token::Identifier)
|
if (_token == Token::Identifier)
|
||||||
return string("identifier");
|
return string("identifier");
|
||||||
else if (_token == Token::EOS)
|
else if (_token == Token::EOS)
|
||||||
return string("end of source");
|
return string("end of source");
|
||||||
else if (Token::isReservedKeyword(_token))
|
else if (TokenTraits::isReservedKeyword(_token))
|
||||||
return string("reserved keyword '") + Token::friendlyName(_token) + "'";
|
return string("reserved keyword '") + TokenTraits::friendlyName(_token) + "'";
|
||||||
else if (Token::isElementaryTypeName(_token)) //for the sake of accuracy in reporting
|
else if (TokenTraits::isElementaryTypeName(_token)) //for the sake of accuracy in reporting
|
||||||
{
|
{
|
||||||
ElementaryTypeNameToken elemTypeName = m_scanner->currentElementaryTypeNameToken();
|
ElementaryTypeNameToken elemTypeName = m_scanner->currentElementaryTypeNameToken();
|
||||||
return string("'") + elemTypeName.toString() + "'";
|
return string("'") + elemTypeName.toString() + "'";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return string("'") + Token::friendlyName(_token) + "'";
|
return string("'") + TokenTraits::friendlyName(_token) + "'";
|
||||||
};
|
};
|
||||||
|
|
||||||
fatalParserError(string("Expected ") + tokenName(_value) + string(" but got ") + tokenName(tok));
|
fatalParserError(string("Expected ") + tokenName(_value) + string(" but got ") + tokenName(tok));
|
||||||
|
@ -63,11 +63,11 @@ protected:
|
|||||||
///@{
|
///@{
|
||||||
///@name Helper functions
|
///@name Helper functions
|
||||||
/// If current token value is not _value, throw exception otherwise advance token.
|
/// If current token value is not _value, throw exception otherwise advance token.
|
||||||
void expectToken(Token::Value _value, bool _advance = true);
|
void expectToken(Token _value, bool _advance = true);
|
||||||
Token::Value currentToken() const;
|
Token currentToken() const;
|
||||||
Token::Value peekNextToken() const;
|
Token peekNextToken() const;
|
||||||
std::string currentLiteral() const;
|
std::string currentLiteral() const;
|
||||||
Token::Value advance();
|
Token advance();
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
/// Increases the recursion depth and throws an exception if it is too deep.
|
/// Increases the recursion depth and throws an exception if it is too deep.
|
||||||
|
@ -214,9 +214,9 @@ void Scanner::addUnicodeAsUTF8(unsigned codepoint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that tokens can be stored in a byte.
|
// Ensure that tokens can be stored in a byte.
|
||||||
BOOST_STATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
|
BOOST_STATIC_ASSERT(TokenTraits::count() <= 0x100);
|
||||||
|
|
||||||
Token::Value Scanner::next()
|
Token Scanner::next()
|
||||||
{
|
{
|
||||||
m_currentToken = m_nextToken;
|
m_currentToken = m_nextToken;
|
||||||
m_skippedComment = m_nextSkippedComment;
|
m_skippedComment = m_nextSkippedComment;
|
||||||
@ -225,7 +225,7 @@ Token::Value Scanner::next()
|
|||||||
return m_currentToken.token;
|
return m_currentToken.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::selectToken(char _next, Token::Value _then, Token::Value _else)
|
Token Scanner::selectToken(char _next, Token _then, Token _else)
|
||||||
{
|
{
|
||||||
advance();
|
advance();
|
||||||
if (m_char == _next)
|
if (m_char == _next)
|
||||||
@ -249,7 +249,7 @@ void Scanner::skipWhitespaceExceptUnicodeLinebreak()
|
|||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::skipSingleLineComment()
|
Token Scanner::skipSingleLineComment()
|
||||||
{
|
{
|
||||||
// Line terminator is not part of the comment. If it is a
|
// Line terminator is not part of the comment. If it is a
|
||||||
// non-ascii line terminator, it will result in a parser error.
|
// non-ascii line terminator, it will result in a parser error.
|
||||||
@ -259,7 +259,7 @@ Token::Value Scanner::skipSingleLineComment()
|
|||||||
return Token::Whitespace;
|
return Token::Whitespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::scanSingleLineDocComment()
|
Token Scanner::scanSingleLineDocComment()
|
||||||
{
|
{
|
||||||
LiteralScope literal(this, LITERAL_TYPE_COMMENT);
|
LiteralScope literal(this, LITERAL_TYPE_COMMENT);
|
||||||
advance(); //consume the last '/' at ///
|
advance(); //consume the last '/' at ///
|
||||||
@ -295,7 +295,7 @@ Token::Value Scanner::scanSingleLineDocComment()
|
|||||||
return Token::CommentLiteral;
|
return Token::CommentLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::skipMultiLineComment()
|
Token Scanner::skipMultiLineComment()
|
||||||
{
|
{
|
||||||
advance();
|
advance();
|
||||||
while (!isSourcePastEndOfInput())
|
while (!isSourcePastEndOfInput())
|
||||||
@ -316,7 +316,7 @@ Token::Value Scanner::skipMultiLineComment()
|
|||||||
return Token::Illegal;
|
return Token::Illegal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::scanMultiLineDocComment()
|
Token Scanner::scanMultiLineDocComment()
|
||||||
{
|
{
|
||||||
LiteralScope literal(this, LITERAL_TYPE_COMMENT);
|
LiteralScope literal(this, LITERAL_TYPE_COMMENT);
|
||||||
bool endFound = false;
|
bool endFound = false;
|
||||||
@ -369,7 +369,7 @@ Token::Value Scanner::scanMultiLineDocComment()
|
|||||||
return Token::CommentLiteral;
|
return Token::CommentLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::scanSlash()
|
Token Scanner::scanSlash()
|
||||||
{
|
{
|
||||||
int firstSlashPosition = sourcePos();
|
int firstSlashPosition = sourcePos();
|
||||||
advance();
|
advance();
|
||||||
@ -380,7 +380,7 @@ Token::Value Scanner::scanSlash()
|
|||||||
else if (m_char == '/')
|
else if (m_char == '/')
|
||||||
{
|
{
|
||||||
// doxygen style /// comment
|
// doxygen style /// comment
|
||||||
Token::Value comment;
|
Token comment;
|
||||||
m_nextSkippedComment.location.start = firstSlashPosition;
|
m_nextSkippedComment.location.start = firstSlashPosition;
|
||||||
comment = scanSingleLineDocComment();
|
comment = scanSingleLineDocComment();
|
||||||
m_nextSkippedComment.location.end = sourcePos();
|
m_nextSkippedComment.location.end = sourcePos();
|
||||||
@ -406,7 +406,7 @@ Token::Value Scanner::scanSlash()
|
|||||||
return Token::Whitespace;
|
return Token::Whitespace;
|
||||||
}
|
}
|
||||||
// we actually have a multiline documentation comment
|
// we actually have a multiline documentation comment
|
||||||
Token::Value comment;
|
Token comment;
|
||||||
m_nextSkippedComment.location.start = firstSlashPosition;
|
m_nextSkippedComment.location.start = firstSlashPosition;
|
||||||
comment = scanMultiLineDocComment();
|
comment = scanMultiLineDocComment();
|
||||||
m_nextSkippedComment.location.end = sourcePos();
|
m_nextSkippedComment.location.end = sourcePos();
|
||||||
@ -432,7 +432,7 @@ void Scanner::scanToken()
|
|||||||
m_nextSkippedComment.literal.clear();
|
m_nextSkippedComment.literal.clear();
|
||||||
m_nextSkippedComment.extendedTokenInfo = make_tuple(0, 0);
|
m_nextSkippedComment.extendedTokenInfo = make_tuple(0, 0);
|
||||||
|
|
||||||
Token::Value token;
|
Token token;
|
||||||
// M and N are for the purposes of grabbing different type sizes
|
// M and N are for the purposes of grabbing different type sizes
|
||||||
unsigned m;
|
unsigned m;
|
||||||
unsigned n;
|
unsigned n;
|
||||||
@ -703,7 +703,7 @@ bool Scanner::isUnicodeLinebreak()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::scanString()
|
Token Scanner::scanString()
|
||||||
{
|
{
|
||||||
char const quote = m_char;
|
char const quote = m_char;
|
||||||
advance(); // consume quote
|
advance(); // consume quote
|
||||||
@ -727,7 +727,7 @@ Token::Value Scanner::scanString()
|
|||||||
return Token::StringLiteral;
|
return Token::StringLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::scanHexString()
|
Token Scanner::scanHexString()
|
||||||
{
|
{
|
||||||
char const quote = m_char;
|
char const quote = m_char;
|
||||||
advance(); // consume quote
|
advance(); // consume quote
|
||||||
@ -760,7 +760,7 @@ void Scanner::scanDecimalDigits()
|
|||||||
// Defer further validation of underscore to SyntaxChecker.
|
// Defer further validation of underscore to SyntaxChecker.
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Value Scanner::scanNumber(char _charSeen)
|
Token Scanner::scanNumber(char _charSeen)
|
||||||
{
|
{
|
||||||
enum { DECIMAL, HEX, BINARY } kind = DECIMAL;
|
enum { DECIMAL, HEX, BINARY } kind = DECIMAL;
|
||||||
LiteralScope literal(this, LITERAL_TYPE_NUMBER);
|
LiteralScope literal(this, LITERAL_TYPE_NUMBER);
|
||||||
@ -854,7 +854,7 @@ Token::Value Scanner::scanNumber(char _charSeen)
|
|||||||
return Token::Number;
|
return Token::Number;
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple<Token::Value, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
|
tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
|
||||||
{
|
{
|
||||||
solAssert(isIdentifierStart(m_char), "");
|
solAssert(isIdentifierStart(m_char), "");
|
||||||
LiteralScope literal(this, LITERAL_TYPE_STRING);
|
LiteralScope literal(this, LITERAL_TYPE_STRING);
|
||||||
@ -863,7 +863,7 @@ tuple<Token::Value, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
|
|||||||
while (isIdentifierPart(m_char)) //get full literal
|
while (isIdentifierPart(m_char)) //get full literal
|
||||||
addLiteralCharAndAdvance();
|
addLiteralCharAndAdvance();
|
||||||
literal.complete();
|
literal.complete();
|
||||||
return Token::fromIdentifierOrKeyword(m_nextToken.literal);
|
return TokenTraits::fromIdentifierOrKeyword(m_nextToken.literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
char CharStream::advanceAndGet(size_t _chars)
|
char CharStream::advanceAndGet(size_t _chars)
|
||||||
|
@ -112,13 +112,13 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
/// @returns the next token and advances input
|
/// @returns the next token and advances input
|
||||||
Token::Value next();
|
Token next();
|
||||||
|
|
||||||
///@{
|
///@{
|
||||||
///@name Information about the current token
|
///@name Information about the current token
|
||||||
|
|
||||||
/// @returns the current token
|
/// @returns the current token
|
||||||
Token::Value currentToken() const
|
Token currentToken() const
|
||||||
{
|
{
|
||||||
return m_currentToken.token;
|
return m_currentToken.token;
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ public:
|
|||||||
///@name Information about the next token
|
///@name Information about the next token
|
||||||
|
|
||||||
/// @returns the next token without advancing input.
|
/// @returns the next token without advancing input.
|
||||||
Token::Value peekNextToken() const { return m_nextToken.token; }
|
Token peekNextToken() const { return m_nextToken.token; }
|
||||||
SourceLocation peekLocation() const { return m_nextToken.location; }
|
SourceLocation peekLocation() const { return m_nextToken.location; }
|
||||||
std::string const& peekLiteral() const { return m_nextToken.literal; }
|
std::string const& peekLiteral() const { return m_nextToken.literal; }
|
||||||
///@}
|
///@}
|
||||||
@ -168,7 +168,7 @@ private:
|
|||||||
/// Used for the current and look-ahead token and comments
|
/// Used for the current and look-ahead token and comments
|
||||||
struct TokenDesc
|
struct TokenDesc
|
||||||
{
|
{
|
||||||
Token::Value token;
|
Token token;
|
||||||
SourceLocation location;
|
SourceLocation location;
|
||||||
std::string literal;
|
std::string literal;
|
||||||
std::tuple<unsigned, unsigned> extendedTokenInfo;
|
std::tuple<unsigned, unsigned> extendedTokenInfo;
|
||||||
@ -185,9 +185,9 @@ private:
|
|||||||
bool advance() { m_char = m_source.advanceAndGet(); return !m_source.isPastEndOfInput(); }
|
bool advance() { m_char = m_source.advanceAndGet(); return !m_source.isPastEndOfInput(); }
|
||||||
void rollback(int _amount) { m_char = m_source.rollback(_amount); }
|
void rollback(int _amount) { m_char = m_source.rollback(_amount); }
|
||||||
|
|
||||||
inline Token::Value selectToken(Token::Value _tok) { advance(); return _tok; }
|
inline Token selectToken(Token _tok) { advance(); return _tok; }
|
||||||
/// If the next character is _next, advance and return _then, otherwise return _else.
|
/// If the next character is _next, advance and return _then, otherwise return _else.
|
||||||
inline Token::Value selectToken(char _next, Token::Value _then, Token::Value _else);
|
inline Token selectToken(char _next, Token _then, Token _else);
|
||||||
|
|
||||||
bool scanHexByte(char& o_scannedByte);
|
bool scanHexByte(char& o_scannedByte);
|
||||||
bool scanUnicode(unsigned& o_codepoint);
|
bool scanUnicode(unsigned& o_codepoint);
|
||||||
@ -199,19 +199,19 @@ private:
|
|||||||
bool skipWhitespace();
|
bool skipWhitespace();
|
||||||
/// Skips all whitespace that are neither '\r' nor '\n'.
|
/// Skips all whitespace that are neither '\r' nor '\n'.
|
||||||
void skipWhitespaceExceptUnicodeLinebreak();
|
void skipWhitespaceExceptUnicodeLinebreak();
|
||||||
Token::Value skipSingleLineComment();
|
Token skipSingleLineComment();
|
||||||
Token::Value skipMultiLineComment();
|
Token skipMultiLineComment();
|
||||||
|
|
||||||
void scanDecimalDigits();
|
void scanDecimalDigits();
|
||||||
Token::Value scanNumber(char _charSeen = 0);
|
Token scanNumber(char _charSeen = 0);
|
||||||
std::tuple<Token::Value, unsigned, unsigned> scanIdentifierOrKeyword();
|
std::tuple<Token, unsigned, unsigned> scanIdentifierOrKeyword();
|
||||||
|
|
||||||
Token::Value scanString();
|
Token scanString();
|
||||||
Token::Value scanHexString();
|
Token scanHexString();
|
||||||
Token::Value scanSingleLineDocComment();
|
Token scanSingleLineDocComment();
|
||||||
Token::Value scanMultiLineDocComment();
|
Token scanMultiLineDocComment();
|
||||||
/// Scans a slash '/' and depending on the characters returns the appropriate token
|
/// Scans a slash '/' and depending on the characters returns the appropriate token
|
||||||
Token::Value scanSlash();
|
Token scanSlash();
|
||||||
|
|
||||||
/// Scans an escape-sequence which is part of a string and adds the
|
/// Scans an escape-sequence which is part of a string and adds the
|
||||||
/// decoded character to the current literal. Returns true if a pattern
|
/// decoded character to the current literal. Returns true if a pattern
|
||||||
|
@ -51,9 +51,9 @@ namespace dev
|
|||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
|
||||||
void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second)
|
void ElementaryTypeNameToken::assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second)
|
||||||
{
|
{
|
||||||
solAssert(Token::isElementaryTypeName(_baseType), "Expected elementary type name: " + string(Token::toString(_baseType)));
|
solAssert(TokenTraits::isElementaryTypeName(_baseType), "Expected elementary type name: " + string(TokenTraits::toString(_baseType)));
|
||||||
if (_baseType == Token::BytesM)
|
if (_baseType == Token::BytesM)
|
||||||
{
|
{
|
||||||
solAssert(_second == 0, "There should not be a second size argument to type bytesM.");
|
solAssert(_second == 0, "There should not be a second size argument to type bytesM.");
|
||||||
@ -61,17 +61,17 @@ void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned con
|
|||||||
}
|
}
|
||||||
else if (_baseType == Token::UIntM || _baseType == Token::IntM)
|
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(_second == 0, "There should not be a second size argument to type " + string(TokenTraits::toString(_baseType)) + ".");
|
||||||
solAssert(
|
solAssert(
|
||||||
_first <= 256 && _first % 8 == 0,
|
_first <= 256 && _first % 8 == 0,
|
||||||
"No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "."
|
"No elementary type " + string(TokenTraits::toString(_baseType)) + to_string(_first) + "."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN)
|
else if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN)
|
||||||
{
|
{
|
||||||
solAssert(
|
solAssert(
|
||||||
_first >= 8 && _first <= 256 && _first % 8 == 0 && _second <= 80,
|
_first >= 8 && _first <= 256 && _first % 8 == 0 && _second <= 80,
|
||||||
"No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "x" + to_string(_second) + "."
|
"No elementary type " + string(TokenTraits::toString(_baseType)) + to_string(_first) + "x" + to_string(_second) + "."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
m_token = _baseType;
|
m_token = _baseType;
|
||||||
@ -79,38 +79,54 @@ void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned con
|
|||||||
m_secondNumber = _second;
|
m_secondNumber = _second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace TokenTraits
|
||||||
|
{
|
||||||
|
|
||||||
|
char const* toString(Token tok)
|
||||||
|
{
|
||||||
|
switch (tok)
|
||||||
|
{
|
||||||
|
#define T(name, string, precedence) case Token::name: return string;
|
||||||
|
TOKEN_LIST(T, T)
|
||||||
|
#undef T
|
||||||
|
default: // Token::NUM_TOKENS:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* name(Token tok)
|
||||||
|
{
|
||||||
#define T(name, string, precedence) #name,
|
#define T(name, string, precedence) #name,
|
||||||
char const* const Token::m_name[NUM_TOKENS] =
|
static char const* const names[TokenTraits::count()] = { TOKEN_LIST(T, T) };
|
||||||
{
|
|
||||||
TOKEN_LIST(T, T)
|
|
||||||
};
|
|
||||||
#undef T
|
#undef T
|
||||||
|
|
||||||
|
solAssert(static_cast<size_t>(tok) < TokenTraits::count(), "");
|
||||||
|
return names[static_cast<size_t>(tok)];
|
||||||
|
}
|
||||||
|
|
||||||
#define T(name, string, precedence) string,
|
std::string friendlyName(Token tok)
|
||||||
char const* const Token::m_string[NUM_TOKENS] =
|
|
||||||
{
|
{
|
||||||
TOKEN_LIST(T, T)
|
char const* ret = toString(tok);
|
||||||
};
|
if (ret)
|
||||||
#undef T
|
return std::string(ret);
|
||||||
|
|
||||||
|
ret = name(tok);
|
||||||
|
solAssert(ret != nullptr, "");
|
||||||
|
return std::string(ret);
|
||||||
|
}
|
||||||
|
|
||||||
#define T(name, string, precedence) precedence,
|
#define T(name, string, precedence) precedence,
|
||||||
int8_t const Token::m_precedence[NUM_TOKENS] =
|
int precedence(Token tok)
|
||||||
{
|
{
|
||||||
TOKEN_LIST(T, T)
|
int8_t const static precs[TokenTraits::count()] =
|
||||||
};
|
{
|
||||||
|
TOKEN_LIST(T, T)
|
||||||
|
};
|
||||||
|
return precs[static_cast<size_t>(tok)];
|
||||||
|
}
|
||||||
#undef T
|
#undef T
|
||||||
|
|
||||||
|
int parseSize(string::const_iterator _begin, string::const_iterator _end)
|
||||||
#define KT(a, b, c) 'T',
|
|
||||||
#define KK(a, b, c) 'K',
|
|
||||||
char const Token::m_tokenType[] =
|
|
||||||
{
|
|
||||||
TOKEN_LIST(KT, KK)
|
|
||||||
};
|
|
||||||
|
|
||||||
int Token::parseSize(string::const_iterator _begin, string::const_iterator _end)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -123,7 +139,20 @@ int Token::parseSize(string::const_iterator _begin, string::const_iterator _end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple<Token::Value, unsigned int, unsigned int> Token::fromIdentifierOrKeyword(string const& _literal)
|
static 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},
|
||||||
|
#define TOKEN(name, string, precedence)
|
||||||
|
static const map<string, Token> keywords({TOKEN_LIST(TOKEN, KEYWORD)});
|
||||||
|
#undef KEYWORD
|
||||||
|
#undef TOKEN
|
||||||
|
auto it = keywords.find(_name);
|
||||||
|
return it == keywords.end() ? Token::Identifier : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(string const& _literal)
|
||||||
{
|
{
|
||||||
auto positionM = find_if(_literal.begin(), _literal.end(), ::isdigit);
|
auto positionM = find_if(_literal.begin(), _literal.end(), ::isdigit);
|
||||||
if (positionM != _literal.end())
|
if (positionM != _literal.end())
|
||||||
@ -131,7 +160,7 @@ tuple<Token::Value, unsigned int, unsigned int> Token::fromIdentifierOrKeyword(s
|
|||||||
string baseType(_literal.begin(), positionM);
|
string baseType(_literal.begin(), positionM);
|
||||||
auto positionX = find_if_not(positionM, _literal.end(), ::isdigit);
|
auto positionX = find_if_not(positionM, _literal.end(), ::isdigit);
|
||||||
int m = parseSize(positionM, positionX);
|
int m = parseSize(positionM, positionX);
|
||||||
Token::Value keyword = keywordByName(baseType);
|
Token keyword = keywordByName(baseType);
|
||||||
if (keyword == Token::Bytes)
|
if (keyword == Token::Bytes)
|
||||||
{
|
{
|
||||||
if (0 < m && m <= 32 && positionX == _literal.end())
|
if (0 < m && m <= 32 && positionX == _literal.end())
|
||||||
@ -172,20 +201,7 @@ tuple<Token::Value, unsigned int, unsigned int> Token::fromIdentifierOrKeyword(s
|
|||||||
|
|
||||||
return make_tuple(keywordByName(_literal), 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},
|
|
||||||
#define TOKEN(name, string, precedence)
|
|
||||||
static const map<string, Token::Value> keywords({TOKEN_LIST(TOKEN, KEYWORD)});
|
|
||||||
#undef KEYWORD
|
|
||||||
#undef TOKEN
|
|
||||||
auto it = keywords.find(_name);
|
|
||||||
return it == keywords.end() ? Token::Identifier : it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef KT
|
}
|
||||||
#undef KK
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include <libdevcore/Common.h>
|
#include <libdevcore/Common.h>
|
||||||
#include <libsolidity/interface/Exceptions.h>
|
#include <libsolidity/interface/Exceptions.h>
|
||||||
#include <libsolidity/parsing/UndefMacros.h>
|
#include <libsolidity/parsing/UndefMacros.h>
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
@ -267,119 +268,95 @@ namespace solidity
|
|||||||
/* Scanner-internal use only. */ \
|
/* Scanner-internal use only. */ \
|
||||||
T(Whitespace, NULL, 0)
|
T(Whitespace, NULL, 0)
|
||||||
|
|
||||||
|
// All token values.
|
||||||
class Token
|
// attention! msvc issue:
|
||||||
{
|
// http://stackoverflow.com/questions/9567868/compile-errors-after-adding-v8-to-my-project-c2143-c2059
|
||||||
public:
|
// @todo: avoid TOKEN_LIST macro
|
||||||
// All token values.
|
enum class Token : unsigned int {
|
||||||
// attention! msvc issue:
|
|
||||||
// http://stackoverflow.com/questions/9567868/compile-errors-after-adding-v8-to-my-project-c2143-c2059
|
|
||||||
// @todo: avoid TOKEN_LIST macro
|
|
||||||
#define T(name, string, precedence) name,
|
#define T(name, string, precedence) name,
|
||||||
enum Value
|
TOKEN_LIST(T, T)
|
||||||
{
|
NUM_TOKENS
|
||||||
TOKEN_LIST(T, T)
|
|
||||||
NUM_TOKENS
|
|
||||||
};
|
|
||||||
#undef T
|
#undef T
|
||||||
|
};
|
||||||
|
|
||||||
// @returns a string corresponding to the C++ token name
|
namespace TokenTraits
|
||||||
// (e.g. "LT" for the token LT).
|
{
|
||||||
static char const* name(Value tok)
|
constexpr size_t count() { return static_cast<size_t>(Token::NUM_TOKENS); }
|
||||||
{
|
|
||||||
solAssert(tok < NUM_TOKENS, "");
|
|
||||||
return m_name[tok];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Predicates
|
// Predicates
|
||||||
static bool isElementaryTypeName(Value tok) { return Int <= tok && tok < TypesEnd; }
|
constexpr bool isElementaryTypeName(Token tok) { return Token::Int <= tok && tok < Token::TypesEnd; }
|
||||||
static bool isAssignmentOp(Value tok) { return Assign <= tok && tok <= AssignMod; }
|
constexpr bool isAssignmentOp(Token tok) { return Token::Assign <= tok && tok <= Token::AssignMod; }
|
||||||
static bool isBinaryOp(Value op) { return Comma <= op && op <= Exp; }
|
constexpr bool isBinaryOp(Token op) { return Token::Comma <= op && op <= Token::Exp; }
|
||||||
static bool isCommutativeOp(Value op) { return op == BitOr || op == BitXor || op == BitAnd ||
|
constexpr bool isCommutativeOp(Token op) { return op == Token::BitOr || op == Token::BitXor || op == Token::BitAnd ||
|
||||||
op == Add || op == Mul || op == Equal || op == NotEqual; }
|
op == Token::Add || op == Token::Mul || op == Token::Equal || op == Token::NotEqual; }
|
||||||
static bool isArithmeticOp(Value op) { return Add <= op && op <= Exp; }
|
constexpr bool isArithmeticOp(Token op) { return Token::Add <= op && op <= Token::Exp; }
|
||||||
static bool isCompareOp(Value op) { return Equal <= op && op <= GreaterThanOrEqual; }
|
constexpr bool isCompareOp(Token op) { return Token::Equal <= op && op <= Token::GreaterThanOrEqual; }
|
||||||
|
|
||||||
static Value AssignmentToBinaryOp(Value op)
|
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; }
|
||||||
|
|
||||||
|
constexpr bool isStateMutabilitySpecifier(Token op, bool _allowConstant = true)
|
||||||
{
|
{
|
||||||
solAssert(isAssignmentOp(op) && op != Assign, "");
|
return (op == Token::Constant && _allowConstant)
|
||||||
return Value(op + (BitOr - AssignBitOr));
|
|| op == Token::Pure || op == Token::View || op == Token::Payable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isBitOp(Value op) { return (BitOr <= op && op <= BitAnd) || op == BitNot; }
|
constexpr bool isEtherSubdenomination(Token op) { return op == Token::SubWei || op == Token::SubSzabo || op == Token::SubFinney || op == Token::SubEther; }
|
||||||
static bool isBooleanOp(Value op) { return (Or <= op && op <= And) || op == Not; }
|
constexpr bool isTimeSubdenomination(Token op) { return op == Token::SubSecond || op == Token::SubMinute || op == Token::SubHour || op == Token::SubDay || op == Token::SubWeek || op == Token::SubYear; }
|
||||||
static bool isUnaryOp(Value op) { return (Not <= op && op <= Delete) || op == Add || op == Sub; }
|
constexpr bool isReservedKeyword(Token op) { return (Token::Abstract <= op && op <= Token::Unchecked); }
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (op == Constant && _allowConstant)
|
|
||||||
return true;
|
|
||||||
return op == Pure || op == View || op == 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
|
inline Token AssignmentToBinaryOp(Token op)
|
||||||
// (.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, "");
|
solAssert(isAssignmentOp(op) && op != Token::Assign, "");
|
||||||
return m_string[tok];
|
return static_cast<Token>(static_cast<int>(op) + (static_cast<int>(Token::BitOr) - static_cast<int>(Token::AssignBitOr)));
|
||||||
}
|
|
||||||
|
|
||||||
static std::string friendlyName(Value tok)
|
|
||||||
{
|
|
||||||
char const* ret = toString(tok);
|
|
||||||
if (ret == nullptr)
|
|
||||||
{
|
|
||||||
ret = name(tok);
|
|
||||||
solAssert(ret != nullptr, "");
|
|
||||||
}
|
|
||||||
return std::string(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @returns the precedence > 0 for binary and compare
|
// @returns the precedence > 0 for binary and compare
|
||||||
// operators; returns 0 otherwise.
|
// operators; returns 0 otherwise.
|
||||||
static int precedence(Value tok)
|
int precedence(Token tok);
|
||||||
{
|
|
||||||
solAssert(tok < NUM_TOKENS, "");
|
|
||||||
return m_precedence[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 a string corresponding to the C++ token name
|
||||||
// @returns -1 on error (invalid digit or number too large)
|
// (e.g. "LT" for the token LT).
|
||||||
static int parseSize(std::string::const_iterator _begin, std::string::const_iterator _end);
|
char const* name(Token tok);
|
||||||
// @returns the keyword with name @a _name or Token::Identifier of no such keyword exists.
|
|
||||||
static Token::Value keywordByName(std::string const& _name);
|
// @returns a string corresponding to the JS token string
|
||||||
static char const* const m_name[NUM_TOKENS];
|
// (.e., "<" for the token LT) or NULL if the token doesn't
|
||||||
static char const* const m_string[NUM_TOKENS];
|
// have a (unique) string (e.g. an IDENTIFIER).
|
||||||
static int8_t const m_precedence[NUM_TOKENS];
|
char const* toString(Token tok);
|
||||||
static char const m_tokenType[NUM_TOKENS];
|
|
||||||
};
|
std::string friendlyName(Token tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, Token token)
|
||||||
|
{
|
||||||
|
os << TokenTraits::friendlyName(token);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
class ElementaryTypeNameToken
|
class ElementaryTypeNameToken
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ElementaryTypeNameToken(Token::Value _token, unsigned const& _firstNumber, unsigned const& _secondNumber)
|
ElementaryTypeNameToken(Token _token, unsigned const& _firstNumber, unsigned const& _secondNumber)
|
||||||
{
|
{
|
||||||
assertDetails(_token, _firstNumber, _secondNumber);
|
assertDetails(_token, _firstNumber, _secondNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int firstNumber() const { return m_firstNumber; }
|
unsigned int firstNumber() const { return m_firstNumber; }
|
||||||
unsigned int secondNumber() const { return m_secondNumber; }
|
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
|
///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 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))
|
if (tokenValue || (firstNumber() == 0 && secondNumber() == 0))
|
||||||
return name;
|
return name;
|
||||||
solAssert(name.size() >= 3, "Token name size should be greater than 3. Should not reach here.");
|
solAssert(name.size() >= 3, "Token name size should be greater than 3. Should not reach here.");
|
||||||
@ -390,11 +367,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value m_token;
|
Token m_token;
|
||||||
unsigned int m_firstNumber;
|
unsigned int m_firstNumber;
|
||||||
unsigned int m_secondNumber;
|
unsigned int m_secondNumber;
|
||||||
/// throws if type is not properly sized
|
/// 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,13 +42,13 @@ SemVerMatchExpression parseExpression(string const& _input)
|
|||||||
{
|
{
|
||||||
Scanner scanner{CharStream(_input)};
|
Scanner scanner{CharStream(_input)};
|
||||||
vector<string> literals;
|
vector<string> literals;
|
||||||
vector<Token::Value> tokens;
|
vector<Token> tokens;
|
||||||
while (scanner.currentToken() != Token::EOS)
|
while (scanner.currentToken() != Token::EOS)
|
||||||
{
|
{
|
||||||
auto token = scanner.currentToken();
|
auto token = scanner.currentToken();
|
||||||
string literal = scanner.currentLiteral();
|
string literal = scanner.currentLiteral();
|
||||||
if (literal.empty() && Token::toString(token))
|
if (literal.empty() && TokenTraits::toString(token))
|
||||||
literal = Token::toString(token);
|
literal = TokenTraits::toString(token);
|
||||||
literals.push_back(literal);
|
literals.push_back(literal);
|
||||||
tokens.push_back(token);
|
tokens.push_back(token);
|
||||||
scanner.next();
|
scanner.next();
|
||||||
|
Loading…
Reference in New Issue
Block a user