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

pointer.
This commit is contained in:
Christian 2014-10-20 14:00:37 +02:00
parent f0c334670d
commit be885dc3cf
13 changed files with 302 additions and 313 deletions

86
AST.cpp
View File

@ -250,46 +250,42 @@ void Literal::accept(ASTVisitor& _visitor)
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 "
"to expected type."));
//@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();
return ptr<Type>();
}
ptr<Type> IfStatement::checkTypeRequirements()
void IfStatement::checkTypeRequirements()
{
expectType(*m_condition, BoolType());
m_trueBody->checkTypeRequirements();
if (m_falseBody)
m_falseBody->checkTypeRequirements();
return ptr<Type>();
}
ptr<Type> WhileStatement::checkTypeRequirements()
void WhileStatement::checkTypeRequirements()
{
expectType(*m_condition, BoolType());
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);
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,
// but for now, we only allow one return parameter
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
// setsthe type.
@ -313,17 +308,20 @@ ptr<Type> VariableDefinition::checkTypeRequirements()
if (m_variable->getType())
expectType(*m_value, *m_variable->getType());
else
{
// 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
// 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();
if (m_assigmentOperator != Token::ASSIGN)
{
@ -331,19 +329,18 @@ ptr<Type> Assignment::checkTypeRequirements()
if (!m_type->acceptsBinaryOperator(Token::AssignmentToBinaryOp(m_assigmentOperator)))
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
m_type = m_subExpression->checkTypeRequirements();
m_subExpression->checkTypeRequirements();
m_type = m_subExpression->getType();
if (m_type->acceptsUnaryOperator(m_operator))
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_left->checkTypeRequirements();
@ -362,19 +359,18 @@ ptr<Type> BinaryOperation::checkTypeRequirements()
if (!m_commonType->acceptsBinaryOperator(m_operator))
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type."));
}
return m_type;
}
ptr<Type> FunctionCall::checkTypeRequirements()
void FunctionCall::checkTypeRequirements()
{
m_expression->checkTypeRequirements();
for (ptr<Expression> const& argument: m_arguments)
for (ASTPointer<Expression> const& argument: m_arguments)
argument->checkTypeRequirements();
ptr<Type> expressionType = m_expression->getType();
Type::Category const category = expressionType->getCategory();
Type const& expressionType = *m_expression->getType();
Type::Category const category = expressionType.getCategory();
if (category == Type::Category::TYPE)
{
TypeType* type = dynamic_cast<TypeType*>(expressionType.get());
TypeType const* type = dynamic_cast<TypeType const*>(&expressionType);
BOOST_ASSERT(type != nullptr);
//@todo for structs, we have to check the number of arguments to be equal to the
// 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
// and then ask if that is implicitly convertible to the struct represented by the
// function parameters
FunctionType* function = dynamic_cast<FunctionType*>(expressionType.get());
FunctionType const* function = dynamic_cast<FunctionType const*>(&expressionType);
BOOST_ASSERT(function != nullptr);
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())
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Wrong argument count for "
"function call."));
@ -413,24 +409,21 @@ ptr<Type> FunctionCall::checkTypeRequirements()
{
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
// m_type = ;
return m_type;
}
ptr<Type> IndexAccess::checkTypeRequirements()
void IndexAccess::checkTypeRequirements()
{
BOOST_ASSERT(false); // not yet implemented
// m_type = ;
return m_type;
}
ptr<Type> Identifier::checkTypeRequirements()
void Identifier::checkTypeRequirements()
{
BOOST_ASSERT(m_referencedDeclaration != nullptr);
//@todo these dynamic casts here are not really nice...
@ -444,11 +437,11 @@ ptr<Type> Identifier::checkTypeRequirements()
VariableDeclaration* variable = dynamic_cast<VariableDeclaration*>(m_referencedDeclaration);
if (variable != nullptr)
{
if (variable->getType().get() == nullptr)
if (!variable->getType())
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Variable referenced before type "
"could be determined."));
m_type = variable->getType();
return m_type;
return;
}
//@todo can we unify these with TypeName::toType()?
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
m_type = std::make_shared<TypeType>(std::make_shared<StructType>(*structDef));
return m_type;
return;
}
FunctionDefinition* functionDef = dynamic_cast<FunctionDefinition*>(m_referencedDeclaration);
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
// conversion.
m_type = std::make_shared<FunctionType>(*functionDef);
return m_type;
return;
}
ContractDefinition* contractDef = dynamic_cast<ContractDefinition*>(m_referencedDeclaration);
if (contractDef != nullptr)
{
m_type = std::make_shared<TypeType>(std::make_shared<ContractType>(*contractDef));
return m_type;
return;
}
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));
return m_type;
}
ptr<Type> Literal::checkTypeRequirements()
void Literal::checkTypeRequirements()
{
m_type = Type::forLiteral(*this);
return m_type;
}
}

217
AST.h
View File

