Exemple #1
0
        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();
        }