Browse Source

Pointer type cleanup: Use ASTPointer only for AST nodes and shared_ptr for type

pointer.
cl-refactor
Christian 10 years ago
parent
commit
fa22722e0e
  1. 86
      libsolidity/AST.cpp
  2. 217
      libsolidity/AST.h
  3. 2
      libsolidity/ASTForward.h
  4. 2
      libsolidity/ASTPrinter.cpp
  5. 4
      libsolidity/ASTPrinter.h
  6. 6
      libsolidity/NameAndTypeResolver.cpp
  7. 1
      libsolidity/NameAndTypeResolver.h
  8. 172
      libsolidity/Parser.cpp
  9. 42
      libsolidity/Parser.h
  10. 31
      libsolidity/Scanner.cpp
  11. 1
      libsolidity/Scope.h
  12. 16
      libsolidity/Types.cpp
  13. 35
      libsolidity/Types.h
  14. 6
      solc/main.cpp
  15. 2
      test/solidityNameAndTypeResolution.cpp
  16. 2
      test/solidityParser.cpp

86
libsolidity/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
libsolidity/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;
}; };
/// @} /// @}

2
libsolidity/ASTForward.h

@ -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;

2
libsolidity/ASTPrinter.cpp

@ -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)
{ {
} }

4
libsolidity/ASTPrinter.h

@ -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;
}; };

6
libsolidity/NameAndTypeResolver.cpp

@ -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();

1
libsolidity/NameAndTypeResolver.h

@ -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>

172
libsolidity/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,38 +406,38 @@ 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())
{ {
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);
} }
break; break;
case Token::PERIOD: case Token::PERIOD:
{ {
m_scanner->next(); m_scanner->next();
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken()); expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
} }
break; break;
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);
} }
break; break;
default: default:
return expression; return expression;
@ -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:
@ -467,12 +467,12 @@ ptr<Expression> Parser::parsePrimaryExpression()
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance()); expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());
break; break;
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;
} }
default: default:
if (Token::isElementaryTypeName(token)) if (Token::isElementaryTypeName(token))
{ {
@ -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
libsolidity/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);
/// @} /// @}

31
libsolidity/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
libsolidity/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
libsolidity/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
libsolidity/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;
}; };

6
solc/main.cpp

@ -15,9 +15,9 @@ namespace dev
namespace solidity namespace solidity
{ {
ptr<ContractDefinition> parseAST(std::string const& _source) ASTPointer<ContractDefinition> parseAST(std::string const& _source)
{ {
ptr<Scanner> scanner = std::make_shared<Scanner>(CharStream(_source)); ASTPointer<Scanner> scanner = std::make_shared<Scanner>(CharStream(_source));
Parser parser; Parser parser;
return parser.parse(scanner); return parser.parse(scanner);
} }
@ -73,7 +73,7 @@ int main(int argc, char** argv)
} }
std::cout << "Parsing..." << std::endl; std::cout << "Parsing..." << std::endl;
// @todo catch exception // @todo catch exception
dev::solidity::ptr<dev::solidity::ContractDefinition> ast = dev::solidity::parseAST(src); dev::solidity::ASTPointer<dev::solidity::ContractDefinition> ast = dev::solidity::parseAST(src);
std::cout << "Syntax tree for the contract:" << std::endl; std::cout << "Syntax tree for the contract:" << std::endl;
dev::solidity::ASTPrinter printer(ast, src); dev::solidity::ASTPrinter printer(ast, src);
printer.print(std::cout); printer.print(std::cout);

2
test/solidityNameAndTypeResolution.cpp

@ -41,7 +41,7 @@ namespace
void parseTextAndResolveNames(const std::string& _source) void parseTextAndResolveNames(const std::string& _source)
{ {
Parser parser; Parser parser;
ptr<ContractDefinition> contract = parser.parse( ASTPointer<ContractDefinition> contract = parser.parse(
std::make_shared<Scanner>(CharStream(_source))); std::make_shared<Scanner>(CharStream(_source)));
NameAndTypeResolver resolver; NameAndTypeResolver resolver;
resolver.resolveNamesAndTypes(*contract); resolver.resolveNamesAndTypes(*contract);

2
test/solidityParser.cpp

@ -37,7 +37,7 @@ namespace test
namespace namespace
{ {
ptr<ASTNode> parseText(const std::string& _source) ASTPointer<ASTNode> parseText(const std::string& _source)
{ {
Parser parser; Parser parser;
return parser.parse(std::make_shared<Scanner>(CharStream(_source))); return parser.parse(std::make_shared<Scanner>(CharStream(_source)));

Loading…
Cancel
Save