@ -51,9 +51,9 @@ public:
virtual void accept(ASTVisitor& _visitor) = 0;
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);
}
@ -65,22 +65,22 @@ private:
class Declaration: public ASTNode
{
public:
Declaration(Location const& _location, ptr<ASTString> const& _name)
Declaration(Location const& _location, ASTPointer<ASTString> const& _name)
: ASTNode(_location), m_name(_name) {}
const ASTString& getName() const { return *m_name; }
private:
ptr<ASTString> m_name;
ASTPointer<ASTString> m_name;
};
class ContractDefinition: public Declaration
{
public:
ContractDefinition(Location const& _location,
ptr<ASTString> const& _name,
std::vector<ptr<StructDefinition>> const& _definedStructs,
std::vector<ptr<VariableDeclaration>> const& _stateVariables,
std::vector<ptr<FunctionDefinition>> const& _definedFunctions)
ASTPointer<ASTString> const& _name,
std::vector<ASTPointer<StructDefinition>> const& _definedStructs,
std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables,
std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions)
: Declaration(_location, _name),
m_definedStructs(_definedStructs),
m_stateVariables(_stateVariables),
@ -89,26 +89,26 @@ public:
virtual void accept(ASTVisitor& _visitor) override;
std::vector<ptr<StructDefinition>> const& getDefinedStructs() { return m_definedStructs; }
std::vector<ptr<VariableDeclaration>> const& getStateVariables() { return m_stateVariables; }
std::vector<ptr<FunctionDefinition>> const& getDefinedFunctions() { return m_definedFunctions; }
std::vector<ASTPointer<StructDefinition>> const& getDefinedStructs() { return m_definedStructs; }
std::vector<ASTPointer<VariableDeclaration>> const& getStateVariables() { return m_stateVariables; }
std::vector<ASTPointer<FunctionDefinition>> const& getDefinedFunctions() { return m_definedFunctions; }
private:
std::vector<ptr<StructDefinition>> m_definedStructs;
std::vector<ptr<VariableDeclaration>> m_stateVariables;
std::vector<ptr<FunctionDefinition>> m_definedFunctions;
std::vector<ASTPointer<StructDefinition>> m_definedStructs;
std::vector<ASTPointer<VariableDeclaration>> m_stateVariables;
std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions;
};
class StructDefinition: public Declaration
{
public:
StructDefinition(Location const& _location,
ptr<ASTString> const& _name,
std::vector<ptr<VariableDeclaration>> const& _members)
ASTPointer<ASTString> const& _name,
std::vector<ASTPointer<VariableDeclaration>> const& _members)
: Declaration(_location, _name), m_members(_members) {}
virtual void accept(ASTVisitor& _visitor) override;
private:
std::vector<ptr<VariableDeclaration>> m_members;
std::vector<ASTPointer<VariableDeclaration>> m_members;
};
/// Used as function parameter list and return list
@ -117,23 +117,23 @@ private:
class ParameterList: public ASTNode
{
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) {}
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:
std::vector<ptr<VariableDeclaration>> m_parameters;
std::vector<ASTPointer<VariableDeclaration>> m_parameters;
};
class FunctionDefinition: public Declaration
{
public:
FunctionDefinition(Location const& _location, ptr<ASTString> const& _name, bool _isPublic,
ptr<ParameterList> const& _parameters,
FunctionDefinition(Location const& _location, ASTPointer<ASTString> const& _name, bool _isPublic,
ASTPointer<ParameterList> const& _parameters,
bool _isDeclaredConst,
ptr<ParameterList> const& _returnParameters,
ptr<Block> const& _body)
ASTPointer<ParameterList> const& _returnParameters,
ASTPointer<Block> const& _body)
: Declaration(_location, _name), m_isPublic(_isPublic), m_parameters(_parameters),
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters),
m_body(_body) {}
@ -141,23 +141,23 @@ public:
bool isPublic() const { return m_isPublic; }
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; }
ptr<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
Block& getBody() { return *m_body; }
private:
bool m_isPublic;
ptr<ParameterList> m_parameters;
ASTPointer<ParameterList> m_parameters;
bool m_isDeclaredConst;
ptr<ParameterList> m_returnParameters;
ptr<Block> m_body;
ASTPointer<ParameterList> m_returnParameters;
ASTPointer<Block> m_body;
};
class VariableDeclaration: public Declaration
{
public:
VariableDeclaration(Location const& _location, ptr<TypeName> const& _type,
ptr<ASTString> const& _name)
VariableDeclaration(Location const& _location, ASTPointer<TypeName> const& _type,
ASTPointer<ASTString> const& _name)
: Declaration(_location, _name), m_typeName(_type) {}
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
//! declared and there is no assignment to the variable that fixes the type.
ptr<Type> const& getType() const { return m_type; }
void setType(ptr<Type> const& _type) { m_type = _type; }
std::shared_ptr<Type const> const& getType() const { return m_type; }
void setType(std::shared_ptr<Type const> const& _type) { m_type = _type; }
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
@ -183,7 +183,7 @@ public:
explicit TypeName(Location const& _location): ASTNode(_location) {}
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
@ -193,7 +193,7 @@ public:
explicit ElementaryTypeName(Location const& _location, Token::Value _type)
: TypeName(_location), m_type(_type) {}
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; }
private:
@ -203,16 +203,16 @@ private:
class UserDefinedTypeName: public TypeName
{
public:
UserDefinedTypeName(Location const& _location, ptr<ASTString> const& _name)
UserDefinedTypeName(Location const& _location, ASTPointer<ASTString> const& _name)
: TypeName(_location), m_name(_name) {}
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; }
void setReferencedStruct(StructDefinition& _referencedStruct) { m_referencedStruct = &_referencedStruct; }
StructDefinition const* getReferencedStruct() const { return m_referencedStruct; }
private:
ptr<ASTString> m_name;
ASTPointer<ASTString> m_name;
StructDefinition* m_referencedStruct;
};
@ -220,14 +220,14 @@ private:
class Mapping: public TypeName
{
public:
Mapping(Location const& _location, ptr<ElementaryTypeName> const& _keyType,
ptr<TypeName> const& _valueType)
Mapping(Location const& _location, ASTPointer<ElementaryTypeName> const& _keyType,
ASTPointer<TypeName> const& _valueType)
: TypeName(_location), m_keyType(_keyType), m_valueType(_valueType) {}
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:
ptr<ElementaryTypeName> m_keyType;
ptr<TypeName> m_valueType;
ASTPointer<ElementaryTypeName> m_keyType;
ASTPointer<TypeName> m_valueType;
};
/// @}
@ -244,7 +244,7 @@ public:
//! 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
//! statements, returns the empty pointer.
virtual ptr<Type> checkTypeRequirements() = 0;
virtual void checkTypeRequirements() = 0;
protected:
//! Check that the inferred type for _expression is _expectedType or at least implicitly
//! convertible to _expectedType. If not, throw exception.
@ -254,28 +254,28 @@ protected:
class Block: public Statement
{
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) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
private:
std::vector<ptr<Statement>> m_statements;
std::vector<ASTPointer<Statement>> m_statements;
};
class IfStatement: public Statement
{
public:
IfStatement(Location const& _location, ptr<Expression> const& _condition,
ptr<Statement> const& _trueBody, ptr<Statement> const& _falseBody)
IfStatement(Location const& _location, ASTPointer<Expression> const& _condition,
ASTPointer<Statement> const& _trueBody, ASTPointer<Statement> const& _falseBody)
: Statement(_location), m_condition(_condition),
m_trueBody(_trueBody), m_falseBody(_falseBody) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
private:
ptr<Expression> m_condition;
ptr<Statement> m_trueBody;
ptr<Statement> m_falseBody; //< "else" part, optional
ASTPointer<Expression> m_condition;
ASTPointer<Statement> m_trueBody;
ASTPointer<Statement> m_falseBody; //< "else" part, optional
};
class BreakableStatement: public Statement
@ -288,14 +288,14 @@ public:
class WhileStatement: public BreakableStatement
{
public:
WhileStatement(Location const& _location, ptr<Expression> const& _condition,
ptr<Statement> const& _body)
WhileStatement(Location const& _location, ASTPointer<Expression> const& _condition,
ASTPointer<Statement> const& _body)
: BreakableStatement(_location), m_condition(_condition), m_body(_body) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
private:
ptr<Expression> m_condition;
ptr<Statement> m_body;
ASTPointer<Expression> m_condition;
ASTPointer<Statement> m_body;
};
class Continue: public Statement
@ -303,7 +303,7 @@ class Continue: public Statement
public:
Continue(Location const& _location): Statement(_location) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
};
class Break: public Statement
@ -311,20 +311,20 @@ class Break: public Statement
public:
Break(Location const& _location): Statement(_location) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
};
class Return: public Statement
{
public:
Return(Location const& _location, ptr<Expression> _expression)
Return(Location const& _location, ASTPointer<Expression> _expression)
: Statement(_location), m_expression(_expression) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; }
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
};
@ -332,24 +332,25 @@ private:
class VariableDefinition: public Statement
{
public:
VariableDefinition(Location const& _location, ptr<VariableDeclaration> _variable,
ptr<Expression> _value)
VariableDefinition(Location const& _location, ASTPointer<VariableDeclaration> _variable,
ASTPointer<Expression> _value)
: Statement(_location), m_variable(_variable), m_value(_value) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
private:
ptr<VariableDeclaration> m_variable;
ptr<Expression> m_value; ///< can be missing
ASTPointer<VariableDeclaration> m_variable;
ASTPointer<Expression> m_value; ///< can be missing
};
class Expression: public Statement
{
public:
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:
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
{
public:
Assignment(Location const& _location, ptr<Expression> const& _leftHandSide,
Token::Value _assignmentOperator, ptr<Expression> const& _rightHandSide)
Assignment(Location const& _location, ASTPointer<Expression> const& _leftHandSide,
Token::Value _assignmentOperator, ASTPointer<Expression> const& _rightHandSide)
: Expression(_location), m_leftHandSide(_leftHandSide),
m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
Token::Value getAssignmentOperator() const { return m_assigmentOperator; }
private:
ptr<Expression> m_leftHandSide;
ASTPointer<Expression> m_leftHandSide;
Token::Value m_assigmentOperator;
ptr<Expression> m_rightHandSide;
ASTPointer<Expression> m_rightHandSide;
};
class UnaryOperation: public Expression
{
public:
UnaryOperation(Location const& _location, Token::Value _operator,
ptr<Expression> const& _subExpression, bool _isPrefix)
ASTPointer<Expression> const& _subExpression, bool _isPrefix)
: Expression(_location), m_operator(_operator),
m_subExpression(_subExpression), m_isPrefix(_isPrefix) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
Token::Value getOperator() const { return m_operator; }
bool isPrefixOperation() const { return m_isPrefix; }
private:
Token::Value m_operator;
ptr<Expression> m_subExpression;
ASTPointer<Expression> m_subExpression;
bool m_isPrefix;
};
class BinaryOperation: public Expression
{
public:
BinaryOperation(Location const& _location, ptr<Expression> const& _left,
Token::Value _operator, ptr<Expression> const& _right)
BinaryOperation(Location const& _location, ASTPointer<Expression> const& _left,
Token::Value _operator, ASTPointer<Expression> const& _right)
: Expression(_location), m_left(_left), m_operator(_operator), m_right(_right) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
Token::Value getOperator() const { return m_operator; }
private:
ptr<Expression> m_left;
ASTPointer<Expression> m_left;
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.
class FunctionCall: public Expression
{
public:
FunctionCall(Location const& _location, ptr<Expression> const& _expression,
std::vector<ptr<Expression>> const& _arguments)
FunctionCall(Location const& _location, ASTPointer<Expression> const& _expression,
std::vector<ASTPointer<Expression>> const& _arguments)
: Expression(_location), m_expression(_expression), m_arguments(_arguments) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
private:
ptr<Expression> m_expression;
std::vector<ptr<Expression>> m_arguments;
ASTPointer<Expression> m_expression;
std::vector<ASTPointer<Expression>> m_arguments;
};
class MemberAccess: public Expression
{
public:
MemberAccess(Location const& _location, ptr<Expression> _expression,
ptr<ASTString> const& _memberName)
MemberAccess(Location const& _location, ASTPointer<Expression> _expression,
ASTPointer<ASTString> const& _memberName)
: Expression(_location), m_expression(_expression), m_memberName(_memberName) {}
virtual void accept(ASTVisitor& _visitor) override;
const ASTString& getMemberName() const { return *m_memberName; }
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
private:
ptr<Expression> m_expression;
ptr<ASTString> m_memberName;
ASTPointer<Expression> m_expression;
ASTPointer<ASTString> m_memberName;
};
class IndexAccess: public Expression
{
public:
IndexAccess(Location const& _location, ptr<Expression> const& _base,
ptr<Expression> const& _index)
IndexAccess(Location const& _location, ASTPointer<Expression> const& _base,
ASTPointer<Expression> const& _index)
: Expression(_location), m_base(_base), m_index(_index) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
private:
ptr<Expression> m_base;
ptr<Expression> m_index;
ASTPointer<Expression> m_base;
ASTPointer<Expression> m_index;
};
class PrimaryExpression: public Expression
@ -460,16 +461,16 @@ public:
class Identifier: public PrimaryExpression
{
public:
Identifier(Location const& _location, ptr<ASTString> const& _name)
Identifier(Location const& _location, ASTPointer<ASTString> const& _name)
: PrimaryExpression(_location), m_name(_name) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
ASTString const& getName() const { return *m_name; }
void setReferencedDeclaration(Declaration& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
Declaration* getReferencedDeclaration() { return m_referencedDeclaration; }
private:
ptr<ASTString> m_name;
ASTPointer<ASTString> m_name;
//! Declaration the name refers to.
Declaration* m_referencedDeclaration;
@ -481,7 +482,7 @@ public:
ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken)
: PrimaryExpression(_location), m_typeToken(_typeToken) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
Token::Value getTypeToken() const { return m_typeToken; }
private:
@ -491,16 +492,16 @@ private:
class Literal: public PrimaryExpression
{
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) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override;
virtual void checkTypeRequirements() override;
Token::Value getToken() const { return m_token; }
ASTString const& getValue() const { return *m_value; }
private:
Token::Value m_token;
ptr<ASTString> m_value;
ASTPointer<ASTString> m_value;
};
/// @}

View File

@ -69,7 +69,7 @@ class Literal;
// not do reference counting but point to a special memory area that is completely released
// explicitly.
template <class T>
using ptr = std::shared_ptr<T>;
using ASTPointer = std::shared_ptr<T>;
using ASTString = std::string;

View File

@ -28,7 +28,7 @@ namespace dev
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)
{
}

