Destructuring assignments.

This commit is contained in:
chriseth
2015-10-15 17:38:42 +02:00
parent 7ebd536e79
commit 039b2a764f
11 changed files with 389 additions and 105 deletions
+30 -11
View File
@@ -177,20 +177,18 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
bool ExpressionCompiler::visit(Assignment const& _assignment)
{
// cout << "-----Assignment" << endl;
CompilerContext::LocationSetter locationSetter(m_context, _assignment);
_assignment.rightHandSide().accept(*this);
TypePointer type = _assignment.rightHandSide().annotation().type;
if (!_assignment.annotation().type->dataStoredIn(DataLocation::Storage))
{
utils().convertType(*type, *_assignment.annotation().type);
type = _assignment.annotation().type;
}
else
{
utils().convertType(*type, *type->mobileType());
type = type->mobileType();
}
// Perform some conversion already. This will convert storage types to memory and literals
// to their actual type, but will not convert e.g. memory to storage.
TypePointer type = _assignment.rightHandSide().annotation().type->closestTemporaryType(
_assignment.leftHandSide().annotation().type
);
// cout << "-----Type conversion" << endl;
utils().convertType(*_assignment.rightHandSide().annotation().type, *type);
// cout << "-----LHS" << endl;
_assignment.leftHandSide().accept(*this);
solAssert(!!m_currentLValue, "LValue not retrieved.");
@@ -216,11 +214,32 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
}
}
// cout << "-----Store" << endl;
m_currentLValue->storeValue(*type, _assignment.location());
m_currentLValue.reset();
return false;
}
bool ExpressionCompiler::visit(TupleExpression const& _tuple)
{
vector<unique_ptr<LValue>> lvalues;
for (auto const& component: _tuple.components())
if (component)
{
component->accept(*this);
if (_tuple.annotation().lValueRequested)
{
solAssert(!!m_currentLValue, "");
lvalues.push_back(move(m_currentLValue));
}
}
else if (_tuple.annotation().lValueRequested)
lvalues.push_back(unique_ptr<LValue>());
if (_tuple.annotation().lValueRequested)
m_currentLValue.reset(new TupleObject(m_context, move(lvalues)));
return false;
}
bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
{
CompilerContext::LocationSetter locationSetter(m_context, _unaryOperation);