internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
{
// TODO:
// {target}[{arguments}] op= rhs
// we need to evaluate {arguments} once: http://ironruby.codeplex.com/workitem/4525
// first, read target into a temp:
MSA.Expression transformedLeftTarget = _left.TransformTargetRead(gen);
MSA.Expression leftTargetTemp;
if (transformedLeftTarget != null)
{
leftTargetTemp = gen.CurrentScope.DefineHiddenVariable(String.Empty, transformedLeftTarget.Type);
}
else
{
leftTargetTemp = null;
}
MSA.Expression transformedRight = _right.TransformRead(gen);
// lhs &&= rhs --> lhs && (lhs = rhs)
// lhs ||= rhs --> lhs || (lhs = rhs)
if (Operation == Symbols.And || Operation == Symbols.Or)
{
MSA.Expression transformedLeftRead = _left.TransformRead(gen,
(transformedLeftTarget != null) ? Ast.Assign(leftTargetTemp, transformedLeftTarget) : null,
true // tryRead
);
MSA.Expression transformedWrite = _left.TransformWrite(gen, leftTargetTemp, transformedRight);
if (Operation == Symbols.And)
{
return(AndExpression.TransformRead(gen, transformedLeftRead, transformedWrite));
}
else
{
return(OrExpression.TransformRead(gen, transformedLeftRead, transformedWrite));
}
}
else
{
// lhs op= rhs --> lhs = lhs op rhs
if (Operation != null)
{
MSA.Expression transformedLeftRead = _left.TransformRead(gen, leftTargetTemp, false);
transformedRight = MethodCall.TransformRead(this, gen, false, Operation, transformedLeftRead, null, null, transformedRight, null);
}
// transform lhs write assigning lhs-target temp:
return(_left.TransformWrite(gen,
(transformedLeftTarget != null) ? Ast.Assign(leftTargetTemp, transformedLeftTarget) : null,
transformedRight
));
}
}