View File

@ -35,7 +35,7 @@ class ASTPrinter: public ASTVisitor
public:
/// 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.
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.
void print(std::ostream& _stream);
@ -108,7 +108,7 @@ private:
int m_indentation;
std::string m_source;
ptr<ASTNode> m_ast;
ASTPointer<ASTNode> m_ast;
std::ostream* m_ostream;
};

View File

@ -42,9 +42,9 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
DeclarationRegistrationHelper registrar(m_scopes, _contract);
m_currentScope = &m_scopes[&_contract];
//@todo structs
for (ptr<VariableDeclaration> const& variable: _contract.getStateVariables())
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
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()];
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
// the types, since it is possible to call functions that are only defined later
// in the source.
for (ptr<FunctionDefinition> const& function: _contract.getDefinedFunctions())
for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions())
{
m_currentScope = &m_scopes[function.get()];
function->getBody().checkTypeRequirements();

View File

@ -23,7 +23,6 @@
#pragma once
#include <map>
#include <boost/noncopyable.hpp>
#include <libsolidity/Scope.h>

View File

@ -31,7 +31,7 @@ namespace dev
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;
return parseContractDefinition();
@ -48,10 +48,10 @@ public:
void markEndPosition() { m_location.end = m_parser.getEndPosition(); }
void setLocationEmpty() { m_location.end = m_location.start; }
/// 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>
ptr<NodeType> createNode(Args&& ... _args)
ASTPointer<NodeType> createNode(Args&& ... _args)
{
if (m_location.end < 0)
markEndPosition();
@ -74,15 +74,15 @@ int Parser::getEndPosition() const
}
ptr<ContractDefinition> Parser::parseContractDefinition()
ASTPointer<ContractDefinition> Parser::parseContractDefinition()
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::CONTRACT);
ptr<ASTString> name = expectIdentifierToken();
ASTPointer<ASTString> name = expectIdentifierToken();
expectToken(Token::LBRACE);
std::vector<ptr<StructDefinition>> structs;
std::vector<ptr<VariableDeclaration>> stateVariables;
std::vector<ptr<FunctionDefinition>> functions;
std::vector<ASTPointer<StructDefinition>> structs;
std::vector<ASTPointer<VariableDeclaration>> stateVariables;
std::vector<ASTPointer<FunctionDefinition>> functions;
bool visibilityIsPublic = true;
while (true)
{
@ -115,19 +115,19 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
}
ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::FUNCTION);
ptr<ASTString> name(expectIdentifierToken());
ptr<ParameterList> parameters(parseParameterList());
ASTPointer<ASTString> name(expectIdentifierToken());
ASTPointer<ParameterList> parameters(parseParameterList());
bool isDeclaredConst = false;
if (m_scanner->getCurrentToken() == Token::CONST)
{
isDeclaredConst = true;
m_scanner->next();
}
ptr<ParameterList> returnParameters;
ASTPointer<ParameterList> returnParameters;
if (m_scanner->getCurrentToken() == Token::RETURNS)
{
bool const permitEmptyParameterList = false;
@ -139,20 +139,20 @@ ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
// create an empty parameter list at a zero-length location
ASTNodeFactory nodeFactory(*this);
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);
return nodeFactory.createNode<FunctionDefinition>(name, _isPublic, parameters,
isDeclaredConst, returnParameters, block);
}
ptr<StructDefinition> Parser::parseStructDefinition()
ASTPointer<StructDefinition> Parser::parseStructDefinition()
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::STRUCT);
ptr<ASTString> name = expectIdentifierToken();
std::vector<ptr<VariableDeclaration>> members;
ASTPointer<ASTString> name = expectIdentifierToken();
std::vector<ASTPointer<VariableDeclaration>> members;
expectToken(Token::LBRACE);
while (m_scanner->getCurrentToken() != Token::RBRACE)
{
@ -165,17 +165,17 @@ ptr<StructDefinition> Parser::parseStructDefinition()
return nodeFactory.createNode<StructDefinition>(name, members);
}
ptr<VariableDeclaration> Parser::parseVariableDeclaration(bool _allowVar)
ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(bool _allowVar)
{
ASTNodeFactory nodeFactory(*this);
ptr<TypeName> type = parseTypeName(_allowVar);
ASTPointer<TypeName> type = parseTypeName(_allowVar);
nodeFactory.markEndPosition();
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();
if (Token::isElementaryTypeName(token))
{
@ -203,28 +203,28 @@ ptr<TypeName> Parser::parseTypeName(bool _allowVar)
return type;
}
ptr<Mapping> Parser::parseMapping()
ASTPointer<Mapping> Parser::parseMapping()
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::MAPPING);
expectToken(Token::LPAREN);
if (!Token::isElementaryTypeName(m_scanner->getCurrentToken()))
throwExpectationError("Expected elementary type name for mapping key type");
ptr<ElementaryTypeName> keyType;
ASTPointer<ElementaryTypeName> keyType;
keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(m_scanner->getCurrentToken());
m_scanner->next();
expectToken(Token::ARROW);
bool const allowVar = false;
ptr<TypeName> valueType = parseTypeName(allowVar);
ASTPointer<TypeName> valueType = parseTypeName(allowVar);
nodeFactory.markEndPosition();
expectToken(Token::RPAREN);
return nodeFactory.createNode<Mapping>(keyType, valueType);
}
ptr<ParameterList> Parser::parseParameterList(bool _allowEmpty)
ASTPointer<ParameterList> Parser::parseParameterList(bool _allowEmpty)
{
ASTNodeFactory nodeFactory(*this);
std::vector<ptr<VariableDeclaration>> parameters;
std::vector<ASTPointer<VariableDeclaration>> parameters;
expectToken(Token::LPAREN);
if (!_allowEmpty || m_scanner->getCurrentToken() != Token::RPAREN)
{
@ -241,11 +241,11 @@ ptr<ParameterList> Parser::parseParameterList(bool _allowEmpty)
return nodeFactory.createNode<ParameterList>(parameters);
}
ptr<Block> Parser::parseBlock()
ASTPointer<Block> Parser::parseBlock()
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::LBRACE);
std::vector<ptr<Statement>> statements;
std::vector<ASTPointer<Statement>> statements;
while (m_scanner->getCurrentToken() != Token::RBRACE)
statements.push_back(parseStatement());
nodeFactory.markEndPosition();
@ -253,9 +253,9 @@ ptr<Block> Parser::parseBlock()
return nodeFactory.createNode<Block>(statements);
}
ptr<Statement> Parser::parseStatement()
ASTPointer<Statement> Parser::parseStatement()
{
ptr<Statement> statement;
ASTPointer<Statement> statement;
switch (m_scanner->getCurrentToken())
{
case Token::IF:
@ -274,7 +274,7 @@ ptr<Statement> Parser::parseStatement()
case Token::RETURN:
{
ASTNodeFactory nodeFactory(*this);
ptr<Expression> expression;
ASTPointer<Expression> expression;
if (m_scanner->next() != Token::SEMICOLON)
{
expression = parseExpression();
@ -301,15 +301,15 @@ ptr<Statement> Parser::parseStatement()
return statement;
}
ptr<IfStatement> Parser::parseIfStatement()
ASTPointer<IfStatement> Parser::parseIfStatement()
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::IF);
expectToken(Token::LPAREN);
ptr<Expression> condition = parseExpression();
ASTPointer<Expression> condition = parseExpression();
expectToken(Token::RPAREN);
ptr<Statement> trueBody = parseStatement();
ptr<Statement> falseBody;
ASTPointer<Statement> trueBody = parseStatement();
ASTPointer<Statement> falseBody;
if (m_scanner->getCurrentToken() == Token::ELSE)
{
m_scanner->next();
@ -321,24 +321,24 @@ ptr<IfStatement> Parser::parseIfStatement()
return nodeFactory.createNode<IfStatement>(condition, trueBody, falseBody);
}
ptr<WhileStatement> Parser::parseWhileStatement()
ASTPointer<WhileStatement> Parser::parseWhileStatement()
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::WHILE);
expectToken(Token::LPAREN);
ptr<Expression> condition = parseExpression();
ASTPointer<Expression> condition = parseExpression();
expectToken(Token::RPAREN);
ptr<Statement> body = parseStatement();
ASTPointer<Statement> body = parseStatement();
nodeFactory.setEndPositionFromNode(body);
return nodeFactory.createNode<WhileStatement>(condition, body);
}
ptr<VariableDefinition> Parser::parseVariableDefinition()
ASTPointer<VariableDefinition> Parser::parseVariableDefinition()
{
ASTNodeFactory nodeFactory(*this);
bool const allowVar = true;
ptr<VariableDeclaration> variable = parseVariableDeclaration(allowVar);
ptr<Expression> value;
ASTPointer<VariableDeclaration> variable = parseVariableDeclaration(allowVar);
ASTPointer<Expression> value;
if (m_scanner->getCurrentToken() == Token::ASSIGN)
{
m_scanner->next();
@ -350,22 +350,22 @@ ptr<VariableDefinition> Parser::parseVariableDefinition()
return nodeFactory.createNode<VariableDefinition>(variable, value);
}
ptr<Expression> Parser::parseExpression()
ASTPointer<Expression> Parser::parseExpression()
{
ASTNodeFactory nodeFactory(*this);
ptr<Expression> expression = parseBinaryExpression();
ASTPointer<Expression> expression = parseBinaryExpression();
if (!Token::isAssignmentOp(m_scanner->getCurrentToken()))
return expression;
Token::Value assignmentOperator = expectAssignmentOperator();
ptr<Expression> rightHandSide = parseExpression();
ASTPointer<Expression> rightHandSide = parseExpression();
nodeFactory.setEndPositionFromNode(rightHandSide);
return nodeFactory.createNode<Assignment>(expression, assignmentOperator, rightHandSide);
}
ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
ASTPointer<Expression> Parser::parseBinaryExpression(int _minPrecedence)
{
ASTNodeFactory nodeFactory(*this);
ptr<Expression> expression = parseUnaryExpression();
ASTPointer<Expression> expression = parseUnaryExpression();
int precedence = Token::precedence(m_scanner->getCurrentToken());
for (; precedence >= _minPrecedence; --precedence)
{
@ -373,7 +373,7 @@ ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
{
Token::Value op = m_scanner->getCurrentToken();
m_scanner->next();
ptr<Expression> right = parseBinaryExpression(precedence + 1);
ASTPointer<Expression> right = parseBinaryExpression(precedence + 1);
nodeFactory.setEndPositionFromNode(right);
expression = nodeFactory.createNode<BinaryOperation>(expression, op, right);
}
@ -381,7 +381,7 @@ ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
return expression;
}
ptr<Expression> Parser::parseUnaryExpression()
ASTPointer<Expression> Parser::parseUnaryExpression()
{
ASTNodeFactory nodeFactory(*this);
Token::Value token = m_scanner->getCurrentToken();
@ -389,14 +389,14 @@ ptr<Expression> Parser::parseUnaryExpression()
{
// prefix expression
m_scanner->next();
ptr<Expression> subExpression = parseUnaryExpression();
ASTPointer<Expression> subExpression = parseUnaryExpression();
nodeFactory.setEndPositionFromNode(subExpression);
return nodeFactory.createNode<UnaryOperation>(token, subExpression, true);
}
else
{
// potential postfix expression
ptr<Expression> subExpression = parseLeftHandSideExpression();
ASTPointer<Expression> subExpression = parseLeftHandSideExpression();
token = m_scanner->getCurrentToken();
if (!Token::isCountOp(token))
return subExpression;
@ -406,38 +406,38 @@ ptr<Expression> Parser::parseUnaryExpression()
}
}
ptr<Expression> Parser::parseLeftHandSideExpression()
ASTPointer<Expression> Parser::parseLeftHandSideExpression()
{
ASTNodeFactory nodeFactory(*this);
ptr<Expression> expression = parsePrimaryExpression();
ASTPointer<Expression> expression = parsePrimaryExpression();
while (true)
{
switch (m_scanner->getCurrentToken())
{
case Token::LBRACK:
{
m_scanner->next();
ptr<Expression> index = parseExpression();
nodeFactory.markEndPosition();
expectToken(Token::RBRACK);
expression = nodeFactory.createNode<IndexAccess>(expression, index);
}
{
m_scanner->next();
ASTPointer<Expression> index = parseExpression();
nodeFactory.markEndPosition();
expectToken(Token::RBRACK);
expression = nodeFactory.createNode<IndexAccess>(expression, index);
}
break;
case Token::PERIOD:
{
m_scanner->next();
nodeFactory.markEndPosition();
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
}
{
m_scanner->next();
nodeFactory.markEndPosition();
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
}
break;
case Token::LPAREN:
{
m_scanner->next();
std::vector<ptr<Expression>> arguments = parseFunctionCallArguments();
nodeFactory.markEndPosition();
expectToken(Token::RPAREN);
expression = nodeFactory.createNode<FunctionCall>(expression, arguments);
}
{
m_scanner->next();
std::vector<ASTPointer<Expression>> arguments = parseFunctionCallArguments();
nodeFactory.markEndPosition();
expectToken(Token::RPAREN);
expression = nodeFactory.createNode<FunctionCall>(expression, arguments);
}
break;
default:
return expression;
@ -445,16 +445,16 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
}
}
ptr<Expression> Parser::parsePrimaryExpression()
ASTPointer<Expression> Parser::parsePrimaryExpression()
{
ASTNodeFactory nodeFactory(*this);
Token::Value token = m_scanner->getCurrentToken();
ptr<Expression> expression;
ASTPointer<Expression> expression;
switch (token)
{
case Token::TRUE_LITERAL:
case Token::FALSE_LITERAL:
expression = nodeFactory.createNode<Literal>(token, ptr<ASTString>());
expression = nodeFactory.createNode<Literal>(token, ASTPointer<ASTString>());
m_scanner->next();
break;
case Token::NUMBER:
@ -467,12 +467,12 @@ ptr<Expression> Parser::parsePrimaryExpression()
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());
break;
case Token::LPAREN:
{
m_scanner->next();
ptr<Expression> expression = parseExpression();
expectToken(Token::RPAREN);
return expression;
}
{
m_scanner->next();
ASTPointer<Expression> expression = parseExpression();
expectToken(Token::RPAREN);
return expression;
}
default:
if (Token::isElementaryTypeName(token))
{
@ -483,16 +483,16 @@ ptr<Expression> Parser::parsePrimaryExpression()
else
{
throwExpectationError("Expected primary expression.");
return ptr<Expression>(); // this is not reached
return ASTPointer<Expression>(); // this is not reached
}
break;
}
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)
{
arguments.push_back(parseExpression());
@ -521,16 +521,16 @@ Token::Value Parser::expectAssignmentOperator()
return op;
}
ptr<ASTString> Parser::expectIdentifierToken()
ASTPointer<ASTString> Parser::expectIdentifierToken()
{
if (m_scanner->getCurrentToken() != Token::IDENTIFIER)
throwExpectationError("Expected identifier");
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();
return identifier;
}

View File

@ -34,7 +34,7 @@ class Scanner;
class Parser
{
public:
ptr<ContractDefinition> parse(std::shared_ptr<Scanner> const& _scanner);
ASTPointer<ContractDefinition> parse(std::shared_ptr<Scanner> const& _scanner);
private:
class ASTNodeFactory;
@ -46,24 +46,24 @@ private:
/// Parsing functions for the AST nodes
/// @{
ptr<ContractDefinition> parseContractDefinition();
ptr<FunctionDefinition> parseFunctionDefinition(bool _isPublic);
ptr<StructDefinition> parseStructDefinition();
ptr<VariableDeclaration> parseVariableDeclaration(bool _allowVar);
ptr<TypeName> parseTypeName(bool _allowVar);
ptr<Mapping> parseMapping();
ptr<ParameterList> parseParameterList(bool _allowEmpty = true);
ptr<Block> parseBlock();
ptr<Statement> parseStatement();
ptr<IfStatement> parseIfStatement();
ptr<WhileStatement> parseWhileStatement();
ptr<VariableDefinition> parseVariableDefinition();
ptr<Expression> parseExpression();
ptr<Expression> parseBinaryExpression(int _minPrecedence = 4);
ptr<Expression> parseUnaryExpression();
ptr<Expression> parseLeftHandSideExpression();
ptr<Expression> parsePrimaryExpression();
std::vector<ptr<Expression>> parseFunctionCallArguments();
ASTPointer<ContractDefinition> parseContractDefinition();
ASTPointer<FunctionDefinition> parseFunctionDefinition(bool _isPublic);
ASTPointer<StructDefinition> parseStructDefinition();
ASTPointer<VariableDeclaration> parseVariableDeclaration(bool _allowVar);
ASTPointer<TypeName> parseTypeName(bool _allowVar);
ASTPointer<Mapping> parseMapping();
ASTPointer<ParameterList> parseParameterList(bool _allowEmpty = true);
ASTPointer<Block> parseBlock();
ASTPointer<Statement> parseStatement();
ASTPointer<IfStatement> parseIfStatement();
ASTPointer<WhileStatement> parseWhileStatement();
ASTPointer<VariableDefinition> parseVariableDefinition();
ASTPointer<Expression> parseExpression();
ASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4);
ASTPointer<Expression> parseUnaryExpression();
ASTPointer<Expression> parseLeftHandSideExpression();
ASTPointer<Expression> parsePrimaryExpression();
std::vector<ASTPointer<Expression>> parseFunctionCallArguments();
/// @}
/// Helper functions
@ -71,8 +71,8 @@ private:
/// If current token value is not _value, throw exception otherwise advance token.
void expectToken(Token::Value _value);
Token::Value expectAssignmentOperator();
ptr<ASTString> expectIdentifierToken();
ptr<ASTString> getLiteralAndAdvance();
ASTPointer<ASTString> expectIdentifierToken();
ASTPointer<ASTString> getLiteralAndAdvance();
void throwExpectationError(std::string const& _description);
/// @}

View File

@ -81,12 +81,15 @@ bool IsIdentifierPart(char c)
int HexValue(char c)
{
if (c >= '0' && c <= '9') return c - '0';
else if (c >= 'a' && c <= 'f') return c - 'a' + 10;
else if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else return -1;
}
}
} // end anonymous namespace
Scanner::Scanner(CharStream const& _source)
{
@ -409,13 +412,15 @@ bool Scanner::scanEscape()
c = '\t';
break;
case 'u':
if (!scanHexNumber(c, 4)) return false;
if (!scanHexNumber(c, 4))
return false;
break;
case 'v':
c = '\v';
break;
case 'x':
if (!scanHexNumber(c, 2)) return false;
if (!scanHexNumber(c, 2))
return false;
break;
}
@ -612,9 +617,8 @@ case ch:
int const keyword_length = sizeof(keyword) - 1; \
BOOST_STATIC_ASSERT(keyword_length >= kMinLength); \
BOOST_STATIC_ASSERT(keyword_length <= kMaxLength); \
if (input == keyword) { \
return token; \
} \
if (input == keyword) \
return token; \
}
KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD)
}
@ -635,9 +639,11 @@ Token::Value Scanner::scanIdentifierOrKeyword()
char CharStream::advanceAndGet()
{
if (isPastEndOfInput()) return 0;
if (isPastEndOfInput())
return 0;
++m_pos;
if (isPastEndOfInput()) return 0;
if (isPastEndOfInput())
return 0;
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
using size_type = std::string::size_type;
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);
if (lineStart == std::string::npos)
lineStart = 0;

