public override Statement VisitExpressionStatement(ExpressionStatement statement)
{
// Check for statements that require special handling
AssignmentExpression assignmentExpr = statement.Expression as AssignmentExpression;
AssignmentStatement assignmentStatement = null;
MethodCall methodCall = statement.Expression as MethodCall;
SelfExpression selfAccess = statement.Expression as SelfExpression;
UnaryExpression choose = null;
if (assignmentExpr != null)
{
assignmentStatement = assignmentExpr.AssignmentStatement as AssignmentStatement;
if (assignmentStatement != null && assignmentStatement.Source is MethodCall)
methodCall = (MethodCall)assignmentStatement.Source;
if (assignmentStatement != null && assignmentStatement.Source is UnaryExpression &&
assignmentStatement.Source.NodeType == (NodeType)ZingNodeType.Choose)
choose = (UnaryExpression)assignmentStatement.Source;
if (assignmentStatement != null && assignmentStatement.Source is BinaryExpression &&
assignmentStatement.Target.Type is Set)
{
BinaryExpression binaryExpression = (BinaryExpression)assignmentStatement.Source;
this.validSetOperations.Add(binaryExpression, null);
if (SameVariable(assignmentStatement.Target, binaryExpression.Operand1))
{
// all is well
}
else if (SameVariable(assignmentStatement.Target, binaryExpression.Operand2))
{
// swap operands to put the statement in its desired form
Expression tmp = binaryExpression.Operand1;
binaryExpression.Operand1 = binaryExpression.Operand2;
binaryExpression.Operand2 = tmp;
}
else
{
this.HandleError(statement, Error.InvalidSetAssignment);
return null;
}
}
//
// If the source and target types aren't equal, but both are numeric, then we
// insert an implied cast to the target type. If & when we add an explicit cast
// operator to Zing, then this can be removed.
//
if (assignmentStatement != null &&
assignmentStatement.Source != null && assignmentStatement.Source.Type != null &&
assignmentStatement.Target != null && assignmentStatement.Target.Type != null &&
assignmentStatement.Source.Type != assignmentStatement.Target.Type &&
assignmentStatement.Source.Type.IsPrimitiveNumeric &&
assignmentStatement.Target.Type.IsPrimitiveNumeric)
{
// Wrap a cast operator around the source expression
BinaryExpression binExpr = new BinaryExpression(assignmentStatement.Source,
new MemberBinding(null, assignmentStatement.Target.Type),
NodeType.Castclass, assignmentStatement.Source.SourceContext);
binExpr.Type = assignmentStatement.Target.Type;
assignmentStatement.Source = binExpr;
}
}
if (methodCall != null)
this.validMethodCalls.Add(methodCall, null);
if (selfAccess != null)
this.validSelfAccess.Add(selfAccess, null);
if (choose != null)
this.validChooses.Add(choose, null);
return base.VisitExpressionStatement(statement);
}