aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2014-11-13 08:12:57 +0800
committerChristian <c@ethdev.com>2014-11-14 21:08:14 +0800
commitc560a62352b8ba1a106ec06aedf779df06af3a22 (patch)
tree325f19538a1239529e68d0126341e0f6aa655ef7 /ExpressionCompiler.cpp
parent46dd62982084dfe5712292b88047d2a58e0a420e (diff)
downloaddexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.tar.gz
dexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.tar.zst
dexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.zip
Struct types.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r--ExpressionCompiler.cpp17
1 files changed, 13 insertions, 4 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index d80b42b3..f37ce39c 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -49,7 +49,6 @@ bool ExpressionCompiler::visit(Assignment& _assignment)
{
_assignment.getRightHandSide().accept(*this);
appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType());
- m_currentLValue.reset();
_assignment.getLeftHandSide().accept(*this);
if (asserts(m_currentLValue.isValid()))
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved."));
@@ -63,6 +62,7 @@ bool ExpressionCompiler::visit(Assignment& _assignment)
appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType());
}
m_currentLValue.storeValue(_assignment);
+ m_currentLValue.reset();
return false;
}
@@ -90,6 +90,7 @@ void ExpressionCompiler::endVisit(UnaryOperation& _unaryOperation)
if (m_currentLValue.storesReferenceOnStack())
m_context << eth::Instruction::SWAP1;
m_currentLValue.storeValue(_unaryOperation);
+ m_currentLValue.reset();
break;
case Token::INC: // ++ (pre- or postfix)
case Token::DEC: // -- (pre- or postfix)
@@ -113,6 +114,7 @@ void ExpressionCompiler::endVisit(UnaryOperation& _unaryOperation)
if (m_currentLValue.storesReferenceOnStack())
m_context << eth::Instruction::SWAP1;
m_currentLValue.storeValue(_unaryOperation, !_unaryOperation.isPrefixOperation());
+ m_currentLValue.reset();
break;
case Token::ADD: // +
// unary add, so basically no-op
@@ -182,10 +184,10 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
arguments[i]->accept(*this);
appendTypeConversion(*arguments[i]->getType(), *function.getParameters()[i]->getType());
}
- m_currentLValue.reset();
_functionCall.getExpression().accept(*this);
if (asserts(m_currentLValue.isInCode()))
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Code reference expected."));
+ m_currentLValue.reset();
m_context.appendJump();
m_context << returnLabel;
@@ -201,9 +203,16 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
return false;
}
-void ExpressionCompiler::endVisit(MemberAccess&)
+void ExpressionCompiler::endVisit(MemberAccess& _memberAccess)
{
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Member access not yet implemented."));
+ if (asserts(m_currentLValue.isInStorage()))
+ BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Member access to a non-storage value."));
+ StructType const& type = dynamic_cast<StructType const&>(*_memberAccess.getExpression().getType());
+ unsigned memberIndex = type.memberNameToIndex(_memberAccess.getMemberName());
+ if (asserts(memberIndex <= type.getMemberCount()))
+ BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Member not found in struct during compilation."));
+ m_context << type.getStorageOffsetOfMember(memberIndex) << eth::Instruction::ADD;
+ m_currentLValue.retrieveValueIfLValueNotRequested(_memberAccess);
}
bool ExpressionCompiler::visit(IndexAccess& _indexAccess)