예제 #1
0
        public override Type OutputType(out CompiledFragment newOperation)
        {
            newOperation = this;
            Type typeB = Input1.OutputType(out Input1);
            Type typeA = Input0.OutputType(out Input0);

            if (typeA != typeB)
            {
                bool BString = (typeB == typeof(string));
                if (typeA == typeof(string) || BString)
                {
                    if (BString)
                    {
                        // This is alright - convert Input0 to a ToString operation.
                        Input0 = Types.ToStringMethod(Method, Input0, typeA);
                        typeA  = typeof(string);
                    }
                    else
                    {
                        Input1 = Types.ToStringMethod(Method, Input1, typeB);
                        typeB  = typeof(string);
                    }
                }
            }
            if (typeA == typeof(string) && typeB == typeof(string))
            {
                // Adding two strings (concat).
                newOperation = new MethodOperation(Method, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }), Input0, Input1);
            }
            else
            {
                typeA = Numerical(typeA, typeB, "Addition", ref newOperation);
            }
            return(typeA);
        }
        public override Type OutputType(out CompiledFragment v)
        {
            v = this;
            Type TypeA = Input1.OutputType(out Input1);
            Type TypeB = Input0.OutputType(out Input0);

            return(Numerical(TypeA, TypeB, "Multiply", ref v));
        }
예제 #3
0
        public override Type OutputType(out CompiledFragment v)
        {
            v = this;
            Type typeA = Input1.OutputType(out Input1);
            Type typeB = Input0.OutputType(out Input0);

            return(Numerical(typeA, typeB, "Division", ref v));
        }
예제 #4
0
        public override Type OutputType(out CompiledFragment newOperation)
        {
            newOperation = this;
            Type typeB = Input1.OutputType(out Input1);

            if (Input0 == null)
            {
                // Negation
                return(Numerical(ref Input1, typeB, typeof(float)));
            }
            Type typeA = Input0.OutputType(out Input0);

            return(Numerical(typeA, typeB, "Subtraction", ref newOperation));
        }
예제 #5
0
        public override Type OutputType(out CompiledFragment v)
        {
            v = this;
            Type typeA = Input0.OutputType(out Input0);
            Type typeB = Input1.OutputType(out Input1);

            CompiledFragment equalityOverload = null;

            FindOverload("Equality", typeA, typeB, ref equalityOverload);
            if (equalityOverload != null)
            {
                v = equalityOverload;
            }
            return(typeof(bool));
        }
예제 #6
0
        public override Type OutputType(out CompiledFragment v)
        {
            v = this;
            Type typeA = Input0.OutputType(out Input0);
            Type typeB = Input1.OutputType(out Input1);

            CompiledFragment overload = null;

            FindOverload("GreaterThan", typeA, typeB, ref overload);

            if (overload != null)
            {
                v = overload;
            }

            return(typeof(bool));
        }
예제 #7
0
 public override Type OutputType(out CompiledFragment v)
 {
     v = this;
     Input1.OutputType(out Input1);
     return(Input0.OutputType(out Input0));
 }
        public override void OutputIL(NitroIL into)
        {
            Type type2 = Input1.OutputType(out Input1);

            // Is it something which is being ["indexed"]? May apply to properties too.
            bool indexOperation    = (Input0.GetType() == typeof(IndexOperation));
            bool propertyOperation = (Input0.GetType() == typeof(PropertyOperation));

            if (indexOperation || propertyOperation)
            {
                // Hook up what we will be setting for the index to handle if it needs to.
                // Note that the object will not change as we have already run it's OutputType call above.
                ((Operation)Input0).Input0 = Input1;
            }

            // Update input0 by computing the type it outputs:
            Type type1 = Input0.OutputType(out Input0);

            object value = Input0.ActiveValue();

            if (value.GetType() != typeof(LocalVariable))
            {
                // Local vars can change type so this doesn't affect them.

                if (type1 == null)
                {
                    Error("Can't set to nothing.");
                }

                if (type2 == null)
                {
                    if (type1.IsValueType)
                    {
                        Error("Can't set " + type1 + " to null because it's a value type.");
                    }
                }
                else if (!type1.IsAssignableFrom(type2))
                {
                    Error("Can't implicity convert " + type2 + " to " + type1 + ".");
                }
            }

            if (Types.IsTypeOf(value, typeof(ISettable)))
            {
                ISettable Value = (ISettable)value;

                Value.OutputTarget(into);
                Input1.OutputIL(into);
                Value.OutputSet(into, type2);

                if (Output)
                {
                    // Daisy chaining these sets.
                    Input0.OutputIL(into);
                }
            }
            else if (indexOperation && value.GetType() == typeof(MethodOperation))
            {
                // This is ok! We've called something like obj["hello"]=input1;
                // Just output the method call:
                Input0.OutputIL(into);

                if (Output)
                {
                    Error("Can't daisy chain with an indexer. Place your indexed object furthest left.");
                }
            }
            else if (propertyOperation && value.GetType() == typeof(MethodOperation) && ((MethodOperation)value).MethodName == "set_Item")
            {
                // This is also ok - we've done something like object.property=value; and it mapped to object["property"]=value;
                // Just output the method call:
                Input0.OutputIL(into);

                if (Output)
                {
                    Error("Can't daisy chain with a property set here. Place your indexed object furthest left.");
                }
            }
            else
            {
                Error("Attempted to set to something (a " + value.GetType() + ") that isn't a variable.");
            }
        }