ilcclib.Converter.CIL.CILConverter.BinaryExpression C# (CSharp) Method

BinaryExpression() private method

private BinaryExpression ( CParser BinaryExpression ) : void
BinaryExpression CParser
return void
        public void BinaryExpression(CParser.BinaryExpression BinaryExpression)
        {
            var Operator = BinaryExpression.Operator;

            var Left = BinaryExpression.Left;
            var LeftCType = Left.GetCachedCType(this);
            var LeftType = ConvertCTypeToType(LeftCType);

            var Right = BinaryExpression.Right;
            var RightCType = Right.GetCachedCType(this);
            var RightType = ConvertCTypeToType(RightCType);

            // Assignments
            switch (Operator)
            {
                case "<<=":
                case ">>=":
                case "&=":
                case "|=":
                case "^=":
                case "*=":
                case "/=":
                case "%=":
                case "-=":
                case "+=":
                case "=":
                    {
                        LocalBuilder LeftValueLocal = null;

                        if (RequireYieldResult)
                        {
                            LeftValueLocal = SafeILGenerator.DeclareLocal(LeftType, "TempLocal");
                        }

                        var LeftFieldAccess = Left as CParser.FieldAccessExpression;
                        FieldInfo FieldToStore = null;
                        MethodInfo MethodInfoToCallSet = null;
                        MethodInfo MethodInfoToCallGet = null;

                        // This is a field? Instead of loading the address try to perform a StoreField.
                        if (LeftFieldAccess != null && LeftFieldAccess.Operator == ".")
                        {
                            var StructureCType = LeftFieldAccess.LeftExpression.GetCachedCType(this);
                            var StructureType = ConvertCTypeToType(StructureCType);

                            FieldToStore = StructureType.GetField(LeftFieldAccess.FieldName);
                            MethodInfoToCallSet = StructureType.GetMethod("set_" + LeftFieldAccess.FieldName);
                            MethodInfoToCallGet = StructureType.GetMethod("get_" + LeftFieldAccess.FieldName);

                            if (FieldToStore == null && MethodInfoToCallSet == null)
                            {
                                throw(new InvalidOperationException("Null"));
                            }

                            DoGenerateAddress(true, () =>
                            {
                                Traverse(LeftFieldAccess.LeftExpression);
                            });

                        }
                        // Other kind, get the address and later it will perform a StoreIndirect.
                        else
                        {
                            DoGenerateAddress(true, () =>
                            {
                                Traverse(Left);
                            });
                        }

                        // Just store.
                        if (Operator == "=")
                        {
                            DoGenerateAddress(false, () =>
                            {
                                Traverse(Right);
                            });
                        }
                        // Store the value modified.
                        else
                        {
                            SafeILGenerator.Duplicate();

                            if (MethodInfoToCallGet != null)
                            {
                                SafeILGenerator.Call(MethodInfoToCallGet);
                            }
                            else
                            {
                                SafeILGenerator.LoadIndirect(LeftType);
                            }

                            DoGenerateAddress(false, () =>
                            {
                                Traverse(Right);
                            });
                            _DoBinaryOperation(Operator.Substring(0, Operator.Length - 1), LeftCType.GetCSimpleType().Sign);
                        }

                        // Convert the value to the LeftType.
                        SafeILGenerator.ConvertTo(LeftType);

                        // Stores the value into the temp variable without poping it.
                        if (LeftValueLocal != null)
                        {
                            SafeILGenerator.Duplicate();
                            SafeILGenerator.StoreLocal(LeftValueLocal);
                        }

                        // Stores the result
                        if (FieldToStore != null)
                        {
                            SafeILGenerator.StoreField(FieldToStore);
                        }
                        else if (MethodInfoToCallSet != null)
                        {
                            SafeILGenerator.Call(MethodInfoToCallSet);
                        }
                        else
                        {
                            SafeILGenerator.StoreIndirect(LeftType);
                        }

                        // Yields the result.
                        if (LeftValueLocal != null)
                        {
                            SafeILGenerator.LoadLocal(LeftValueLocal);
                        }
                    }
                    return;
                default:
                    {
                        // Pointer operations.
                        if (LeftType.IsPointer || RightType.IsPointer)
                        {
                            switch (Operator)
                            {
                                case "+":
                                    DoGenerateAddress(false, () =>
                                    {
                                        Traverse(Left);
                                        //Traverse(Right);
                                        Traverse(new CParser.BinaryExpression(Right, "*", new CParser.SizeofTypeExpression(((CPointerType)LeftCType).ElementCType)));
                                    });

                                    //SafeILGenerator.Sizeof(LeftType.GetElementType());
                                    //SafeILGenerator.BinaryOperation(SafeBinaryOperator.MultiplyUnsigned);

                                    SafeILGenerator.BinaryOperation(SafeBinaryOperator.AdditionUnsigned);
                                    break;
                                case "-":
                                    // TODO: Check both types?!
                                    DoGenerateAddress(false, () =>
                                    {
                                        Traverse(Left);
                                        Traverse(Right);
                                    });
                                    SafeILGenerator.BinaryOperation(SafeBinaryOperator.SubstractionSigned);
                                    SafeILGenerator.Sizeof(LeftType.GetElementType());
                                    SafeILGenerator.BinaryOperation(SafeBinaryOperator.DivideUnsigned);
                                    break;
                                case ">=":
                                case "<=":
                                case ">":
                                case "<":
                                case "==":
                                case "!=":
                                case "&&":
                                case "||":
                                    DoGenerateAddress(false, () =>
                                    {
                                        Traverse(Left);
                                        Traverse(Right);
                                    });
                                    _DoBinaryOperation(Operator, Left.GetCachedCType(this).GetCSimpleType().Sign);
                                    break;
                                default:
                                    Console.Error.WriteLine("Not supported operator '{0}' for pointer aritmetic types : {1}, {2}", Operator, LeftType, RightType);
                                    throw (new NotImplementedException(String.Format("Not supported operator '{0}' for pointer aritmetic types : {1}, {2}", Operator, LeftType, RightType)));
                            }
                        }
                        // Non-pointer operations
                        else
                        {
                            DoBinaryOperation(Operator, Left, Right);
                        }
                    }
                    break;
            }
        }