mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #3297 from ethereum/separate_expression_and_statement
Separate expression and statement
This commit is contained in:
@@ -42,11 +42,13 @@ using If = solidity::assembly::If;
|
||||
using Case = solidity::assembly::Case;
|
||||
using Switch = solidity::assembly::Switch;
|
||||
using ForLoop = solidity::assembly::ForLoop;
|
||||
using ExpressionStatement = solidity::assembly::ExpressionStatement;
|
||||
using Block = solidity::assembly::Block;
|
||||
|
||||
using TypedName = solidity::assembly::TypedName;
|
||||
|
||||
using Statement = boost::variant<Instruction, Literal, Label, StackAssignment, Identifier, Assignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Block>;
|
||||
using Expression = boost::variant<FunctionalInstruction, FunctionCall, Identifier, Literal>;
|
||||
using Statement = boost::variant<ExpressionStatement, Instruction, Label, StackAssignment, Assignment, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Block>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,13 @@ void CodeTransform::operator()(StackAssignment const& _assignment)
|
||||
checkStackHeight(&_assignment);
|
||||
}
|
||||
|
||||
void CodeTransform::operator()(ExpressionStatement const& _statement)
|
||||
{
|
||||
m_assembly.setSourceLocation(_statement.location);
|
||||
boost::apply_visitor(*this, _statement.expression);
|
||||
checkStackHeight(&_statement);
|
||||
}
|
||||
|
||||
void CodeTransform::operator()(Label const& _label)
|
||||
{
|
||||
m_assembly.setSourceLocation(_label.location);
|
||||
@@ -460,7 +467,7 @@ AbstractAssembly::LabelID CodeTransform::functionEntryID(string const& _name, Sc
|
||||
return m_context->functionEntryIDs[&_function];
|
||||
}
|
||||
|
||||
void CodeTransform::visitExpression(Statement const& _expression)
|
||||
void CodeTransform::visitExpression(Expression const& _expression)
|
||||
{
|
||||
int height = m_assembly.stackHeight();
|
||||
boost::apply_visitor(*this, _expression);
|
||||
|
||||
@@ -101,6 +101,7 @@ public:
|
||||
void operator()(Identifier const& _identifier);
|
||||
void operator()(FunctionalInstruction const& _instr);
|
||||
void operator()(FunctionCall const&);
|
||||
void operator()(ExpressionStatement const& _statement);
|
||||
void operator()(Label const& _label);
|
||||
void operator()(StackAssignment const& _assignment);
|
||||
void operator()(Assignment const& _assignment);
|
||||
@@ -118,7 +119,7 @@ private:
|
||||
AbstractAssembly::LabelID labelID(solidity::assembly::Scope::Label const& _label);
|
||||
AbstractAssembly::LabelID functionEntryID(std::string const& _name, solidity::assembly::Scope::Function const& _function);
|
||||
/// Generates code for an expression that is supposed to return a single value.
|
||||
void visitExpression(Statement const& _expression);
|
||||
void visitExpression(Expression const& _expression);
|
||||
|
||||
void visitStatements(std::vector<Statement> const& _statements);
|
||||
|
||||
|
||||
@@ -37,6 +37,11 @@ Statement ASTCopier::operator()(Instruction const&)
|
||||
return {};
|
||||
}
|
||||
|
||||
Statement ASTCopier::operator()(ExpressionStatement const& _statement)
|
||||
{
|
||||
return ExpressionStatement{ _statement.location, translate(_statement.expression) };
|
||||
}
|
||||
|
||||
Statement ASTCopier::operator()(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
return VariableDeclaration{
|
||||
@@ -67,7 +72,7 @@ Statement ASTCopier::operator()(Label const&)
|
||||
return {};
|
||||
}
|
||||
|
||||
Statement ASTCopier::operator()(FunctionCall const& _call)
|
||||
Expression ASTCopier::operator()(FunctionCall const& _call)
|
||||
{
|
||||
return FunctionCall{
|
||||
_call.location,
|
||||
@@ -76,7 +81,7 @@ Statement ASTCopier::operator()(FunctionCall const& _call)
|
||||
};
|
||||
}
|
||||
|
||||
Statement ASTCopier::operator()(FunctionalInstruction const& _instruction)
|
||||
Expression ASTCopier::operator()(FunctionalInstruction const& _instruction)
|
||||
{
|
||||
return FunctionalInstruction{
|
||||
_instruction.location,
|
||||
@@ -85,12 +90,12 @@ Statement ASTCopier::operator()(FunctionalInstruction const& _instruction)
|
||||
};
|
||||
}
|
||||
|
||||
Statement ASTCopier::operator()(Identifier const& _identifier)
|
||||
Expression ASTCopier::operator()(Identifier const& _identifier)
|
||||
{
|
||||
return Identifier{_identifier.location, translateIdentifier(_identifier.name)};
|
||||
}
|
||||
|
||||
Statement ASTCopier::operator()(Literal const& _literal)
|
||||
Expression ASTCopier::operator()(Literal const& _literal)
|
||||
{
|
||||
return translate(_literal);
|
||||
}
|
||||
@@ -140,9 +145,14 @@ Statement ASTCopier::operator ()(Block const& _block)
|
||||
return translate(_block);
|
||||
}
|
||||
|
||||
Expression ASTCopier::translate(Expression const& _expression)
|
||||
{
|
||||
return _expression.apply_visitor(static_cast<ExpressionCopier&>(*this));
|
||||
}
|
||||
|
||||
Statement ASTCopier::translate(Statement const& _statement)
|
||||
{
|
||||
return boost::apply_visitor(*this, _statement);
|
||||
return _statement.apply_visitor(static_cast<StatementCopier&>(*this));
|
||||
}
|
||||
|
||||
Block ASTCopier::translate(Block const& _block)
|
||||
|
||||
@@ -34,28 +34,55 @@ namespace dev
|
||||
namespace julia
|
||||
{
|
||||
|
||||
class ExpressionCopier: public boost::static_visitor<Expression>
|
||||
{
|
||||
public:
|
||||
virtual Expression operator()(Literal const& _literal) = 0;
|
||||
virtual Expression operator()(Identifier const& _identifier) = 0;
|
||||
virtual Expression operator()(FunctionalInstruction const& _instr) = 0;
|
||||
virtual Expression operator()(FunctionCall const&) = 0;
|
||||
};
|
||||
|
||||
class StatementCopier: public boost::static_visitor<Statement>
|
||||
{
|
||||
public:
|
||||
virtual Statement operator()(ExpressionStatement const& _statement) = 0;
|
||||
virtual Statement operator()(Instruction const& _instruction) = 0;
|
||||
virtual Statement operator()(Label const& _label) = 0;
|
||||
virtual Statement operator()(StackAssignment const& _assignment) = 0;
|
||||
virtual Statement operator()(Assignment const& _assignment) = 0;
|
||||
virtual Statement operator()(VariableDeclaration const& _varDecl) = 0;
|
||||
virtual Statement operator()(If const& _if) = 0;
|
||||
virtual Statement operator()(Switch const& _switch) = 0;
|
||||
virtual Statement operator()(FunctionDefinition const&) = 0;
|
||||
virtual Statement operator()(ForLoop const&) = 0;
|
||||
virtual Statement operator()(Block const& _block) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a copy of a iulia AST potentially replacing identifier names.
|
||||
* Base class to be extended.
|
||||
*/
|
||||
class ASTCopier: public boost::static_visitor<Statement>
|
||||
class ASTCopier: public ExpressionCopier, public StatementCopier
|
||||
{
|
||||
public:
|
||||
Statement operator()(Literal const& _literal);
|
||||
Statement operator()(Instruction const& _instruction);
|
||||
Statement operator()(Identifier const& _identifier);
|
||||
Statement operator()(FunctionalInstruction const& _instr);
|
||||
Statement operator()(FunctionCall const&);
|
||||
Statement operator()(Label const& _label);
|
||||
Statement operator()(StackAssignment const& _assignment);
|
||||
Statement operator()(Assignment const& _assignment);
|
||||
Statement operator()(VariableDeclaration const& _varDecl);
|
||||
Statement operator()(If const& _if);
|
||||
Statement operator()(Switch const& _switch);
|
||||
Statement operator()(FunctionDefinition const&);
|
||||
Statement operator()(ForLoop const&);
|
||||
Statement operator()(Block const& _block);
|
||||
virtual Expression operator()(Literal const& _literal) override;
|
||||
virtual Statement operator()(Instruction const& _instruction) override;
|
||||
virtual Expression operator()(Identifier const& _identifier) override;
|
||||
virtual Expression operator()(FunctionalInstruction const& _instr) override;
|
||||
virtual Expression operator()(FunctionCall const&) override;
|
||||
virtual Statement operator()(ExpressionStatement const& _statement) override;
|
||||
virtual Statement operator()(Label const& _label) override;
|
||||
virtual Statement operator()(StackAssignment const& _assignment) override;
|
||||
virtual Statement operator()(Assignment const& _assignment) override;
|
||||
virtual Statement operator()(VariableDeclaration const& _varDecl) override;
|
||||
virtual Statement operator()(If const& _if) override;
|
||||
virtual Statement operator()(Switch const& _switch) override;
|
||||
virtual Statement operator()(FunctionDefinition const&) override;
|
||||
virtual Statement operator()(ForLoop const&) override;
|
||||
virtual Statement operator()(Block const& _block) override;
|
||||
|
||||
virtual Expression translate(Expression const& _expression);
|
||||
virtual Statement translate(Statement const& _statement);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -42,6 +42,11 @@ void ASTWalker::operator()(FunctionCall const& _funCall)
|
||||
walkVector(_funCall.arguments | boost::adaptors::reversed);
|
||||
}
|
||||
|
||||
void ASTWalker::operator()(ExpressionStatement const& _statement)
|
||||
{
|
||||
boost::apply_visitor(*this, _statement.expression);
|
||||
}
|
||||
|
||||
void ASTWalker::operator()(Assignment const& _assignment)
|
||||
{
|
||||
for (auto const& name: _assignment.variableNames)
|
||||
@@ -100,6 +105,11 @@ void ASTModifier::operator()(FunctionCall& _funCall)
|
||||
walkVector(_funCall.arguments | boost::adaptors::reversed);
|
||||
}
|
||||
|
||||
void ASTModifier::operator()(ExpressionStatement& _statement)
|
||||
{
|
||||
boost::apply_visitor(*this, _statement.expression);
|
||||
}
|
||||
|
||||
void ASTModifier::operator()(Assignment& _assignment)
|
||||
{
|
||||
for (auto& name: _assignment.variableNames)
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
virtual void operator()(Identifier const&) {}
|
||||
virtual void operator()(FunctionalInstruction const& _instr);
|
||||
virtual void operator()(FunctionCall const& _funCall);
|
||||
virtual void operator()(ExpressionStatement const& _statement);
|
||||
virtual void operator()(Label const&) { solAssert(false, ""); }
|
||||
virtual void operator()(StackAssignment const&) { solAssert(false, ""); }
|
||||
virtual void operator()(Assignment const& _assignment);
|
||||
@@ -77,6 +78,7 @@ public:
|
||||
virtual void operator()(Identifier&) {}
|
||||
virtual void operator()(FunctionalInstruction& _instr);
|
||||
virtual void operator()(FunctionCall& _funCall);
|
||||
virtual void operator()(ExpressionStatement& _statement);
|
||||
virtual void operator()(Label&) { solAssert(false, ""); }
|
||||
virtual void operator()(StackAssignment&) { solAssert(false, ""); }
|
||||
virtual void operator()(Assignment& _assignment);
|
||||
@@ -98,6 +100,10 @@ protected:
|
||||
{
|
||||
boost::apply_visitor(*this, _st);
|
||||
}
|
||||
virtual void visit(Expression& _e)
|
||||
{
|
||||
boost::apply_visitor(*this, _e);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -26,14 +26,14 @@ using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::julia;
|
||||
|
||||
Statement Substitution::translate(Statement const& _statement)
|
||||
Expression Substitution::translate(Expression const& _expression)
|
||||
{
|
||||
if (_statement.type() == typeid(Identifier))
|
||||
if (_expression.type() == typeid(Identifier))
|
||||
{
|
||||
string const& name = boost::get<Identifier>(_statement).name;
|
||||
string const& name = boost::get<Identifier>(_expression).name;
|
||||
if (m_substitutions.count(name))
|
||||
// No recursive substitution
|
||||
return ASTCopier().translate(*m_substitutions.at(name));
|
||||
}
|
||||
return ASTCopier::translate(_statement);
|
||||
return ASTCopier::translate(_expression);
|
||||
}
|
||||
|
||||
@@ -33,18 +33,17 @@ namespace julia
|
||||
|
||||
/**
|
||||
* Specific AST copier that replaces certain identifiers with expressions.
|
||||
* Only works on ASTs that are expressions.
|
||||
*/
|
||||
class Substitution: public ASTCopier
|
||||
{
|
||||
public:
|
||||
Substitution(std::map<std::string, Statement const*> const& _substitutions):
|
||||
Substitution(std::map<std::string, Expression const*> const& _substitutions):
|
||||
m_substitutions(_substitutions)
|
||||
{}
|
||||
virtual Statement translate(Statement const& _statement) override;
|
||||
virtual Expression translate(Expression const& _expression) override;
|
||||
|
||||
private:
|
||||
std::map<std::string, Statement const*> const& m_substitutions;
|
||||
std::map<std::string, Expression const*> const& m_substitutions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user