View File

@ -23,7 +23,6 @@
#pragma once
#include <map>
#include <boost/noncopyable.hpp>
#include <libsolidity/ASTForward.h>

View File

@ -28,7 +28,7 @@ namespace dev
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)
{
@ -52,18 +52,18 @@ ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
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());
}
ptr<Type> Type::fromMapping(Mapping const&)
std::shared_ptr<Type> Type::fromMapping(Mapping const&)
{
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())
{
@ -73,13 +73,13 @@ ptr<Type> Type::forLiteral(Literal const& _literal)
case Token::NUMBER:
return IntegerType::smallestTypeForLiteral(_literal.getValue());
case Token::STRING_LITERAL:
return ptr<Type>(); // @todo
return std::shared_ptr<Type>(); // @todo
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
return std::make_shared<IntegerType>(256, Modifier::UNSIGNED);

35
Types.h
View File

@ -26,7 +26,7 @@
#include <string>
#include <boost/noncopyable.hpp>
#include <boost/assert.hpp>
#include <libsolidity/ASTForward.h>
#include <libsolidity/Token.h>
namespace dev
@ -34,18 +34,6 @@ namespace dev
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
class Type: private boost::noncopyable
@ -57,11 +45,11 @@ public:
};
//! factory functions that convert an AST TypeName to a Type.
static ptr<Type> fromElementaryTypeName(Token::Value _typeToken);
static ptr<Type> fromUserDefinedTypeName(UserDefinedTypeName const& _typeName);
static ptr<Type> fromMapping(Mapping const& _typeName);
static std::shared_ptr<Type> fromElementaryTypeName(Token::Value _typeToken);
static std::shared_ptr<Type> fromUserDefinedTypeName(UserDefinedTypeName 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 bool isImplicitlyConvertibleTo(Type const&) const { return false; }
@ -82,7 +70,7 @@ public:
};
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);
@ -95,6 +83,7 @@ public:
bool isHash() const { return m_modifier == Modifier::HASH || m_modifier == Modifier::ADDRESS; }
bool isAddress() const { return m_modifier == Modifier::ADDRESS; }
int isSigned() const { return m_modifier == Modifier::SIGNED; }
private:
int m_bits;
Modifier m_modifier;
@ -125,6 +114,7 @@ public:
virtual Category getCategory() const { return Category::CONTRACT; }
ContractType(ContractDefinition const& _contract): m_contract(_contract) {}
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const;
private:
ContractDefinition const& m_contract;
};
@ -139,6 +129,7 @@ public:
{
return _operator == Token::DELETE;
}
private:
StructDefinition const& m_struct;
};
@ -150,6 +141,7 @@ public:
FunctionType(FunctionDefinition const& _function): m_function(_function) {}
FunctionDefinition const& getFunction() const { return m_function; }
private:
FunctionDefinition const& m_function;
};
@ -175,11 +167,12 @@ class TypeType: public Type
{
public:
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:
ptr<Type> m_actualType;
std::shared_ptr<Type const> m_actualType;
};