public override AstNode Visit(BinaryAssignOperation node) { // Begin the node. builder.BeginNode(node); // Get the expressions. Expression left = node.GetVariable(); Expression right = node.GetValue(); // Get the types. IChelaType leftType = left.GetNodeType(); IChelaType rightType = right.GetNodeType(); IChelaType coercionType = node.GetCoercionType(); IChelaType secondCoercion = node.GetSecondCoercion(); // Get the variable. Variable variable = (Variable)left.GetNodeValue(); left.Accept(this); // Duplicate the variable reference. DuplicateReference(node, variable); // If the variable is an event, if(variable.IsEvent()) { // Use event functions. EventVariable eventVar = (EventVariable)variable; // Send the argument. right.Accept(this); Cast(node, right.GetNodeValue(), rightType, secondCoercion); // Select the correct function. Function modifier = null; if(node.GetOperation() == BinaryOperation.OpAdd) modifier = eventVar.AddModifier; else modifier = eventVar.RemoveModifier; // Invoke the modifier. if(!modifier.IsStatic()) { Method method = (Method)modifier; if(method.IsVirtual()) builder.CreateCallVirtual(method, 2); else builder.CreateCall(method, 2); } else { builder.CreateCall(modifier, 1); } // Return the node. return builder.EndNode(); } // Duplicate again. DuplicateReference(node, variable); // Read the variable. Cast(node, variable, leftType, coercionType); // Send the right operand. right.Accept(this); if(rightType != secondCoercion) Cast(node, right.GetNodeValue(), rightType, secondCoercion); // Get the overloaded operator. Function op = node.GetOverload(); // Perform the operation if(op != null) { // Use the overloaded operation. builder.CreateCall(op, 2); // Coerce the result. IChelaType opResult = op.GetFunctionType().GetReturnType(); if(opResult != coercionType) builder.CreateCast(coercionType); } else { switch(node.GetOperation()) { case BinaryOperation.OpAdd: builder.CreateAdd(); break; case BinaryOperation.OpSub: builder.CreateSub(); break; case BinaryOperation.OpMul: builder.CreateMul(); break; case BinaryOperation.OpDiv: builder.CreateDiv(); break; case BinaryOperation.OpMod: builder.CreateMod(); break; case BinaryOperation.OpBitAnd: builder.CreateAnd(); break; case BinaryOperation.OpBitOr: builder.CreateOr(); break; case BinaryOperation.OpBitXor: builder.CreateXor(); break; case BinaryOperation.OpBitLeft: builder.CreateShLeft(); break; case BinaryOperation.OpBitRight: builder.CreateShRight(); break; case BinaryOperation.OpLT: case BinaryOperation.OpGT: case BinaryOperation.OpEQ: case BinaryOperation.OpNEQ: case BinaryOperation.OpLEQ: case BinaryOperation.OpGEQ: case BinaryOperation.OpLAnd: case BinaryOperation.OpLOr: // Shouldn't reach here. break; } } // Now, perform the assignment. PerformAssignment(node, variable); // Set the node value. node.SetNodeValue(variable); return builder.EndNode(); }