mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Pointer type cleanup: Use ASTPointer only for AST nodes and shared_ptr for type
pointer.
This commit is contained in:
parent
f0c334670d
commit
be885dc3cf
86
AST.cpp
86
AST.cpp
@ -250,46 +250,42 @@ void Literal::accept(ASTVisitor& _visitor)
|
|||||||
|
|
||||||
void Statement::expectType(Expression& _expression, const Type& _expectedType)
|
void Statement::expectType(Expression& _expression, const Type& _expectedType)
|
||||||
{
|
{
|
||||||
if (!_expression.checkTypeRequirements()->isImplicitlyConvertibleTo(_expectedType))
|
_expression.checkTypeRequirements();
|
||||||
|
if (!_expression.getType()->isImplicitlyConvertibleTo(_expectedType))
|
||||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Type not implicitly convertible "
|
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Type not implicitly convertible "
|
||||||
"to expected type."));
|
"to expected type."));
|
||||||
//@todo provide more information to the exception
|
//@todo provide more information to the exception
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Block::checkTypeRequirements()
|
void Block::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
for (ptr<Statement> const& statement: m_statements)
|
for (std::shared_ptr<Statement> const& statement: m_statements)
|
||||||
statement->checkTypeRequirements();
|
statement->checkTypeRequirements();
|
||||||
return ptr<Type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> IfStatement::checkTypeRequirements()
|
void IfStatement::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
expectType(*m_condition, BoolType());
|
expectType(*m_condition, BoolType());
|
||||||
m_trueBody->checkTypeRequirements();
|
m_trueBody->checkTypeRequirements();
|
||||||
if (m_falseBody)
|
if (m_falseBody)
|
||||||
m_falseBody->checkTypeRequirements();
|
m_falseBody->checkTypeRequirements();
|
||||||
return ptr<Type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> WhileStatement::checkTypeRequirements()
|
void WhileStatement::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
expectType(*m_condition, BoolType());
|
expectType(*m_condition, BoolType());
|
||||||
m_body->checkTypeRequirements();
|
m_body->checkTypeRequirements();
|
||||||
return ptr<Type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Continue::checkTypeRequirements()
|
void Continue::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
return ptr<Type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Break::checkTypeRequirements()
|
void Break::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
return ptr<Type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Return::checkTypeRequirements()
|
void Return::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_returnParameters != nullptr);
|
BOOST_ASSERT(m_returnParameters != nullptr);
|
||||||
if (m_returnParameters->getParameters().size() != 1)
|
if (m_returnParameters->getParameters().size() != 1)
|
||||||
@ -299,10 +295,9 @@ ptr<Type> Return::checkTypeRequirements()
|
|||||||
// this could later be changed such that the paramaters type is an anonymous struct type,
|
// this could later be changed such that the paramaters type is an anonymous struct type,
|
||||||
// but for now, we only allow one return parameter
|
// but for now, we only allow one return parameter
|
||||||
expectType(*m_expression, *m_returnParameters->getParameters().front()->getType());
|
expectType(*m_expression, *m_returnParameters->getParameters().front()->getType());
|
||||||
return ptr<Type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> VariableDefinition::checkTypeRequirements()
|
void VariableDefinition::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
// Variables can be declared without type (with "var"), in which case the first assignment
|
// Variables can be declared without type (with "var"), in which case the first assignment
|
||||||
// setsthe type.
|
// setsthe type.
|
||||||
@ -313,17 +308,20 @@ ptr<Type> VariableDefinition::checkTypeRequirements()
|
|||||||
if (m_variable->getType())
|
if (m_variable->getType())
|
||||||
expectType(*m_value, *m_variable->getType());
|
expectType(*m_value, *m_variable->getType());
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// no type declared and no previous assignment, infer the type
|
// no type declared and no previous assignment, infer the type
|
||||||
m_variable->setType(m_value->checkTypeRequirements());
|
m_value->checkTypeRequirements();
|
||||||
|
m_variable->setType(m_value->getType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ptr<Type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Assignment::checkTypeRequirements()
|
void Assignment::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
//@todo lefthandside actually has to be assignable
|
//@todo lefthandside actually has to be assignable
|
||||||
// add a feature to the type system to check that
|
// add a feature to the type system to check that
|
||||||
expectType(*m_rightHandSide, *m_leftHandSide->checkTypeRequirements());
|
m_leftHandSide->checkTypeRequirements();
|
||||||
|
expectType(*m_rightHandSide, *m_leftHandSide->getType());
|
||||||
m_type = m_leftHandSide->getType();
|
m_type = m_leftHandSide->getType();
|
||||||
if (m_assigmentOperator != Token::ASSIGN)
|
if (m_assigmentOperator != Token::ASSIGN)
|
||||||
{
|
{
|
||||||
@ -331,19 +329,18 @@ ptr<Type> Assignment::checkTypeRequirements()
|
|||||||
if (!m_type->acceptsBinaryOperator(Token::AssignmentToBinaryOp(m_assigmentOperator)))
|
if (!m_type->acceptsBinaryOperator(Token::AssignmentToBinaryOp(m_assigmentOperator)))
|
||||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type."));
|
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type."));
|
||||||
}
|
}
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> UnaryOperation::checkTypeRequirements()
|
void UnaryOperation::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
// INC, DEC, NOT, BIT_NOT, DELETE
|
// INC, DEC, NOT, BIT_NOT, DELETE
|
||||||
m_type = m_subExpression->checkTypeRequirements();
|
m_subExpression->checkTypeRequirements();
|
||||||
|
m_type = m_subExpression->getType();
|
||||||
if (m_type->acceptsUnaryOperator(m_operator))
|
if (m_type->acceptsUnaryOperator(m_operator))
|
||||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Unary operator not compatible with type."));
|
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Unary operator not compatible with type."));
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> BinaryOperation::checkTypeRequirements()
|
void BinaryOperation::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
m_right->checkTypeRequirements();
|
m_right->checkTypeRequirements();
|
||||||
m_left->checkTypeRequirements();
|
m_left->checkTypeRequirements();
|
||||||
@ -362,19 +359,18 @@ ptr<Type> BinaryOperation::checkTypeRequirements()
|
|||||||
if (!m_commonType->acceptsBinaryOperator(m_operator))
|
if (!m_commonType->acceptsBinaryOperator(m_operator))
|
||||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type."));
|
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type."));
|
||||||
}
|
}
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> FunctionCall::checkTypeRequirements()
|
void FunctionCall::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
m_expression->checkTypeRequirements();
|
m_expression->checkTypeRequirements();
|
||||||
for (ptr<Expression> const& argument: m_arguments)
|
for (ASTPointer<Expression> const& argument: m_arguments)
|
||||||
argument->checkTypeRequirements();
|
argument->checkTypeRequirements();
|
||||||
ptr<Type> expressionType = m_expression->getType();
|
Type const& expressionType = *m_expression->getType();
|
||||||
Type::Category const category = expressionType->getCategory();
|
Type::Category const category = expressionType.getCategory();
|
||||||
if (category == Type::Category::TYPE)
|
if (category == Type::Category::TYPE)
|
||||||
{
|
{
|
||||||
TypeType* type = dynamic_cast<TypeType*>(expressionType.get());
|
TypeType const* type = dynamic_cast<TypeType const*>(&expressionType);
|
||||||
BOOST_ASSERT(type != nullptr);
|
BOOST_ASSERT(type != nullptr);
|
||||||
//@todo for structs, we have to check the number of arguments to be equal to the
|
//@todo for structs, we have to check the number of arguments to be equal to the
|
||||||
// number of non-mapping members
|
// number of non-mapping members
|
||||||
@ -391,10 +387,10 @@ ptr<Type> FunctionCall::checkTypeRequirements()
|
|||||||
//@todo would be nice to create a struct type from the arguments
|
//@todo would be nice to create a struct type from the arguments
|
||||||
// and then ask if that is implicitly convertible to the struct represented by the
|
// and then ask if that is implicitly convertible to the struct represented by the
|
||||||
// function parameters
|
// function parameters
|
||||||
FunctionType* function = dynamic_cast<FunctionType*>(expressionType.get());
|
FunctionType const* function = dynamic_cast<FunctionType const*>(&expressionType);
|
||||||
BOOST_ASSERT(function != nullptr);
|
BOOST_ASSERT(function != nullptr);
|
||||||
FunctionDefinition const& fun = function->getFunction();
|
FunctionDefinition const& fun = function->getFunction();
|
||||||
std::vector<ptr<VariableDeclaration>> const& parameters = fun.getParameters();
|
std::vector<ASTPointer<VariableDeclaration>> const& parameters = fun.getParameters();
|
||||||
if (parameters.size() != m_arguments.size())
|
if (parameters.size() != m_arguments.size())
|
||||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Wrong argument count for "
|
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Wrong argument count for "
|
||||||
"function call."));
|
"function call."));
|
||||||
@ -413,24 +409,21 @@ ptr<Type> FunctionCall::checkTypeRequirements()
|
|||||||
{
|
{
|
||||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Type does not support invocation."));
|
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Type does not support invocation."));
|
||||||
}
|
}
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> MemberAccess::checkTypeRequirements()
|
void MemberAccess::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(false); // not yet implemented
|
BOOST_ASSERT(false); // not yet implemented
|
||||||
// m_type = ;
|
// m_type = ;
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> IndexAccess::checkTypeRequirements()
|
void IndexAccess::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(false); // not yet implemented
|
BOOST_ASSERT(false); // not yet implemented
|
||||||
// m_type = ;
|
// m_type = ;
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Identifier::checkTypeRequirements()
|
void Identifier::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_referencedDeclaration != nullptr);
|
BOOST_ASSERT(m_referencedDeclaration != nullptr);
|
||||||
//@todo these dynamic casts here are not really nice...
|
//@todo these dynamic casts here are not really nice...
|
||||||
@ -444,11 +437,11 @@ ptr<Type> Identifier::checkTypeRequirements()
|
|||||||
VariableDeclaration* variable = dynamic_cast<VariableDeclaration*>(m_referencedDeclaration);
|
VariableDeclaration* variable = dynamic_cast<VariableDeclaration*>(m_referencedDeclaration);
|
||||||
if (variable != nullptr)
|
if (variable != nullptr)
|
||||||
{
|
{
|
||||||
if (variable->getType().get() == nullptr)
|
if (!variable->getType())
|
||||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Variable referenced before type "
|
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Variable referenced before type "
|
||||||
"could be determined."));
|
"could be determined."));
|
||||||
m_type = variable->getType();
|
m_type = variable->getType();
|
||||||
return m_type;
|
return;
|
||||||
}
|
}
|
||||||
//@todo can we unify these with TypeName::toType()?
|
//@todo can we unify these with TypeName::toType()?
|
||||||
StructDefinition* structDef = dynamic_cast<StructDefinition*>(m_referencedDeclaration);
|
StructDefinition* structDef = dynamic_cast<StructDefinition*>(m_referencedDeclaration);
|
||||||
@ -456,7 +449,7 @@ ptr<Type> Identifier::checkTypeRequirements()
|
|||||||
{
|
{
|
||||||
// note that we do not have a struct type here
|
// note that we do not have a struct type here
|
||||||
m_type = std::make_shared<TypeType>(std::make_shared<StructType>(*structDef));
|
m_type = std::make_shared<TypeType>(std::make_shared<StructType>(*structDef));
|
||||||
return m_type;
|
return;
|
||||||
}
|
}
|
||||||
FunctionDefinition* functionDef = dynamic_cast<FunctionDefinition*>(m_referencedDeclaration);
|
FunctionDefinition* functionDef = dynamic_cast<FunctionDefinition*>(m_referencedDeclaration);
|
||||||
if (functionDef != nullptr)
|
if (functionDef != nullptr)
|
||||||
@ -465,28 +458,25 @@ ptr<Type> Identifier::checkTypeRequirements()
|
|||||||
// Calling a function (e.g. function(12), otherContract.function(34)) does not do a type
|
// Calling a function (e.g. function(12), otherContract.function(34)) does not do a type
|
||||||
// conversion.
|
// conversion.
|
||||||
m_type = std::make_shared<FunctionType>(*functionDef);
|
m_type = std::make_shared<FunctionType>(*functionDef);
|
||||||
return m_type;
|
return;
|
||||||
}
|
}
|
||||||
ContractDefinition* contractDef = dynamic_cast<ContractDefinition*>(m_referencedDeclaration);
|
ContractDefinition* contractDef = dynamic_cast<ContractDefinition*>(m_referencedDeclaration);
|
||||||
if (contractDef != nullptr)
|
if (contractDef != nullptr)
|
||||||
{
|
{
|
||||||
m_type = std::make_shared<TypeType>(std::make_shared<ContractType>(*contractDef));
|
m_type = std::make_shared<TypeType>(std::make_shared<ContractType>(*contractDef));
|
||||||
return m_type;
|
return;
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(false); // declaration reference of unknown/forbidden type
|
BOOST_ASSERT(false); // declaration reference of unknown/forbidden type
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> ElementaryTypeNameExpression::checkTypeRequirements()
|
void ElementaryTypeNameExpression::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
m_type = std::make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken));
|
m_type = std::make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken));
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Literal::checkTypeRequirements()
|
void Literal::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
m_type = Type::forLiteral(*this);
|
m_type = Type::forLiteral(*this);
|
||||||
return m_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
217
AST.h
217
AST.h
@ -51,9 +51,9 @@ public:
|
|||||||
|
|
||||||
virtual void accept(ASTVisitor& _visitor) = 0;
|
virtual void accept(ASTVisitor& _visitor) = 0;
|
||||||
template <class T>
|
template <class T>
|
||||||
static void listAccept(std::vector<ptr<T>>& _list, ASTVisitor& _visitor)
|
static void listAccept(std::vector<ASTPointer<T>>& _list, ASTVisitor& _visitor)
|
||||||
{
|
{
|
||||||
for (ptr<T>& element: _list)
|
for (ASTPointer<T>& element: _list)
|
||||||
element->accept(_visitor);
|
element->accept(_visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,22 +65,22 @@ private:
|
|||||||
class Declaration: public ASTNode
|
class Declaration: public ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Declaration(Location const& _location, ptr<ASTString> const& _name)
|
Declaration(Location const& _location, ASTPointer<ASTString> const& _name)
|
||||||
: ASTNode(_location), m_name(_name) {}
|
: ASTNode(_location), m_name(_name) {}
|
||||||
|
|
||||||
const ASTString& getName() const { return *m_name; }
|
const ASTString& getName() const { return *m_name; }
|
||||||
private:
|
private:
|
||||||
ptr<ASTString> m_name;
|
ASTPointer<ASTString> m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ContractDefinition: public Declaration
|
class ContractDefinition: public Declaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContractDefinition(Location const& _location,
|
ContractDefinition(Location const& _location,
|
||||||
ptr<ASTString> const& _name,
|
ASTPointer<ASTString> const& _name,
|
||||||
std::vector<ptr<StructDefinition>> const& _definedStructs,
|
std::vector<ASTPointer<StructDefinition>> const& _definedStructs,
|
||||||
std::vector<ptr<VariableDeclaration>> const& _stateVariables,
|
std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables,
|
||||||
std::vector<ptr<FunctionDefinition>> const& _definedFunctions)
|
std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions)
|
||||||
: Declaration(_location, _name),
|
: Declaration(_location, _name),
|
||||||
m_definedStructs(_definedStructs),
|
m_definedStructs(_definedStructs),
|
||||||
m_stateVariables(_stateVariables),
|
m_stateVariables(_stateVariables),
|
||||||
@ -89,26 +89,26 @@ public:
|
|||||||
|
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
std::vector<ptr<StructDefinition>> const& getDefinedStructs() { return m_definedStructs; }
|
std::vector<ASTPointer<StructDefinition>> const& getDefinedStructs() { return m_definedStructs; }
|
||||||
std::vector<ptr<VariableDeclaration>> const& getStateVariables() { return m_stateVariables; }
|
std::vector<ASTPointer<VariableDeclaration>> const& getStateVariables() { return m_stateVariables; }
|
||||||
std::vector<ptr<FunctionDefinition>> const& getDefinedFunctions() { return m_definedFunctions; }
|
std::vector<ASTPointer<FunctionDefinition>> const& getDefinedFunctions() { return m_definedFunctions; }
|
||||||
private:
|
private:
|
||||||
std::vector<ptr<StructDefinition>> m_definedStructs;
|
std::vector<ASTPointer<StructDefinition>> m_definedStructs;
|
||||||
std::vector<ptr<VariableDeclaration>> m_stateVariables;
|
std::vector<ASTPointer<VariableDeclaration>> m_stateVariables;
|
||||||
std::vector<ptr<FunctionDefinition>> m_definedFunctions;
|
std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StructDefinition: public Declaration
|
class StructDefinition: public Declaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StructDefinition(Location const& _location,
|
StructDefinition(Location const& _location,
|
||||||
ptr<ASTString> const& _name,
|
ASTPointer<ASTString> const& _name,
|
||||||
std::vector<ptr<VariableDeclaration>> const& _members)
|
std::vector<ASTPointer<VariableDeclaration>> const& _members)
|
||||||
: Declaration(_location, _name), m_members(_members) {}
|
: Declaration(_location, _name), m_members(_members) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<ptr<VariableDeclaration>> m_members;
|
std::vector<ASTPointer<VariableDeclaration>> m_members;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Used as function parameter list and return list
|
/// Used as function parameter list and return list
|
||||||
@ -117,23 +117,23 @@ private:
|
|||||||
class ParameterList: public ASTNode
|
class ParameterList: public ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ParameterList(Location const& _location, std::vector<ptr<VariableDeclaration>> const& _parameters)
|
ParameterList(Location const& _location, std::vector<ASTPointer<VariableDeclaration>> const& _parameters)
|
||||||
: ASTNode(_location), m_parameters(_parameters) {}
|
: ASTNode(_location), m_parameters(_parameters) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
std::vector<ptr<VariableDeclaration>> const& getParameters() { return m_parameters; }
|
std::vector<ASTPointer<VariableDeclaration>> const& getParameters() { return m_parameters; }
|
||||||
private:
|
private:
|
||||||
std::vector<ptr<VariableDeclaration>> m_parameters;
|
std::vector<ASTPointer<VariableDeclaration>> m_parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FunctionDefinition: public Declaration
|
class FunctionDefinition: public Declaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FunctionDefinition(Location const& _location, ptr<ASTString> const& _name, bool _isPublic,
|
FunctionDefinition(Location const& _location, ASTPointer<ASTString> const& _name, bool _isPublic,
|
||||||
ptr<ParameterList> const& _parameters,
|
ASTPointer<ParameterList> const& _parameters,
|
||||||
bool _isDeclaredConst,
|
bool _isDeclaredConst,
|
||||||
ptr<ParameterList> const& _returnParameters,
|
ASTPointer<ParameterList> const& _returnParameters,
|
||||||
ptr<Block> const& _body)
|
ASTPointer<Block> const& _body)
|
||||||
: Declaration(_location, _name), m_isPublic(_isPublic), m_parameters(_parameters),
|
: Declaration(_location, _name), m_isPublic(_isPublic), m_parameters(_parameters),
|
||||||
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters),
|
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters),
|
||||||
m_body(_body) {}
|
m_body(_body) {}
|
||||||
@ -141,23 +141,23 @@ public:
|
|||||||
|
|
||||||
bool isPublic() const { return m_isPublic; }
|
bool isPublic() const { return m_isPublic; }
|
||||||
bool isDeclaredConst() const { return m_isDeclaredConst; }
|
bool isDeclaredConst() const { return m_isDeclaredConst; }
|
||||||
std::vector<ptr<VariableDeclaration>> const& getParameters() const { return m_parameters->getParameters(); }
|
std::vector<ASTPointer<VariableDeclaration>> const& getParameters() const { return m_parameters->getParameters(); }
|
||||||
ParameterList& getParameterList() { return *m_parameters; }
|
ParameterList& getParameterList() { return *m_parameters; }
|
||||||
ptr<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
|
ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
|
||||||
Block& getBody() { return *m_body; }
|
Block& getBody() { return *m_body; }
|
||||||
private:
|
private:
|
||||||
bool m_isPublic;
|
bool m_isPublic;
|
||||||
ptr<ParameterList> m_parameters;
|
ASTPointer<ParameterList> m_parameters;
|
||||||
bool m_isDeclaredConst;
|
bool m_isDeclaredConst;
|
||||||
ptr<ParameterList> m_returnParameters;
|
ASTPointer<ParameterList> m_returnParameters;
|
||||||
ptr<Block> m_body;
|
ASTPointer<Block> m_body;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VariableDeclaration: public Declaration
|
class VariableDeclaration: public Declaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VariableDeclaration(Location const& _location, ptr<TypeName> const& _type,
|
VariableDeclaration(Location const& _location, ASTPointer<TypeName> const& _type,
|
||||||
ptr<ASTString> const& _name)
|
ASTPointer<ASTString> const& _name)
|
||||||
: Declaration(_location, _name), m_typeName(_type) {}
|
: Declaration(_location, _name), m_typeName(_type) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
@ -166,12 +166,12 @@ public:
|
|||||||
|
|
||||||
//! Returns the declared or inferred type. Can be an empty pointer if no type was explicitly
|
//! Returns the declared or inferred type. Can be an empty pointer if no type was explicitly
|
||||||
//! declared and there is no assignment to the variable that fixes the type.
|
//! declared and there is no assignment to the variable that fixes the type.
|
||||||
ptr<Type> const& getType() const { return m_type; }
|
std::shared_ptr<Type const> const& getType() const { return m_type; }
|
||||||
void setType(ptr<Type> const& _type) { m_type = _type; }
|
void setType(std::shared_ptr<Type const> const& _type) { m_type = _type; }
|
||||||
private:
|
private:
|
||||||
ptr<TypeName> m_typeName; ///< can be empty ("var")
|
ASTPointer<TypeName> m_typeName; ///< can be empty ("var")
|
||||||
|
|
||||||
ptr<Type> m_type;
|
std::shared_ptr<Type const> m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// types
|
/// types
|
||||||
@ -183,7 +183,7 @@ public:
|
|||||||
explicit TypeName(Location const& _location): ASTNode(_location) {}
|
explicit TypeName(Location const& _location): ASTNode(_location) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
virtual ptr<Type> toType() = 0;
|
virtual std::shared_ptr<Type> toType() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// any pre-defined type that is not a mapping
|
/// any pre-defined type that is not a mapping
|
||||||
@ -193,7 +193,7 @@ public:
|
|||||||
explicit ElementaryTypeName(Location const& _location, Token::Value _type)
|
explicit ElementaryTypeName(Location const& _location, Token::Value _type)
|
||||||
: TypeName(_location), m_type(_type) {}
|
: TypeName(_location), m_type(_type) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> toType() override { return Type::fromElementaryTypeName(m_type); }
|
virtual std::shared_ptr<Type> toType() override { return Type::fromElementaryTypeName(m_type); }
|
||||||
|
|
||||||
Token::Value getType() const { return m_type; }
|
Token::Value getType() const { return m_type; }
|
||||||
private:
|
private:
|
||||||
@ -203,16 +203,16 @@ private:
|
|||||||
class UserDefinedTypeName: public TypeName
|
class UserDefinedTypeName: public TypeName
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UserDefinedTypeName(Location const& _location, ptr<ASTString> const& _name)
|
UserDefinedTypeName(Location const& _location, ASTPointer<ASTString> const& _name)
|
||||||
: TypeName(_location), m_name(_name) {}
|
: TypeName(_location), m_name(_name) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> toType() override { return Type::fromUserDefinedTypeName(*this); }
|
virtual std::shared_ptr<Type> toType() override { return Type::fromUserDefinedTypeName(*this); }
|
||||||
|
|
||||||
const ASTString& getName() const { return *m_name; }
|
const ASTString& getName() const { return *m_name; }
|
||||||
void setReferencedStruct(StructDefinition& _referencedStruct) { m_referencedStruct = &_referencedStruct; }
|
void setReferencedStruct(StructDefinition& _referencedStruct) { m_referencedStruct = &_referencedStruct; }
|
||||||
StructDefinition const* getReferencedStruct() const { return m_referencedStruct; }
|
StructDefinition const* getReferencedStruct() const { return m_referencedStruct; }
|
||||||
private:
|
private:
|
||||||
ptr<ASTString> m_name;
|
ASTPointer<ASTString> m_name;
|
||||||
|
|
||||||
StructDefinition* m_referencedStruct;
|
StructDefinition* m_referencedStruct;
|
||||||
};
|
};
|
||||||
@ -220,14 +220,14 @@ private:
|
|||||||
class Mapping: public TypeName
|
class Mapping: public TypeName
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Mapping(Location const& _location, ptr<ElementaryTypeName> const& _keyType,
|
Mapping(Location const& _location, ASTPointer<ElementaryTypeName> const& _keyType,
|
||||||
ptr<TypeName> const& _valueType)
|
ASTPointer<TypeName> const& _valueType)
|
||||||
: TypeName(_location), m_keyType(_keyType), m_valueType(_valueType) {}
|
: TypeName(_location), m_keyType(_keyType), m_valueType(_valueType) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> toType() override { return Type::fromMapping(*this); }
|
virtual std::shared_ptr<Type> toType() override { return Type::fromMapping(*this); }
|
||||||
private:
|
private:
|
||||||
ptr<ElementaryTypeName> m_keyType;
|
ASTPointer<ElementaryTypeName> m_keyType;
|
||||||
ptr<TypeName> m_valueType;
|
ASTPointer<TypeName> m_valueType;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
@ -244,7 +244,7 @@ public:
|
|||||||
//! Check all type requirements, throws exception if some requirement is not met.
|
//! Check all type requirements, throws exception if some requirement is not met.
|
||||||
//! For expressions, this also returns the inferred type of the expression. For other
|
//! For expressions, this also returns the inferred type of the expression. For other
|
||||||
//! statements, returns the empty pointer.
|
//! statements, returns the empty pointer.
|
||||||
virtual ptr<Type> checkTypeRequirements() = 0;
|
virtual void checkTypeRequirements() = 0;
|
||||||
protected:
|
protected:
|
||||||
//! Check that the inferred type for _expression is _expectedType or at least implicitly
|
//! Check that the inferred type for _expression is _expectedType or at least implicitly
|
||||||
//! convertible to _expectedType. If not, throw exception.
|
//! convertible to _expectedType. If not, throw exception.
|
||||||
@ -254,28 +254,28 @@ protected:
|
|||||||
class Block: public Statement
|
class Block: public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Block(Location const& _location, std::vector<ptr<Statement>> const& _statements)
|
Block(Location const& _location, std::vector<ASTPointer<Statement>> const& _statements)
|
||||||
: Statement(_location), m_statements(_statements) {}
|
: Statement(_location), m_statements(_statements) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
private:
|
private:
|
||||||
std::vector<ptr<Statement>> m_statements;
|
std::vector<ASTPointer<Statement>> m_statements;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IfStatement: public Statement
|
class IfStatement: public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IfStatement(Location const& _location, ptr<Expression> const& _condition,
|
IfStatement(Location const& _location, ASTPointer<Expression> const& _condition,
|
||||||
ptr<Statement> const& _trueBody, ptr<Statement> const& _falseBody)
|
ASTPointer<Statement> const& _trueBody, ASTPointer<Statement> const& _falseBody)
|
||||||
: Statement(_location), m_condition(_condition),
|
: Statement(_location), m_condition(_condition),
|
||||||
m_trueBody(_trueBody), m_falseBody(_falseBody) {}
|
m_trueBody(_trueBody), m_falseBody(_falseBody) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_condition;
|
ASTPointer<Expression> m_condition;
|
||||||
ptr<Statement> m_trueBody;
|
ASTPointer<Statement> m_trueBody;
|
||||||
ptr<Statement> m_falseBody; //< "else" part, optional
|
ASTPointer<Statement> m_falseBody; //< "else" part, optional
|
||||||
};
|
};
|
||||||
|
|
||||||
class BreakableStatement: public Statement
|
class BreakableStatement: public Statement
|
||||||
@ -288,14 +288,14 @@ public:
|
|||||||
class WhileStatement: public BreakableStatement
|
class WhileStatement: public BreakableStatement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WhileStatement(Location const& _location, ptr<Expression> const& _condition,
|
WhileStatement(Location const& _location, ASTPointer<Expression> const& _condition,
|
||||||
ptr<Statement> const& _body)
|
ASTPointer<Statement> const& _body)
|
||||||
: BreakableStatement(_location), m_condition(_condition), m_body(_body) {}
|
: BreakableStatement(_location), m_condition(_condition), m_body(_body) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_condition;
|
ASTPointer<Expression> m_condition;
|
||||||
ptr<Statement> m_body;
|
ASTPointer<Statement> m_body;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Continue: public Statement
|
class Continue: public Statement
|
||||||
@ -303,7 +303,7 @@ class Continue: public Statement
|
|||||||
public:
|
public:
|
||||||
Continue(Location const& _location): Statement(_location) {}
|
Continue(Location const& _location): Statement(_location) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Break: public Statement
|
class Break: public Statement
|
||||||
@ -311,20 +311,20 @@ class Break: public Statement
|
|||||||
public:
|
public:
|
||||||
Break(Location const& _location): Statement(_location) {}
|
Break(Location const& _location): Statement(_location) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Return: public Statement
|
class Return: public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Return(Location const& _location, ptr<Expression> _expression)
|
Return(Location const& _location, ASTPointer<Expression> _expression)
|
||||||
: Statement(_location), m_expression(_expression) {}
|
: Statement(_location), m_expression(_expression) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; }
|
void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; }
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_expression; //< value to return, optional
|
ASTPointer<Expression> m_expression; //< value to return, optional
|
||||||
|
|
||||||
ParameterList* m_returnParameters; //< extracted from the function declaration
|
ParameterList* m_returnParameters; //< extracted from the function declaration
|
||||||
};
|
};
|
||||||
@ -332,24 +332,25 @@ private:
|
|||||||
class VariableDefinition: public Statement
|
class VariableDefinition: public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VariableDefinition(Location const& _location, ptr<VariableDeclaration> _variable,
|
VariableDefinition(Location const& _location, ASTPointer<VariableDeclaration> _variable,
|
||||||
ptr<Expression> _value)
|
ASTPointer<Expression> _value)
|
||||||
: Statement(_location), m_variable(_variable), m_value(_value) {}
|
: Statement(_location), m_variable(_variable), m_value(_value) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ptr<VariableDeclaration> m_variable;
|
ASTPointer<VariableDeclaration> m_variable;
|
||||||
ptr<Expression> m_value; ///< can be missing
|
ASTPointer<Expression> m_value; ///< can be missing
|
||||||
};
|
};
|
||||||
|
|
||||||
class Expression: public Statement
|
class Expression: public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Expression(Location const& _location): Statement(_location) {}
|
Expression(Location const& _location): Statement(_location) {}
|
||||||
ptr<Type> const& getType() { return m_type; }
|
std::shared_ptr<Type const> const& getType() const { return m_type; }
|
||||||
protected:
|
protected:
|
||||||
ptr<Type> m_type;
|
//! Inferred type of the expression, only filled after a call to checkTypeRequirements().
|
||||||
|
std::shared_ptr<Type const> m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
@ -360,95 +361,95 @@ protected:
|
|||||||
class Assignment: public Expression
|
class Assignment: public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Assignment(Location const& _location, ptr<Expression> const& _leftHandSide,
|
Assignment(Location const& _location, ASTPointer<Expression> const& _leftHandSide,
|
||||||
Token::Value _assignmentOperator, ptr<Expression> const& _rightHandSide)
|
Token::Value _assignmentOperator, ASTPointer<Expression> const& _rightHandSide)
|
||||||
: Expression(_location), m_leftHandSide(_leftHandSide),
|
: Expression(_location), m_leftHandSide(_leftHandSide),
|
||||||
m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) {}
|
m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
Token::Value getAssignmentOperator() const { return m_assigmentOperator; }
|
Token::Value getAssignmentOperator() const { return m_assigmentOperator; }
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_leftHandSide;
|
ASTPointer<Expression> m_leftHandSide;
|
||||||
Token::Value m_assigmentOperator;
|
Token::Value m_assigmentOperator;
|
||||||
ptr<Expression> m_rightHandSide;
|
ASTPointer<Expression> m_rightHandSide;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnaryOperation: public Expression
|
class UnaryOperation: public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UnaryOperation(Location const& _location, Token::Value _operator,
|
UnaryOperation(Location const& _location, Token::Value _operator,
|
||||||
ptr<Expression> const& _subExpression, bool _isPrefix)
|
ASTPointer<Expression> const& _subExpression, bool _isPrefix)
|
||||||
: Expression(_location), m_operator(_operator),
|
: Expression(_location), m_operator(_operator),
|
||||||
m_subExpression(_subExpression), m_isPrefix(_isPrefix) {}
|
m_subExpression(_subExpression), m_isPrefix(_isPrefix) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
Token::Value getOperator() const { return m_operator; }
|
Token::Value getOperator() const { return m_operator; }
|
||||||
bool isPrefixOperation() const { return m_isPrefix; }
|
bool isPrefixOperation() const { return m_isPrefix; }
|
||||||
private:
|
private:
|
||||||
Token::Value m_operator;
|
Token::Value m_operator;
|
||||||
ptr<Expression> m_subExpression;
|
ASTPointer<Expression> m_subExpression;
|
||||||
bool m_isPrefix;
|
bool m_isPrefix;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BinaryOperation: public Expression
|
class BinaryOperation: public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BinaryOperation(Location const& _location, ptr<Expression> const& _left,
|
BinaryOperation(Location const& _location, ASTPointer<Expression> const& _left,
|
||||||
Token::Value _operator, ptr<Expression> const& _right)
|
Token::Value _operator, 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) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
Token::Value getOperator() const { return m_operator; }
|
Token::Value getOperator() const { return m_operator; }
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_left;
|
ASTPointer<Expression> m_left;
|
||||||
Token::Value m_operator;
|
Token::Value m_operator;
|
||||||
ptr<Expression> m_right;
|
ASTPointer<Expression> m_right;
|
||||||
|
|
||||||
ptr<Type> m_commonType;
|
std::shared_ptr<Type const> m_commonType;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Can be ordinary function call, type cast or struct construction.
|
/// Can be ordinary function call, type cast or struct construction.
|
||||||
class FunctionCall: public Expression
|
class FunctionCall: public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FunctionCall(Location const& _location, ptr<Expression> const& _expression,
|
FunctionCall(Location const& _location, ASTPointer<Expression> const& _expression,
|
||||||
std::vector<ptr<Expression>> const& _arguments)
|
std::vector<ASTPointer<Expression>> const& _arguments)
|
||||||
: Expression(_location), m_expression(_expression), m_arguments(_arguments) {}
|
: Expression(_location), m_expression(_expression), m_arguments(_arguments) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_expression;
|
ASTPointer<Expression> m_expression;
|
||||||
std::vector<ptr<Expression>> m_arguments;
|
std::vector<ASTPointer<Expression>> m_arguments;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MemberAccess: public Expression
|
class MemberAccess: public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemberAccess(Location const& _location, ptr<Expression> _expression,
|
MemberAccess(Location const& _location, ASTPointer<Expression> _expression,
|
||||||
ptr<ASTString> const& _memberName)
|
ASTPointer<ASTString> const& _memberName)
|
||||||
: Expression(_location), m_expression(_expression), m_memberName(_memberName) {}
|
: Expression(_location), m_expression(_expression), m_memberName(_memberName) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
const ASTString& getMemberName() const { return *m_memberName; }
|
const ASTString& getMemberName() const { return *m_memberName; }
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_expression;
|
ASTPointer<Expression> m_expression;
|
||||||
ptr<ASTString> m_memberName;
|
ASTPointer<ASTString> m_memberName;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IndexAccess: public Expression
|
class IndexAccess: public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IndexAccess(Location const& _location, ptr<Expression> const& _base,
|
IndexAccess(Location const& _location, ASTPointer<Expression> const& _base,
|
||||||
ptr<Expression> const& _index)
|
ASTPointer<Expression> const& _index)
|
||||||
: Expression(_location), m_base(_base), m_index(_index) {}
|
: Expression(_location), m_base(_base), m_index(_index) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_base;
|
ASTPointer<Expression> m_base;
|
||||||
ptr<Expression> m_index;
|
ASTPointer<Expression> m_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PrimaryExpression: public Expression
|
class PrimaryExpression: public Expression
|
||||||
@ -460,16 +461,16 @@ public:
|
|||||||
class Identifier: public PrimaryExpression
|
class Identifier: public PrimaryExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Identifier(Location const& _location, ptr<ASTString> const& _name)
|
Identifier(Location const& _location, ASTPointer<ASTString> const& _name)
|
||||||
: PrimaryExpression(_location), m_name(_name) {}
|
: PrimaryExpression(_location), m_name(_name) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
ASTString const& getName() const { return *m_name; }
|
ASTString const& getName() const { return *m_name; }
|
||||||
void setReferencedDeclaration(Declaration& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
|
void setReferencedDeclaration(Declaration& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
|
||||||
Declaration* getReferencedDeclaration() { return m_referencedDeclaration; }
|
Declaration* getReferencedDeclaration() { return m_referencedDeclaration; }
|
||||||
private:
|
private:
|
||||||
ptr<ASTString> m_name;
|
ASTPointer<ASTString> m_name;
|
||||||
|
|
||||||
//! Declaration the name refers to.
|
//! Declaration the name refers to.
|
||||||
Declaration* m_referencedDeclaration;
|
Declaration* m_referencedDeclaration;
|
||||||
@ -481,7 +482,7 @@ public:
|
|||||||
ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken)
|
ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken)
|
||||||
: PrimaryExpression(_location), m_typeToken(_typeToken) {}
|
: PrimaryExpression(_location), m_typeToken(_typeToken) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
Token::Value getTypeToken() const { return m_typeToken; }
|
Token::Value getTypeToken() const { return m_typeToken; }
|
||||||
private:
|
private:
|
||||||
@ -491,16 +492,16 @@ private:
|
|||||||
class Literal: public PrimaryExpression
|
class Literal: public PrimaryExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Literal(Location const& _location, Token::Value _token, ptr<ASTString> const& _value)
|
Literal(Location const& _location, Token::Value _token, ASTPointer<ASTString> const& _value)
|
||||||
: PrimaryExpression(_location), m_token(_token), m_value(_value) {}
|
: PrimaryExpression(_location), m_token(_token), m_value(_value) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual ptr<Type> checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
Token::Value getToken() const { return m_token; }
|
Token::Value getToken() const { return m_token; }
|
||||||
ASTString const& getValue() const { return *m_value; }
|
ASTString const& getValue() const { return *m_value; }
|
||||||
private:
|
private:
|
||||||
Token::Value m_token;
|
Token::Value m_token;
|
||||||
ptr<ASTString> m_value;
|
ASTPointer<ASTString> m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -69,7 +69,7 @@ class Literal;
|
|||||||
// not do reference counting but point to a special memory area that is completely released
|
// not do reference counting but point to a special memory area that is completely released
|
||||||
// explicitly.
|
// explicitly.
|
||||||
template <class T>
|
template <class T>
|
||||||
using ptr = std::shared_ptr<T>;
|
using ASTPointer = std::shared_ptr<T>;
|
||||||
|
|
||||||
using ASTString = std::string;
|
using ASTString = std::string;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ namespace dev
|
|||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
|
||||||
ASTPrinter::ASTPrinter(ptr<ASTNode> _ast, std::string const& _source)
|
ASTPrinter::ASTPrinter(ASTPointer<ASTNode> const& _ast, std::string const& _source)
|
||||||
: m_indentation(0), m_source(_source), m_ast(_ast)
|
: m_indentation(0), m_source(_source), m_ast(_ast)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class ASTPrinter: public ASTVisitor
|
|||||||
public:
|
public:
|
||||||
/// Create a printer for the given abstract syntax tree. If the source is specified,
|
/// Create a printer for the given abstract syntax tree. If the source is specified,
|
||||||
/// the corresponding parts of the source are printed with each node.
|
/// the corresponding parts of the source are printed with each node.
|
||||||
ASTPrinter(ptr<ASTNode> _ast, const std::string& _source = std::string());
|
ASTPrinter(ASTPointer<ASTNode> const& _ast, const std::string& _source = std::string());
|
||||||
/// Output the string representation of the AST to _stream.
|
/// Output the string representation of the AST to _stream.
|
||||||
void print(std::ostream& _stream);
|
void print(std::ostream& _stream);
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ private:
|
|||||||
|
|
||||||
int m_indentation;
|
int m_indentation;
|
||||||
std::string m_source;
|
std::string m_source;
|
||||||
ptr<ASTNode> m_ast;
|
ASTPointer<ASTNode> m_ast;
|
||||||
std::ostream* m_ostream;
|
std::ostream* m_ostream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,9 +42,9 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
|
|||||||
DeclarationRegistrationHelper registrar(m_scopes, _contract);
|
DeclarationRegistrationHelper registrar(m_scopes, _contract);
|
||||||
m_currentScope = &m_scopes[&_contract];
|
m_currentScope = &m_scopes[&_contract];
|
||||||
//@todo structs
|
//@todo structs
|
||||||
for (ptr<VariableDeclaration> const& variable: _contract.getStateVariables())
|
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
|
||||||
ReferencesResolver resolver(*variable, *this, nullptr);
|
ReferencesResolver resolver(*variable, *this, nullptr);
|
||||||
for (ptr<FunctionDefinition> const& function: _contract.getDefinedFunctions())
|
for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions())
|
||||||
{
|
{
|
||||||
m_currentScope = &m_scopes[function.get()];
|
m_currentScope = &m_scopes[function.get()];
|
||||||
ReferencesResolver referencesResolver(*function, *this,
|
ReferencesResolver referencesResolver(*function, *this,
|
||||||
@ -53,7 +53,7 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
|
|||||||
// First, the parameter types of all functions need to be resolved before we can check
|
// First, the parameter types of all functions need to be resolved before we can check
|
||||||
// the types, since it is possible to call functions that are only defined later
|
// the types, since it is possible to call functions that are only defined later
|
||||||
// in the source.
|
// in the source.
|
||||||
for (ptr<FunctionDefinition> const& function: _contract.getDefinedFunctions())
|
for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions())
|
||||||
{
|
{
|
||||||
m_currentScope = &m_scopes[function.get()];
|
m_currentScope = &m_scopes[function.get()];
|
||||||
function->getBody().checkTypeRequirements();
|
function->getBody().checkTypeRequirements();
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
#include <libsolidity/Scope.h>
|
#include <libsolidity/Scope.h>
|
||||||
|
128
Parser.cpp
128
Parser.cpp
@ -31,7 +31,7 @@ namespace dev
|
|||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
|
||||||
ptr<ContractDefinition> Parser::parse(std::shared_ptr<Scanner> const& _scanner)
|
ASTPointer<ContractDefinition> Parser::parse(std::shared_ptr<Scanner> const& _scanner)
|
||||||
{
|
{
|
||||||
m_scanner = _scanner;
|
m_scanner = _scanner;
|
||||||
return parseContractDefinition();
|
return parseContractDefinition();
|
||||||
@ -48,10 +48,10 @@ public:
|
|||||||
void markEndPosition() { m_location.end = m_parser.getEndPosition(); }
|
void markEndPosition() { m_location.end = m_parser.getEndPosition(); }
|
||||||
void setLocationEmpty() { m_location.end = m_location.start; }
|
void setLocationEmpty() { m_location.end = m_location.start; }
|
||||||
/// Set the end position to the one of the given node.
|
/// Set the end position to the one of the given node.
|
||||||
void setEndPositionFromNode(ptr<ASTNode> const& _node) { m_location.end = _node->getLocation().end; }
|
void setEndPositionFromNode(ASTPointer<ASTNode> const& _node) { m_location.end = _node->getLocation().end; }
|
||||||
|
|
||||||
template <class NodeType, typename... Args>
|
template <class NodeType, typename... Args>
|
||||||
ptr<NodeType> createNode(Args&& ... _args)
|
ASTPointer<NodeType> createNode(Args&& ... _args)
|
||||||
{
|
{
|
||||||
if (m_location.end < 0)
|
if (m_location.end < 0)
|
||||||
markEndPosition();
|
markEndPosition();
|
||||||
@ -74,15 +74,15 @@ int Parser::getEndPosition() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ptr<ContractDefinition> Parser::parseContractDefinition()
|
ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::CONTRACT);
|
expectToken(Token::CONTRACT);
|
||||||
ptr<ASTString> name = expectIdentifierToken();
|
ASTPointer<ASTString> name = expectIdentifierToken();
|
||||||
expectToken(Token::LBRACE);
|
expectToken(Token::LBRACE);
|
||||||
std::vector<ptr<StructDefinition>> structs;
|
std::vector<ASTPointer<StructDefinition>> structs;
|
||||||
std::vector<ptr<VariableDeclaration>> stateVariables;
|
std::vector<ASTPointer<VariableDeclaration>> stateVariables;
|
||||||
std::vector<ptr<FunctionDefinition>> functions;
|
std::vector<ASTPointer<FunctionDefinition>> functions;
|
||||||
bool visibilityIsPublic = true;
|
bool visibilityIsPublic = true;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -115,19 +115,19 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
|
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::FUNCTION);
|
expectToken(Token::FUNCTION);
|
||||||
ptr<ASTString> name(expectIdentifierToken());
|
ASTPointer<ASTString> name(expectIdentifierToken());
|
||||||
ptr<ParameterList> parameters(parseParameterList());
|
ASTPointer<ParameterList> parameters(parseParameterList());
|
||||||
bool isDeclaredConst = false;
|
bool isDeclaredConst = false;
|
||||||
if (m_scanner->getCurrentToken() == Token::CONST)
|
if (m_scanner->getCurrentToken() == Token::CONST)
|
||||||
{
|
{
|
||||||
isDeclaredConst = true;
|
isDeclaredConst = true;
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
ptr<ParameterList> returnParameters;
|
ASTPointer<ParameterList> returnParameters;
|
||||||
if (m_scanner->getCurrentToken() == Token::RETURNS)
|
if (m_scanner->getCurrentToken() == Token::RETURNS)
|
||||||
{
|
{
|
||||||
bool const permitEmptyParameterList = false;
|
bool const permitEmptyParameterList = false;
|
||||||
@ -139,20 +139,20 @@ ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
|||||||
// create an empty parameter list at a zero-length location
|
// create an empty parameter list at a zero-length location
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
nodeFactory.setLocationEmpty();
|
nodeFactory.setLocationEmpty();
|
||||||
returnParameters = nodeFactory.createNode<ParameterList>(std::vector<ptr<VariableDeclaration>>());
|
returnParameters = nodeFactory.createNode<ParameterList>(std::vector<ASTPointer<VariableDeclaration>>());
|
||||||
}
|
}
|
||||||
ptr<Block> block = parseBlock();
|
ASTPointer<Block> block = parseBlock();
|
||||||
nodeFactory.setEndPositionFromNode(block);
|
nodeFactory.setEndPositionFromNode(block);
|
||||||
return nodeFactory.createNode<FunctionDefinition>(name, _isPublic, parameters,
|
return nodeFactory.createNode<FunctionDefinition>(name, _isPublic, parameters,
|
||||||
isDeclaredConst, returnParameters, block);
|
isDeclaredConst, returnParameters, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<StructDefinition> Parser::parseStructDefinition()
|
ASTPointer<StructDefinition> Parser::parseStructDefinition()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::STRUCT);
|
expectToken(Token::STRUCT);
|
||||||
ptr<ASTString> name = expectIdentifierToken();
|
ASTPointer<ASTString> name = expectIdentifierToken();
|
||||||
std::vector<ptr<VariableDeclaration>> members;
|
std::vector<ASTPointer<VariableDeclaration>> members;
|
||||||
expectToken(Token::LBRACE);
|
expectToken(Token::LBRACE);
|
||||||
while (m_scanner->getCurrentToken() != Token::RBRACE)
|
while (m_scanner->getCurrentToken() != Token::RBRACE)
|
||||||
{
|
{
|
||||||
@ -165,17 +165,17 @@ ptr<StructDefinition> Parser::parseStructDefinition()
|
|||||||
return nodeFactory.createNode<StructDefinition>(name, members);
|
return nodeFactory.createNode<StructDefinition>(name, members);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<VariableDeclaration> Parser::parseVariableDeclaration(bool _allowVar)
|
ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(bool _allowVar)
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ptr<TypeName> type = parseTypeName(_allowVar);
|
ASTPointer<TypeName> type = parseTypeName(_allowVar);
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
return nodeFactory.createNode<VariableDeclaration>(type, expectIdentifierToken());
|
return nodeFactory.createNode<VariableDeclaration>(type, expectIdentifierToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<TypeName> Parser::parseTypeName(bool _allowVar)
|
ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
||||||
{
|
{
|
||||||
ptr<TypeName> type;
|
ASTPointer<TypeName> type;
|
||||||
Token::Value token = m_scanner->getCurrentToken();
|
Token::Value token = m_scanner->getCurrentToken();
|
||||||
if (Token::isElementaryTypeName(token))
|
if (Token::isElementaryTypeName(token))
|
||||||
{
|
{
|
||||||
@ -203,28 +203,28 @@ ptr<TypeName> Parser::parseTypeName(bool _allowVar)
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Mapping> Parser::parseMapping()
|
ASTPointer<Mapping> Parser::parseMapping()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::MAPPING);
|
expectToken(Token::MAPPING);
|
||||||
expectToken(Token::LPAREN);
|
expectToken(Token::LPAREN);
|
||||||
if (!Token::isElementaryTypeName(m_scanner->getCurrentToken()))
|
if (!Token::isElementaryTypeName(m_scanner->getCurrentToken()))
|
||||||
throwExpectationError("Expected elementary type name for mapping key type");
|
throwExpectationError("Expected elementary type name for mapping key type");
|
||||||
ptr<ElementaryTypeName> keyType;
|
ASTPointer<ElementaryTypeName> keyType;
|
||||||
keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(m_scanner->getCurrentToken());
|
keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(m_scanner->getCurrentToken());
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
expectToken(Token::ARROW);
|
expectToken(Token::ARROW);
|
||||||
bool const allowVar = false;
|
bool const allowVar = false;
|
||||||
ptr<TypeName> valueType = parseTypeName(allowVar);
|
ASTPointer<TypeName> valueType = parseTypeName(allowVar);
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RPAREN);
|
expectToken(Token::RPAREN);
|
||||||
return nodeFactory.createNode<Mapping>(keyType, valueType);
|
return nodeFactory.createNode<Mapping>(keyType, valueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<ParameterList> Parser::parseParameterList(bool _allowEmpty)
|
ASTPointer<ParameterList> Parser::parseParameterList(bool _allowEmpty)
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
std::vector<ptr<VariableDeclaration>> parameters;
|
std::vector<ASTPointer<VariableDeclaration>> parameters;
|
||||||
expectToken(Token::LPAREN);
|
expectToken(Token::LPAREN);
|
||||||
if (!_allowEmpty || m_scanner->getCurrentToken() != Token::RPAREN)
|
if (!_allowEmpty || m_scanner->getCurrentToken() != Token::RPAREN)
|
||||||
{
|
{
|
||||||
@ -241,11 +241,11 @@ ptr<ParameterList> Parser::parseParameterList(bool _allowEmpty)
|
|||||||
return nodeFactory.createNode<ParameterList>(parameters);
|
return nodeFactory.createNode<ParameterList>(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Block> Parser::parseBlock()
|
ASTPointer<Block> Parser::parseBlock()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::LBRACE);
|
expectToken(Token::LBRACE);
|
||||||
std::vector<ptr<Statement>> statements;
|
std::vector<ASTPointer<Statement>> statements;
|
||||||
while (m_scanner->getCurrentToken() != Token::RBRACE)
|
while (m_scanner->getCurrentToken() != Token::RBRACE)
|
||||||
statements.push_back(parseStatement());
|
statements.push_back(parseStatement());
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
@ -253,9 +253,9 @@ ptr<Block> Parser::parseBlock()
|
|||||||
return nodeFactory.createNode<Block>(statements);
|
return nodeFactory.createNode<Block>(statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Statement> Parser::parseStatement()
|
ASTPointer<Statement> Parser::parseStatement()
|
||||||
{
|
{
|
||||||
ptr<Statement> statement;
|
ASTPointer<Statement> statement;
|
||||||
switch (m_scanner->getCurrentToken())
|
switch (m_scanner->getCurrentToken())
|
||||||
{
|
{
|
||||||
case Token::IF:
|
case Token::IF:
|
||||||
@ -274,7 +274,7 @@ ptr<Statement> Parser::parseStatement()
|
|||||||
case Token::RETURN:
|
case Token::RETURN:
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ptr<Expression> expression;
|
ASTPointer<Expression> expression;
|
||||||
if (m_scanner->next() != Token::SEMICOLON)
|
if (m_scanner->next() != Token::SEMICOLON)
|
||||||
{
|
{
|
||||||
expression = parseExpression();
|
expression = parseExpression();
|
||||||
@ -301,15 +301,15 @@ ptr<Statement> Parser::parseStatement()
|
|||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<IfStatement> Parser::parseIfStatement()
|
ASTPointer<IfStatement> Parser::parseIfStatement()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::IF);
|
expectToken(Token::IF);
|
||||||
expectToken(Token::LPAREN);
|
expectToken(Token::LPAREN);
|
||||||
ptr<Expression> condition = parseExpression();
|
ASTPointer<Expression> condition = parseExpression();
|
||||||
expectToken(Token::RPAREN);
|
expectToken(Token::RPAREN);
|
||||||
ptr<Statement> trueBody = parseStatement();
|
ASTPointer<Statement> trueBody = parseStatement();
|
||||||
ptr<Statement> falseBody;
|
ASTPointer<Statement> falseBody;
|
||||||
if (m_scanner->getCurrentToken() == Token::ELSE)
|
if (m_scanner->getCurrentToken() == Token::ELSE)
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -321,24 +321,24 @@ ptr<IfStatement> Parser::parseIfStatement()
|
|||||||
return nodeFactory.createNode<IfStatement>(condition, trueBody, falseBody);
|
return nodeFactory.createNode<IfStatement>(condition, trueBody, falseBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<WhileStatement> Parser::parseWhileStatement()
|
ASTPointer<WhileStatement> Parser::parseWhileStatement()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::WHILE);
|
expectToken(Token::WHILE);
|
||||||
expectToken(Token::LPAREN);
|
expectToken(Token::LPAREN);
|
||||||
ptr<Expression> condition = parseExpression();
|
ASTPointer<Expression> condition = parseExpression();
|
||||||
expectToken(Token::RPAREN);
|
expectToken(Token::RPAREN);
|
||||||
ptr<Statement> body = parseStatement();
|
ASTPointer<Statement> body = parseStatement();
|
||||||
nodeFactory.setEndPositionFromNode(body);
|
nodeFactory.setEndPositionFromNode(body);
|
||||||
return nodeFactory.createNode<WhileStatement>(condition, body);
|
return nodeFactory.createNode<WhileStatement>(condition, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<VariableDefinition> Parser::parseVariableDefinition()
|
ASTPointer<VariableDefinition> Parser::parseVariableDefinition()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
bool const allowVar = true;
|
bool const allowVar = true;
|
||||||
ptr<VariableDeclaration> variable = parseVariableDeclaration(allowVar);
|
ASTPointer<VariableDeclaration> variable = parseVariableDeclaration(allowVar);
|
||||||
ptr<Expression> value;
|
ASTPointer<Expression> value;
|
||||||
if (m_scanner->getCurrentToken() == Token::ASSIGN)
|
if (m_scanner->getCurrentToken() == Token::ASSIGN)
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -350,22 +350,22 @@ ptr<VariableDefinition> Parser::parseVariableDefinition()
|
|||||||
return nodeFactory.createNode<VariableDefinition>(variable, value);
|
return nodeFactory.createNode<VariableDefinition>(variable, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Expression> Parser::parseExpression()
|
ASTPointer<Expression> Parser::parseExpression()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ptr<Expression> expression = parseBinaryExpression();
|
ASTPointer<Expression> expression = parseBinaryExpression();
|
||||||
if (!Token::isAssignmentOp(m_scanner->getCurrentToken()))
|
if (!Token::isAssignmentOp(m_scanner->getCurrentToken()))
|
||||||
return expression;
|
return expression;
|
||||||
Token::Value assignmentOperator = expectAssignmentOperator();
|
Token::Value assignmentOperator = expectAssignmentOperator();
|
||||||
ptr<Expression> rightHandSide = parseExpression();
|
ASTPointer<Expression> rightHandSide = parseExpression();
|
||||||
nodeFactory.setEndPositionFromNode(rightHandSide);
|
nodeFactory.setEndPositionFromNode(rightHandSide);
|
||||||
return nodeFactory.createNode<Assignment>(expression, assignmentOperator, rightHandSide);
|
return nodeFactory.createNode<Assignment>(expression, assignmentOperator, rightHandSide);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
ASTPointer<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ptr<Expression> expression = parseUnaryExpression();
|
ASTPointer<Expression> expression = parseUnaryExpression();
|
||||||
int precedence = Token::precedence(m_scanner->getCurrentToken());
|
int precedence = Token::precedence(m_scanner->getCurrentToken());
|
||||||
for (; precedence >= _minPrecedence; --precedence)
|
for (; precedence >= _minPrecedence; --precedence)
|
||||||
{
|
{
|
||||||
@ -373,7 +373,7 @@ ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
|||||||
{
|
{
|
||||||
Token::Value op = m_scanner->getCurrentToken();
|
Token::Value op = m_scanner->getCurrentToken();
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
ptr<Expression> right = parseBinaryExpression(precedence + 1);
|
ASTPointer<Expression> right = parseBinaryExpression(precedence + 1);
|
||||||
nodeFactory.setEndPositionFromNode(right);
|
nodeFactory.setEndPositionFromNode(right);
|
||||||
expression = nodeFactory.createNode<BinaryOperation>(expression, op, right);
|
expression = nodeFactory.createNode<BinaryOperation>(expression, op, right);
|
||||||
}
|
}
|
||||||
@ -381,7 +381,7 @@ ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
|||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Expression> Parser::parseUnaryExpression()
|
ASTPointer<Expression> Parser::parseUnaryExpression()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
Token::Value token = m_scanner->getCurrentToken();
|
Token::Value token = m_scanner->getCurrentToken();
|
||||||
@ -389,14 +389,14 @@ ptr<Expression> Parser::parseUnaryExpression()
|
|||||||
{
|
{
|
||||||
// prefix expression
|
// prefix expression
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
ptr<Expression> subExpression = parseUnaryExpression();
|
ASTPointer<Expression> subExpression = parseUnaryExpression();
|
||||||
nodeFactory.setEndPositionFromNode(subExpression);
|
nodeFactory.setEndPositionFromNode(subExpression);
|
||||||
return nodeFactory.createNode<UnaryOperation>(token, subExpression, true);
|
return nodeFactory.createNode<UnaryOperation>(token, subExpression, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// potential postfix expression
|
// potential postfix expression
|
||||||
ptr<Expression> subExpression = parseLeftHandSideExpression();
|
ASTPointer<Expression> subExpression = parseLeftHandSideExpression();
|
||||||
token = m_scanner->getCurrentToken();
|
token = m_scanner->getCurrentToken();
|
||||||
if (!Token::isCountOp(token))
|
if (!Token::isCountOp(token))
|
||||||
return subExpression;
|
return subExpression;
|
||||||
@ -406,10 +406,10 @@ ptr<Expression> Parser::parseUnaryExpression()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Expression> Parser::parseLeftHandSideExpression()
|
ASTPointer<Expression> Parser::parseLeftHandSideExpression()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ptr<Expression> expression = parsePrimaryExpression();
|
ASTPointer<Expression> expression = parsePrimaryExpression();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
switch (m_scanner->getCurrentToken())
|
switch (m_scanner->getCurrentToken())
|
||||||
@ -417,7 +417,7 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
|
|||||||
case Token::LBRACK:
|
case Token::LBRACK:
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
ptr<Expression> index = parseExpression();
|
ASTPointer<Expression> index = parseExpression();
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RBRACK);
|
expectToken(Token::RBRACK);
|
||||||
expression = nodeFactory.createNode<IndexAccess>(expression, index);
|
expression = nodeFactory.createNode<IndexAccess>(expression, index);
|
||||||
@ -433,7 +433,7 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
|
|||||||
case Token::LPAREN:
|
case Token::LPAREN:
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
std::vector<ptr<Expression>> arguments = parseFunctionCallArguments();
|
std::vector<ASTPointer<Expression>> arguments = parseFunctionCallArguments();
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RPAREN);
|
expectToken(Token::RPAREN);
|
||||||
expression = nodeFactory.createNode<FunctionCall>(expression, arguments);
|
expression = nodeFactory.createNode<FunctionCall>(expression, arguments);
|
||||||
@ -445,16 +445,16 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Expression> Parser::parsePrimaryExpression()
|
ASTPointer<Expression> Parser::parsePrimaryExpression()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
Token::Value token = m_scanner->getCurrentToken();
|
Token::Value token = m_scanner->getCurrentToken();
|
||||||
ptr<Expression> expression;
|
ASTPointer<Expression> expression;
|
||||||
switch (token)
|
switch (token)
|
||||||
{
|
{
|
||||||
case Token::TRUE_LITERAL:
|
case Token::TRUE_LITERAL:
|
||||||
case Token::FALSE_LITERAL:
|
case Token::FALSE_LITERAL:
|
||||||
expression = nodeFactory.createNode<Literal>(token, ptr<ASTString>());
|
expression = nodeFactory.createNode<Literal>(token, ASTPointer<ASTString>());
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
break;
|
break;
|
||||||
case Token::NUMBER:
|
case Token::NUMBER:
|
||||||
@ -469,7 +469,7 @@ ptr<Expression> Parser::parsePrimaryExpression()
|
|||||||
case Token::LPAREN:
|
case Token::LPAREN:
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
ptr<Expression> expression = parseExpression();
|
ASTPointer<Expression> expression = parseExpression();
|
||||||
expectToken(Token::RPAREN);
|
expectToken(Token::RPAREN);
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
@ -483,16 +483,16 @@ ptr<Expression> Parser::parsePrimaryExpression()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
throwExpectationError("Expected primary expression.");
|
throwExpectationError("Expected primary expression.");
|
||||||
return ptr<Expression>(); // this is not reached
|
return ASTPointer<Expression>(); // this is not reached
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ptr<Expression>> Parser::parseFunctionCallArguments()
|
std::vector<ASTPointer<Expression>> Parser::parseFunctionCallArguments()
|
||||||
{
|
{
|
||||||
std::vector<ptr<Expression>> arguments;
|
std::vector<ASTPointer<Expression>> arguments;
|
||||||
if (m_scanner->getCurrentToken() != Token::RPAREN)
|
if (m_scanner->getCurrentToken() != Token::RPAREN)
|
||||||
{
|
{
|
||||||
arguments.push_back(parseExpression());
|
arguments.push_back(parseExpression());
|
||||||
@ -521,16 +521,16 @@ Token::Value Parser::expectAssignmentOperator()
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<ASTString> Parser::expectIdentifierToken()
|
ASTPointer<ASTString> Parser::expectIdentifierToken()
|
||||||
{
|
{
|
||||||
if (m_scanner->getCurrentToken() != Token::IDENTIFIER)
|
if (m_scanner->getCurrentToken() != Token::IDENTIFIER)
|
||||||
throwExpectationError("Expected identifier");
|
throwExpectationError("Expected identifier");
|
||||||
return getLiteralAndAdvance();
|
return getLiteralAndAdvance();
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<ASTString> Parser::getLiteralAndAdvance()
|
ASTPointer<ASTString> Parser::getLiteralAndAdvance()
|
||||||
{
|
{
|
||||||
ptr<ASTString> identifier = std::make_shared<ASTString>(m_scanner->getCurrentLiteral());
|
ASTPointer<ASTString> identifier = std::make_shared<ASTString>(m_scanner->getCurrentLiteral());
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
42
Parser.h
42
Parser.h
@ -34,7 +34,7 @@ class Scanner;
|
|||||||
class Parser
|
class Parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ptr<ContractDefinition> parse(std::shared_ptr<Scanner> const& _scanner);
|
ASTPointer<ContractDefinition> parse(std::shared_ptr<Scanner> const& _scanner);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ASTNodeFactory;
|
class ASTNodeFactory;
|
||||||
@ -46,24 +46,24 @@ private:
|
|||||||
|
|
||||||
/// Parsing functions for the AST nodes
|
/// Parsing functions for the AST nodes
|
||||||
/// @{
|
/// @{
|
||||||
ptr<ContractDefinition> parseContractDefinition();
|
ASTPointer<ContractDefinition> parseContractDefinition();
|
||||||
ptr<FunctionDefinition> parseFunctionDefinition(bool _isPublic);
|
ASTPointer<FunctionDefinition> parseFunctionDefinition(bool _isPublic);
|
||||||
ptr<StructDefinition> parseStructDefinition();
|
ASTPointer<StructDefinition> parseStructDefinition();
|
||||||
ptr<VariableDeclaration> parseVariableDeclaration(bool _allowVar);
|
ASTPointer<VariableDeclaration> parseVariableDeclaration(bool _allowVar);
|
||||||
ptr<TypeName> parseTypeName(bool _allowVar);
|
ASTPointer<TypeName> parseTypeName(bool _allowVar);
|
||||||
ptr<Mapping> parseMapping();
|
ASTPointer<Mapping> parseMapping();
|
||||||
ptr<ParameterList> parseParameterList(bool _allowEmpty = true);
|
ASTPointer<ParameterList> parseParameterList(bool _allowEmpty = true);
|
||||||
ptr<Block> parseBlock();
|
ASTPointer<Block> parseBlock();
|
||||||
ptr<Statement> parseStatement();
|
ASTPointer<Statement> parseStatement();
|
||||||
ptr<IfStatement> parseIfStatement();
|
ASTPointer<IfStatement> parseIfStatement();
|
||||||
ptr<WhileStatement> parseWhileStatement();
|
ASTPointer<WhileStatement> parseWhileStatement();
|
||||||
ptr<VariableDefinition> parseVariableDefinition();
|
ASTPointer<VariableDefinition> parseVariableDefinition();
|
||||||
ptr<Expression> parseExpression();
|
ASTPointer<Expression> parseExpression();
|
||||||
ptr<Expression> parseBinaryExpression(int _minPrecedence = 4);
|
ASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4);
|
||||||
ptr<Expression> parseUnaryExpression();
|
ASTPointer<Expression> parseUnaryExpression();
|
||||||
ptr<Expression> parseLeftHandSideExpression();
|
ASTPointer<Expression> parseLeftHandSideExpression();
|
||||||
ptr<Expression> parsePrimaryExpression();
|
ASTPointer<Expression> parsePrimaryExpression();
|
||||||
std::vector<ptr<Expression>> parseFunctionCallArguments();
|
std::vector<ASTPointer<Expression>> parseFunctionCallArguments();
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// Helper functions
|
/// Helper functions
|
||||||
@ -71,8 +71,8 @@ private:
|
|||||||
/// 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);
|
void expectToken(Token::Value _value);
|
||||||
Token::Value expectAssignmentOperator();
|
Token::Value expectAssignmentOperator();
|
||||||
ptr<ASTString> expectIdentifierToken();
|
ASTPointer<ASTString> expectIdentifierToken();
|
||||||
ptr<ASTString> getLiteralAndAdvance();
|
ASTPointer<ASTString> getLiteralAndAdvance();
|
||||||
void throwExpectationError(std::string const& _description);
|
void throwExpectationError(std::string const& _description);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
29
Scanner.cpp
29
Scanner.cpp
@ -81,12 +81,15 @@ bool IsIdentifierPart(char c)
|
|||||||
|
|
||||||
int HexValue(char c)
|
int HexValue(char c)
|
||||||
{
|
{
|
||||||
if (c >= '0' && c <= '9') return c - '0';
|
if (c >= '0' && c <= '9')
|
||||||
else if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
return c - '0';
|
||||||
else if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
else if (c >= 'a' && c <= 'f')
|
||||||
|
return c - 'a' + 10;
|
||||||
|
else if (c >= 'A' && c <= 'F')
|
||||||
|
return c - 'A' + 10;
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
}
|
} // end anonymous namespace
|
||||||
|
|
||||||
Scanner::Scanner(CharStream const& _source)
|
Scanner::Scanner(CharStream const& _source)
|
||||||
{
|
{
|
||||||
@ -409,13 +412,15 @@ bool Scanner::scanEscape()
|
|||||||
c = '\t';
|
c = '\t';
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
if (!scanHexNumber(c, 4)) return false;
|
if (!scanHexNumber(c, 4))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
c = '\v';
|
c = '\v';
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
if (!scanHexNumber(c, 2)) return false;
|
if (!scanHexNumber(c, 2))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,9 +617,8 @@ case ch:
|
|||||||
int const keyword_length = sizeof(keyword) - 1; \
|
int const keyword_length = sizeof(keyword) - 1; \
|
||||||
BOOST_STATIC_ASSERT(keyword_length >= kMinLength); \
|
BOOST_STATIC_ASSERT(keyword_length >= kMinLength); \
|
||||||
BOOST_STATIC_ASSERT(keyword_length <= kMaxLength); \
|
BOOST_STATIC_ASSERT(keyword_length <= kMaxLength); \
|
||||||
if (input == keyword) { \
|
if (input == keyword) \
|
||||||
return token; \
|
return token; \
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD)
|
KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD)
|
||||||
}
|
}
|
||||||
@ -635,9 +639,11 @@ Token::Value Scanner::scanIdentifierOrKeyword()
|
|||||||
|
|
||||||
char CharStream::advanceAndGet()
|
char CharStream::advanceAndGet()
|
||||||
{
|
{
|
||||||
if (isPastEndOfInput()) return 0;
|
if (isPastEndOfInput())
|
||||||
|
return 0;
|
||||||
++m_pos;
|
++m_pos;
|
||||||
if (isPastEndOfInput()) return 0;
|
if (isPastEndOfInput())
|
||||||
|
return 0;
|
||||||
return get();
|
return get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +659,8 @@ std::string CharStream::getLineAtPosition(int _position) const
|
|||||||
// if _position points to \n, it returns the line before the \n
|
// if _position points to \n, it returns the line before the \n
|
||||||
using size_type = std::string::size_type;
|
using size_type = std::string::size_type;
|
||||||
size_type searchStart = std::min<size_type>(m_source.size(), _position);
|
size_type searchStart = std::min<size_type>(m_source.size(), _position);
|
||||||
if (searchStart > 0) searchStart--;
|
if (searchStart > 0)
|
||||||
|
searchStart--;
|
||||||
size_type lineStart = m_source.rfind('\n', searchStart);
|
size_type lineStart = m_source.rfind('\n', searchStart);
|
||||||
if (lineStart == std::string::npos)
|
if (lineStart == std::string::npos)
|
||||||
lineStart = 0;
|
lineStart = 0;
|
||||||
|
1
Scope.h
1
Scope.h
@ -23,7 +23,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
#include <libsolidity/ASTForward.h>
|
#include <libsolidity/ASTForward.h>
|
||||||
|
16
Types.cpp
16
Types.cpp
@ -28,7 +28,7 @@ namespace dev
|
|||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
|
||||||
ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
|
std::shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
|
||||||
{
|
{
|
||||||
if (Token::INT <= _typeToken && _typeToken <= Token::HASH256)
|
if (Token::INT <= _typeToken && _typeToken <= Token::HASH256)
|
||||||
{
|
{
|
||||||
@ -52,18 +52,18 @@ ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
|
|||||||
BOOST_ASSERT(false); // @todo add other tyes
|
BOOST_ASSERT(false); // @todo add other tyes
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
|
std::shared_ptr<Type> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
|
||||||
{
|
{
|
||||||
return std::make_shared<StructType>(*_typeName.getReferencedStruct());
|
return std::make_shared<StructType>(*_typeName.getReferencedStruct());
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Type::fromMapping(Mapping const&)
|
std::shared_ptr<Type> Type::fromMapping(Mapping const&)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(false); //@todo not yet implemented
|
BOOST_ASSERT(false); //@todo not yet implemented
|
||||||
return ptr<Type>();
|
return std::shared_ptr<Type>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<Type> Type::forLiteral(Literal const& _literal)
|
std::shared_ptr<Type> Type::forLiteral(Literal const& _literal)
|
||||||
{
|
{
|
||||||
switch (_literal.getToken())
|
switch (_literal.getToken())
|
||||||
{
|
{
|
||||||
@ -73,13 +73,13 @@ ptr<Type> Type::forLiteral(Literal const& _literal)
|
|||||||
case Token::NUMBER:
|
case Token::NUMBER:
|
||||||
return IntegerType::smallestTypeForLiteral(_literal.getValue());
|
return IntegerType::smallestTypeForLiteral(_literal.getValue());
|
||||||
case Token::STRING_LITERAL:
|
case Token::STRING_LITERAL:
|
||||||
return ptr<Type>(); // @todo
|
return std::shared_ptr<Type>(); // @todo
|
||||||
default:
|
default:
|
||||||
return ptr<Type>();
|
return std::shared_ptr<Type>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<IntegerType> IntegerType::smallestTypeForLiteral(const std::string&)
|
std::shared_ptr<IntegerType> IntegerType::smallestTypeForLiteral(std::string const&)
|
||||||
{
|
{
|
||||||
//@todo
|
//@todo
|
||||||
return std::make_shared<IntegerType>(256, Modifier::UNSIGNED);
|
return std::make_shared<IntegerType>(256, Modifier::UNSIGNED);
|
||||||
|
35
Types.h
35
Types.h
@ -26,7 +26,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
#include <libsolidity/ASTForward.h>
|
||||||
#include <libsolidity/Token.h>
|
#include <libsolidity/Token.h>
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
@ -34,18 +34,6 @@ namespace dev
|
|||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
|
||||||
// AST forward declarations
|
|
||||||
class ContractDefinition;
|
|
||||||
class FunctionDefinition;
|
|
||||||
class StructDefinition;
|
|
||||||
class Literal;
|
|
||||||
class ElementaryTypeName;
|
|
||||||
class UserDefinedTypeName;
|
|
||||||
class Mapping;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using ptr = std::shared_ptr<T>;
|
|
||||||
|
|
||||||
// @todo realMxN, string<N>, mapping
|
// @todo realMxN, string<N>, mapping
|
||||||
|
|
||||||
class Type: private boost::noncopyable
|
class Type: private boost::noncopyable
|
||||||
@ -57,11 +45,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! factory functions that convert an AST TypeName to a Type.
|
//! factory functions that convert an AST TypeName to a Type.
|
||||||
static ptr<Type> fromElementaryTypeName(Token::Value _typeToken);
|
static std::shared_ptr<Type> fromElementaryTypeName(Token::Value _typeToken);
|
||||||
static ptr<Type> fromUserDefinedTypeName(UserDefinedTypeName const& _typeName);
|
static std::shared_ptr<Type> fromUserDefinedTypeName(UserDefinedTypeName const& _typeName);
|
||||||
static ptr<Type> fromMapping(Mapping const& _typeName);
|
static std::shared_ptr<Type> fromMapping(Mapping const& _typeName);
|
||||||
|
|
||||||
static ptr<Type> forLiteral(Literal const& _literal);
|
static std::shared_ptr<Type> forLiteral(Literal const& _literal);
|
||||||
|
|
||||||
virtual Category getCategory() const = 0;
|
virtual Category getCategory() const = 0;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const&) const { return false; }
|
virtual bool isImplicitlyConvertibleTo(Type const&) const { return false; }
|
||||||
@ -82,7 +70,7 @@ public:
|
|||||||
};
|
};
|
||||||
virtual Category getCategory() const { return Category::INTEGER; }
|
virtual Category getCategory() const { return Category::INTEGER; }
|
||||||
|
|
||||||
static ptr<IntegerType> smallestTypeForLiteral(std::string const& _literal);
|
static std::shared_ptr<IntegerType> smallestTypeForLiteral(std::string const& _literal);
|
||||||
|
|
||||||
explicit IntegerType(int _bits, Modifier _modifier = Modifier::UNSIGNED);
|
explicit IntegerType(int _bits, Modifier _modifier = Modifier::UNSIGNED);
|
||||||
|
|
||||||
@ -95,6 +83,7 @@ public:
|
|||||||
bool isHash() const { return m_modifier == Modifier::HASH || m_modifier == Modifier::ADDRESS; }
|
bool isHash() const { return m_modifier == Modifier::HASH || m_modifier == Modifier::ADDRESS; }
|
||||||
bool isAddress() const { return m_modifier == Modifier::ADDRESS; }
|
bool isAddress() const { return m_modifier == Modifier::ADDRESS; }
|
||||||
int isSigned() const { return m_modifier == Modifier::SIGNED; }
|
int isSigned() const { return m_modifier == Modifier::SIGNED; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_bits;
|
int m_bits;
|
||||||
Modifier m_modifier;
|
Modifier m_modifier;
|
||||||
@ -125,6 +114,7 @@ public:
|
|||||||
virtual Category getCategory() const { return Category::CONTRACT; }
|
virtual Category getCategory() const { return Category::CONTRACT; }
|
||||||
ContractType(ContractDefinition const& _contract): m_contract(_contract) {}
|
ContractType(ContractDefinition const& _contract): m_contract(_contract) {}
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ContractDefinition const& m_contract;
|
ContractDefinition const& m_contract;
|
||||||
};
|
};
|
||||||
@ -139,6 +129,7 @@ public:
|
|||||||
{
|
{
|
||||||
return _operator == Token::DELETE;
|
return _operator == Token::DELETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StructDefinition const& m_struct;
|
StructDefinition const& m_struct;
|
||||||
};
|
};
|
||||||
@ -150,6 +141,7 @@ public:
|
|||||||
FunctionType(FunctionDefinition const& _function): m_function(_function) {}
|
FunctionType(FunctionDefinition const& _function): m_function(_function) {}
|
||||||
|
|
||||||
FunctionDefinition const& getFunction() const { return m_function; }
|
FunctionDefinition const& getFunction() const { return m_function; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FunctionDefinition const& m_function;
|
FunctionDefinition const& m_function;
|
||||||
};
|
};
|
||||||
@ -175,11 +167,12 @@ class TypeType: public Type
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Category getCategory() const { return Category::TYPE; }
|
virtual Category getCategory() const { return Category::TYPE; }
|
||||||
TypeType(ptr<Type> const& _actualType): m_actualType(_actualType) {}
|
TypeType(std::shared_ptr<Type const> const& _actualType): m_actualType(_actualType) {}
|
||||||
|
|
||||||
|
std::shared_ptr<Type const> const& getActualType() const { return m_actualType; }
|
||||||
|
|
||||||
ptr<Type> const& getActualType() { return m_actualType; }
|
|
||||||
private:
|
private:
|
||||||
ptr<Type> m_actualType;
|
std::shared_ptr<Type const> m_actualType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user