Esempio n. 1
0
        private Operand GetOperandValue(string token, Token tokenForExceptionInfo)
        {
            Operand operand = null;

            if (_currentMethod != null && _currentFormalArgumentList.Contains(token))
            {
                operand = _g.Arg(token);
            }
            else if (_localVariablesTable.ContainsKey(token))
            {
                operand = _localVariablesTable[token];
            }
            else if (!token.Equals(GrammarHelper.This))
            {
                try
                {
                    operand = _g.This().Field(token);
                }
                catch (Exception ex)
                {
                    throw new CodeGenerationException(MessagesHelper.NotFoundVariableEx,
                                                      tokenForExceptionInfo != null ? tokenForExceptionInfo.ToStringInfo() : token, ex);
                }
            }
            else
            {
                operand = _g.This();
            }

            return(operand);
        }
        // example based on the MSDN Operator Overloading Sample (complex.cs)
        public static void GenComplex(AssemblyGen ag)
        {
            var st  = ag.StaticFactory;
            var exp = ag.ExpressionFactory;

            ITypeMapper m       = ag.TypeMapper;
            TypeGen     Complex = ag.Public.Struct("Complex");
            {
                FieldGen real      = Complex.Public.Field(typeof(int), "real");
                FieldGen imaginary = Complex.Public.Field(typeof(int), "imaginary");

                CodeGen g = Complex.Public.Constructor()
                            .Parameter(typeof(int), "real")
                            .Parameter(typeof(int), "imaginary")
                ;
                {
                    g.Assign(real, g.Arg("real"));
                    g.Assign(imaginary, g.Arg("imaginary"));
                }

                // Declare which operator to overload (+), the types
                // that can be added (two Complex objects), and the
                // return type (Complex):
                g = Complex.Operator(Operator.Add, Complex, Complex, "c1", Complex, "c2");

                {
                    var c1 = g.Arg("c1");
                    var c2 = g.Arg("c2");
                    g.Return(exp.New(Complex, c1.Field("real") + c2.Field("real"), c1.Field("imaginary") + c2.Field("imaginary")));
                }

                // Override the ToString method to display an complex number in the suitable format:
                g = Complex.Public.Override.Method(typeof(string), "ToString");
                {
                    g.Return(st.Invoke(typeof(string), "Format", "{0} + {1}i", real, imaginary));
                }

                g = Complex.Public.Static.Method(typeof(void), "Main");
                {
                    var num1 = g.Local(exp.New(Complex, 2, 3));
                    var num2 = g.Local(exp.New(Complex, 3, 4));

                    // Add two Complex objects (num1 and num2) through the
                    // overloaded plus operator:
                    var sum = g.Local(num1 + num2);

                    // Print the numbers and the sum using the overriden ToString method:
                    g.WriteLine("First complex number:  {0}", num1);
                    g.WriteLine("Second complex number: {0}", num2);
                    g.WriteLine("The sum of the two numbers: {0}", sum);
                }
            }
        }
Esempio n. 3
0
        // example based on the MSDN Delegates Sample (compose.cs)
        public static void GenCompose(AssemblyGen ag)
        {
            var st  = ag.StaticFactory;
            var exp = ag.ExpressionFactory;

            TypeGen myDelegate = ag.Delegate(typeof(void), "MyDelegate").Parameter(typeof(string), "string");

            TypeGen myClass = ag.Class("MyClass");
            {
                CodeGen g = myClass.Public.Static.Method(typeof(void), "Hello").Parameter(typeof(string), "s");
                {
                    g.WriteLine("  Hello, {0}!", g.Arg("s"));
                }

                g = myClass.Public.Static.Method(typeof(void), "Goodbye").Parameter(typeof(string), "s");
                {
                    g.WriteLine("  Goodbye, {0}!", g.Arg("s"));
                }

                g = myClass.Public.Static.Method(typeof(void), "Main");
                {
                    ContextualOperand a = g.Local(), b = g.Local(), c = g.Local(), d = g.Local();

                    // Create the delegate object a that references
                    // the method Hello:
                    ITypeMapper typeMapper = ag.TypeMapper;
                    g.Assign(a, exp.NewDelegate(myDelegate, myClass, "Hello"));
                    // Create the delegate object b that references
                    // the method Goodbye:
                    ITypeMapper typeMapper1 = ag.TypeMapper;
                    g.Assign(b, exp.NewDelegate(myDelegate, myClass, "Goodbye"));
                    // The two delegates, a and b, are composed to form c,
                    // which calls both methods in order:
                    g.Assign(c, a + b);
                    // Remove a from the composed delegate, leaving d,
                    // which calls only the method Goodbye:
                    g.Assign(d, c - a);

                    g.WriteLine("Invoking delegate a:");
                    g.InvokeDelegate(a, "A");
                    g.WriteLine("Invoking delegate b:");
                    g.InvokeDelegate(b, "B");
                    g.WriteLine("Invoking delegate c:");
                    g.InvokeDelegate(c, "C");
                    g.WriteLine("Invoking delegate d:");
                    g.InvokeDelegate(d, "D");
                }
            }
        }
Esempio n. 4
0
        // example based on the MSDN Structs Sample (struct2.cs)
        public static void GenStruct2(AssemblyGen ag)
        {
            var st  = ag.StaticFactory;
            var exp = ag.ExpressionFactory;

            TypeGen TheClass = ag.Class("TheClass");
            {
                TheClass.Public.Field(typeof(int), "x");
            }

            TypeGen TheStruct = ag.Struct("TheStruct");
            {
                TheStruct.Public.Field(typeof(int), "x");
            }

            TypeGen TestClass = ag.Class("TestClass");
            {
                CodeGen g = TestClass.Public.Static.Method(typeof(void), "structtaker").Parameter(TheStruct, "s");
                {
                    ITypeMapper typeMapper = ag.TypeMapper;
                    g.Assign(g.Arg("s").Field("x"), 5);
                }

                g = TestClass.Public.Static.Method(typeof(void), "classtaker").Parameter(TheClass, "c");
                {
                    ITypeMapper typeMapper = ag.TypeMapper;
                    g.Assign(g.Arg("c").Field("x"), 5);
                }

                g = TestClass.Public.Static.Method(typeof(void), "Main");
                {
                    var a = g.Local(TheStruct);
                    g.InitObj(a);
                    ITypeMapper typeMapper4 = ag.TypeMapper;
                    var         b           = g.Local(exp.New(TheClass));

                    ITypeMapper typeMapper = ag.TypeMapper;
                    g.Assign(a.Field("x"), 1);
                    ITypeMapper typeMapper2 = ag.TypeMapper;
                    g.Assign(b.Field("x"), 1);
                    g.Invoke(TestClass, "structtaker", a);
                    g.Invoke(TestClass, "classtaker", b);
                    ITypeMapper typeMapper3 = ag.TypeMapper;
                    g.WriteLine("a.x = {0}", a.Field("x"));
                    ITypeMapper typeMapper1 = ag.TypeMapper;
                    g.WriteLine("b.x = {0}", b.Field("x"));
                }
            }
        }
Esempio n. 5
0
        public static void GenCmdLine2(AssemblyGen ag)
        {
            ITypeMapper       m   = ag.TypeMapper;
            var               st  = ag.StaticFactory;
            var               exp = ag.ExpressionFactory;
            ContextualOperand x;
            TypeGen           commandLine3 = ag.Public.Class("CommandLine3");
            {
                CodeGen g = commandLine3.Public.Method(typeof(void), "Main3").Parameter(typeof(string[]), "args");
                {
                    var args = g.Arg("args");

                    g.WriteLine("Number of command line 3 parameters = {0}",
                                args.Property("Length"));
                    var s = g.ForEach(typeof(string), args);
                    {
                        g.WriteLine(s);
                    }
                    g.End();
                    g.WriteLine(g.This().Invoke("GetType").Property("BaseType").Property("Name"));

                    var inst = st.Field(typeof(CmdLineTestClass), "Default");
                    g.WriteLine(inst.Invoke("GetValue"));
                }


                commandLine3.Public.CommonConstructor();
            }

            TypeGen commandLine2 = ag.Public.Class("CommandLine2");
            {
                CodeGen g = commandLine2.Public.Static.Method(typeof(void), "Main").Parameter(typeof(string[]), "args");
                {
                    //g.Invoke(CommandLine3, "Main3", g.Arg("args"));
                    var cl = g.Local(exp.New(commandLine3));
                    g.WriteLine(0);
                    g.Invoke(cl, "Main3", g.Arg("args"));
                    var args = g.Arg("args");
                    g.WriteLine("Number of command line parameters = {0}",
                                args.Property("Length"));
                    var s = g.ForEach(typeof(string), args);
                    {
                        g.WriteLine(s);
                    }
                    g.End();
                }
            }
        }
        public void Execute()
        {
            DynamicMethodGen dmg = DynamicMethodGen.Static(typeof(TryCatchReachibilityBug)).Method(typeof(string), new TypeMapper())
                                   .Parameter(typeof(string), "name")
                                   .Parameter(typeof(string), "other");
            CodeGen g = dmg.GetCode();

            {
                g.Try();
                {
                    var name = g.Local(typeof(string), g.Arg("name"));
                    g.WriteLine("Hello " + name + "!");
                }
                g.CatchAll();
                {
                    g.WriteLine("Error");
                    g.Return("a");
                }
                g.End();
                var l = g.Local();
                g.Eval(l.Assign(dmg.StaticFactory.Invoke(typeof(TryCatchReachibilityBug), nameof(CallMe), g.Arg("other"), 2)));
                g.Return(l);
            }
            dmg.GetCompletedDynamicMethod(true);
        }
Esempio n. 7
0
        // example based on the MSDN Delegates Sample (compose.cs)
        public static void GenCompose(AssemblyGen ag)
        {
            TypeGen MyDelegate = ag.DelegateVoid("MyDelegate").Parameter <string>("string");

            TypeGen MyClass = ag.Class("MyClass");
            {
                CodeGen g = MyClass.Public.Static.Void("Hello").Parameter <string>("s");
                {
                    g.WriteLine("  Hello, {0}!", g.Arg("s"));
                }

                g = MyClass.Public.Static.Void("Goodbye").Parameter <string>("s");
                {
                    g.WriteLine("  Goodbye, {0}!", g.Arg("s"));
                }

                g = MyClass.Public.Static.Void("Main");
                {
                    Operand a = g.Local(), b = g.Local(), c = g.Local(), d = g.Local();

                    // Create the delegate object a that references
                    // the method Hello:
                    g.Assign(a, Exp.NewDelegate(MyDelegate, MyClass, "Hello"));
                    // Create the delegate object b that references
                    // the method Goodbye:
                    g.Assign(b, Exp.NewDelegate(MyDelegate, MyClass, "Goodbye"));
                    // The two delegates, a and b, are composed to form c,
                    // which calls both methods in order:
                    g.Assign(c, a + b);
                    // Remove a from the composed delegate, leaving d,
                    // which calls only the method Goodbye:
                    g.Assign(d, c - a);

                    g.WriteLine("Invoking delegate a:");
                    g.InvokeDelegate(a, "A");
                    g.WriteLine("Invoking delegate b:");
                    g.InvokeDelegate(b, "B");
                    g.WriteLine("Invoking delegate c:");
                    g.InvokeDelegate(c, "C");
                    g.WriteLine("Invoking delegate d:");
                    g.InvokeDelegate(d, "D");
                }
            }
        }
Esempio n. 8
0
        // example based on the MSDN Structs Sample (struct2.cs)
        public static void GenStruct2(AssemblyGen ag)
        {
            TypeGen TheClass = ag.Class("TheClass");
            {
                TheClass.Public.Field <int>("x");
            }

            TypeGen TheStruct = ag.Struct("TheStruct");
            {
                TheStruct.Public.Field <int>("x");
            }

            TypeGen TestClass = ag.Class("TestClass");
            {
                CodeGen g = TestClass.Public.Static.Void("structtaker").Parameter(TheStruct, "s");
                {
                    g.Assign(g.Arg("s").Field("x"), 5);
                }

                g = TestClass.Public.Static.Void("classtaker").Parameter(TheClass, "c");
                {
                    g.Assign(g.Arg("c").Field("x"), 5);
                }

                g = TestClass.Public.Static.Void("Main");
                {
                    Operand a = g.Local(TheStruct);
                    g.InitObj(a);
                    Operand b = g.Local(Exp.New(TheClass));

                    g.Assign(a.Field("x"), 1);
                    g.Assign(b.Field("x"), 1);
                    g.Invoke(TestClass, "structtaker", a);
                    g.Invoke(TestClass, "classtaker", b);
                    g.WriteLine("a.x = {0}", a.Field("x"));
                    g.WriteLine("b.x = {0}", b.Field("x"));
                }
            }
        }
Esempio n. 9
0
        public void CreateComWrapper(string filePath, string dllPath, string p1, string p2)
        {
            AssemblyGen ag = new AssemblyGen(filePath);

            Assembly asm = Assembly.LoadFrom(dllPath);

            ag.Attribute(asm.GetType("WaveTech.Scutex.Model.LicenseAttribute"), p1, p2);

            ag.Attribute(typeof(System.Runtime.InteropServices.ComVisibleAttribute), true);
            ag.Attribute(typeof(System.Reflection.AssemblyVersionAttribute), "1.0.0.0");
            ag.Attribute(typeof(System.Reflection.AssemblyFileVersionAttribute), "1.0.0.0");
            ag.Attribute(typeof(System.Runtime.InteropServices.GuidAttribute), "DC7DE67E-EA7A-4D26-89FF-FECEF2937268");

            ag.Namespace("ScutexLicensingCCW");

            TypeGen ComWrapper = ag.Public.Class(_stringDataGeneratorProvider.GenerateRandomString(10, 50, false, false)).Attribute(typeof(System.Runtime.InteropServices.ClassInterfaceAttribute), System.Runtime.InteropServices.ClassInterfaceType.AutoDual);

            {
                CodeGen g1 = ComWrapper.Public.Constructor();

                CodeGen g2 = ComWrapper.Public.Method(typeof(int), "Validate").Parameter(typeof(int), "interactionMode");
                {
                    Operand licensingManager = g2.Local(Exp.New(asm.GetType("WaveTech.Scutex.Licensing.LicensingManager"), g2.This()));
                    Operand scutexLicensing  = g2.Local(asm.GetType("WaveTech.Scutex.Model.ScutexLicense"));

                    Operand value = g2.Local(asm.GetType("WaveTech.Scutex.Model.InteractionModes"));
                    g2.Assign(value, g2.Arg("interactionMode").Cast(asm.GetType("WaveTech.Scutex.Model.InteractionModes")));

                    g2.Assign(scutexLicensing, licensingManager.Invoke("Validate", value));

                    g2.Return(0);
                }

                CodeGen g3 = ComWrapper.Public.Method(typeof(int), "Register").Parameter(typeof(string), "licenseKey");
                {
                    Operand licensingManager = g3.Local(Exp.New(asm.GetType("WaveTech.Scutex.Licensing.LicensingManager"), g3.This()));
                    Operand scutexLicensing  = g3.Local(asm.GetType("WaveTech.Scutex.Model.ScutexLicense"));

                    g3.Assign(scutexLicensing, licensingManager.Invoke("Register", g3.Arg("licenseKey")));

                    g3.Return(0);
                }
            }

            ag.Save();
            asm = null;
        }
Esempio n. 10
0
 public static void GenCmdLine2(AssemblyGen ag)
 {
     TypeGen CommandLine2 = ag.Public.Class("CommandLine2");
     {
         CodeGen g = CommandLine2.Public.Static.Method(typeof(void), "Main").Parameter(typeof(string[]), "args");
         {
             Operand args = g.Arg("args");
             g.WriteLine("Number of command line parameters = {0}",
                         args.Property("Length"));
             Operand s = g.ForEach(typeof(string), args);
             {
                 g.WriteLine(s);
             }
             g.End();
         }
     }
 }
Esempio n. 11
0
 public static void GenHello3(AssemblyGen ag)
 {
     TypeGen Hello3 = ag.Public.Class("Hello3");
     {
         CodeGen g = Hello3.Public.Static.Method(typeof(void), "Main").Parameter(typeof(string[]), "args");
         {
             Operand args = g.Arg("args");
             g.WriteLine("Hello, World!");
             g.WriteLine("You entered the following {0} command line arguments:",
                         args.ArrayLength());
             Operand i = g.Local();
             g.For(i.Assign(0), i < args.ArrayLength(), i.Increment());
             {
                 g.WriteLine("{0}", args[i]);
             }
             g.End();
         }
     }
 }
Esempio n. 12
0
        public void Execute()
        {
            ConsoleTester.ClearAndStartCapturing();

            DynamicMethodGen dmg = DynamicMethodGen.Static(typeof(DynamicMethodTest)).Method(typeof(string), new TypeMapper())
                                   .Parameter(typeof(string), "name")
                                   .Parameter(typeof(string), "other");
            CodeGen g = dmg.GetCode();
            {
                g.Try();
                {
                    var name = g.Local(typeof(string), g.Arg("name"));
                    g.WriteLine("Hello " + name + "!");
                }
                g.CatchAll();
                {
                    g.WriteLine("Error");
                }
                g.End();
                g.Return(dmg.StaticFactory.Invoke(typeof(DynamicMethodTest), nameof(CallMe), g.Arg("other"), 2));
            }
            DynamicMethod dm = dmg.GetCompletedDynamicMethod(true);


            // reflection-style invocation
            Assert.That(dm.Invoke(null, new object[] { "Dynamic Method", "first1" }), Is.EqualTo("test240"));

            // delegate invocation
            Func <string, string, string> hello = (Func <string, string, string>)dm.CreateDelegate(typeof(Func <string, string, string>));

            Assert.That(hello("Delegate", "first1"), Is.EqualTo("test240"));

            ConsoleTester.AssertAndClear(@"Hello Dynamic Method!
Hello Delegate!
");
        }
Esempio n. 13
0
        // example based on the MSDN Events Sample (events1.cs)
        public static void GenEvents1(AssemblyGen ag)
        {
            TypeGen ChangedEventHandler, ListWithChangedEvent;

            using (ag.Namespace("MyCollections"))
            {
                // A delegate type for hooking up change notifications.
                ChangedEventHandler = ag.Delegate(typeof(void), "ChangedEventHandler").Parameter(typeof(object), "sender").Parameter(typeof(EventArgs), "e");

                // A class that works just like ArrayList, but sends event
                // notifications whenever the list changes.
                ListWithChangedEvent = ag.Public.Class("ListWithChangedEvent", typeof(ArrayList));
                {
                    // An event that clients can use to be notified whenever the
                    // elements of the list change.
                    EventGen Changed = ListWithChangedEvent.Public.Event(ChangedEventHandler, "Changed");

                    // Invoke the Changed event; called whenever list changes
                    CodeGen g = ListWithChangedEvent.Protected.Virtual.Method(typeof(void), "OnChanged").Parameter(typeof(EventArgs), "e");
                    {
                        g.If(Changed != null);
                        {
                            g.InvokeDelegate(Changed, g.This(), g.Arg("e"));
                        }
                        g.End();
                    }

                    // Override some of the methods that can change the list;
                    // invoke event after each
                    g = ListWithChangedEvent.Public.Override.Method(typeof(int), "Add").Parameter(typeof(object), "value");
                    {
                        Operand i = g.Local(g.Base().Invoke("Add", g.Arg("value")));
                        g.Invoke(g.This(), "OnChanged", Static.Field(typeof(EventArgs), "Empty"));
                        g.Return(i);
                    }

                    g = ListWithChangedEvent.Public.Override.Method(typeof(void), "Clear");
                    {
                        g.Invoke(g.Base(), "Clear");
                        g.Invoke(g.This(), "OnChanged", Static.Field(typeof(EventArgs), "Empty"));
                    }

                    g = ListWithChangedEvent.Public.Override.Indexer(typeof(object)).Index(typeof(int), "index").Setter();
                    {
                        g.Assign(g.Base()[g.Arg("index")], g.PropertyValue());
                        g.Invoke(g.This(), "OnChanged", Static.Field(typeof(EventArgs), "Empty"));
                    }
                }
            }

            using (ag.Namespace("TestEvents"))
            {
                TypeGen EventListener = ag.Class("EventListener");
                {
                    FieldGen List = EventListener.Field(ListWithChangedEvent, "List");

                    // This will be called whenever the list changes.
                    CodeGen g = EventListener.Private.Method(typeof(void), "ListChanged").Parameter(typeof(object), "sender").Parameter(typeof(EventArgs), "eventArgs");
                    {
                        g.WriteLine("This is called when the event fires.");
                    }

                    g = EventListener.Public.Constructor().Parameter(ListWithChangedEvent, "list");
                    {
                        g.Assign(List, g.Arg("list"));
                        // Add "ListChanged" to the Changed event on "List".
                        g.SubscribeEvent(List, "Changed", Exp.NewDelegate(ChangedEventHandler, g.This(), "ListChanged"));
                    }

                    g = EventListener.Public.Method(typeof(void), "Detach");
                    {
                        // Detach the event and delete the list
                        g.UnsubscribeEvent(List, "Changed", Exp.NewDelegate(ChangedEventHandler, g.This(), "ListChanged"));
                        g.Assign(List, null);
                    }
                }

                TypeGen Test = ag.Class("Test");
                {
                    // Test the ListWithChangedEvent class.
                    CodeGen g = Test.Public.Static.Method(typeof(void), "Main");
                    {
                        // Create a new list.
                        Operand list = g.Local(Exp.New(ListWithChangedEvent));

                        // Create a class that listens to the list's change event.
                        Operand listener = g.Local(Exp.New(EventListener, list));

                        // Add and remove items from the list.
                        g.Invoke(list, "Add", "item 1");
                        g.Invoke(list, "Clear");
                        g.Invoke(listener, "Detach");
                    }
                }
            }
        }
        // example based on the MSDN Collection Classes Sample (tokens2.cs)
        public static void GenTokens2(AssemblyGen ag)
        {
            TypeGen Tokens = ag.Public.Class("Tokens", typeof(object), typeof(IEnumerable));
            {
                FieldGen elements = Tokens.Private.Field(typeof(string[]), "elements");

                CodeGen g = Tokens.Constructor()
                            .Parameter(typeof(string), "source")
                            .Parameter(typeof(char[]), "delimiters")
                ;
                {
                    g.Assign(elements, g.Arg("source").Invoke("Split", g.Arg("delimiters")));
                }

                // Inner class implements IEnumerator interface:

                TypeGen TokenEnumerator = Tokens.Public.Class("TokenEnumerator", typeof(object), typeof(IEnumerator));
                {
                    FieldGen position = TokenEnumerator.Field(typeof(int), "position", -1);
                    FieldGen t        = TokenEnumerator.Field(Tokens, "t");

                    g = TokenEnumerator.Public.Constructor().Parameter(Tokens, "tokens");
                    {
                        g.Assign(t, g.Arg("tokens"));
                    }

                    g = TokenEnumerator.Public.Method(typeof(bool), "MoveNext");
                    {
                        g.If(position < t.Field("elements").ArrayLength() - 1);
                        {
                            g.Increment(position);
                            g.Return(true);
                        }
                        g.Else();
                        {
                            g.Return(false);
                        }
                        g.End();
                    }

                    g = TokenEnumerator.Public.Method(typeof(void), "Reset");
                    {
                        g.Assign(position, -1);
                    }

                    // non-IEnumerator version: type-safe
                    g = TokenEnumerator.Public.Property(typeof(string), "Current").Getter();
                    {
                        g.Return(t.Field("elements")[position]);
                    }

                    // IEnumerator version: returns object
                    g = TokenEnumerator.Public.PropertyImplementation(typeof(IEnumerator), typeof(object), "Current").Getter();
                    {
                        g.Return(t.Field("elements")[position]);
                    }
                }

                // IEnumerable Interface Implementation:

                // non-IEnumerable version
                g = Tokens.Public.Method(TokenEnumerator, "GetEnumerator");
                {
                    g.Return(Exp.New(TokenEnumerator, g.This()));
                }

                // IEnumerable version
                g = Tokens.Public.MethodImplementation(typeof(IEnumerable), typeof(IEnumerator), "GetEnumerator");
                {
                    g.Return(Exp.New(TokenEnumerator, g.This()).Cast(typeof(IEnumerator)));
                }

                // Test Tokens, TokenEnumerator

                g = Tokens.Static.Method(typeof(void), "Main");
                {
                    Operand f = g.Local(Exp.New(Tokens, "This is a well-done program.",
                                                Exp.NewInitializedArray(typeof(char), ' ', '-')));
                    Operand item = g.ForEach(typeof(string), f);                        // try changing string to int
                    {
                        g.WriteLine(item);
                    }
                    g.End();
                }
            }
        }
        // example based on the MSDN Explicit Interface Implementation Sample (explicit.cs)
        public static void GenExplicit2(AssemblyGen ag)
        {
            var st  = ag.StaticFactory;
            var exp = ag.ExpressionFactory;

            ITypeMapper m = ag.TypeMapper;
            // Declare the English units interface:
            TypeGen IEnglishDimensions = ag.Interface("IEnglishDimensions");
            {
                IEnglishDimensions.Method(typeof(float), "Length");
                IEnglishDimensions.Method(typeof(float), "Width");
            }

            // Declare the metric units interface:
            TypeGen IMetricDimensions = ag.Interface("IMetricDimensions");
            {
                IMetricDimensions.Method(typeof(float), "Length");
                IMetricDimensions.Method(typeof(float), "Width");
            }

            // Declare the "Box" class that implements the two interfaces:
            // IEnglishDimensions and IMetricDimensions:
            TypeGen Box = ag.Class("Box", typeof(object), IEnglishDimensions, IMetricDimensions);
            {
                FieldGen lengthInches = Box.Field(typeof(float), "lengthInches");
                FieldGen widthInches  = Box.Field(typeof(float), "widthInches");

                CodeGen g = Box.Public.Constructor()
                            .Parameter(typeof(float), "length")
                            .Parameter(typeof(float), "width")
                ;
                {
                    g.Assign(lengthInches, g.Arg("length"));
                    g.Assign(widthInches, g.Arg("width"));
                }
                // Explicitly implement the members of IEnglishDimensions:
                g = Box.MethodImplementation(IEnglishDimensions, typeof(float), "Length");
                {
                    g.Return(lengthInches);
                }
                g = Box.MethodImplementation(IEnglishDimensions, typeof(float), "Width");
                {
                    g.Return(widthInches);
                }
                // Explicitly implement the members of IMetricDimensions:
                g = Box.MethodImplementation(IMetricDimensions, typeof(float), "Length");
                {
                    g.Return(lengthInches * 2.54f);
                }
                g = Box.MethodImplementation(IMetricDimensions, typeof(float), "Width");
                {
                    g.Return(widthInches * 2.54f);
                }
                g = Box.Public.Static.Method(typeof(void), "Main");
                {
                    // Declare a class instance "myBox":
                    var myBox = g.Local(exp.New(Box, 30.0f, 20.0f));
                    // Declare an instance of the English units interface:
                    var eDimensions = g.Local(myBox.Cast(IEnglishDimensions));
                    // Declare an instance of the metric units interface:
                    var mDimensions = g.Local(myBox.Cast(IMetricDimensions));
                    // Print dimensions in English units:
                    g.WriteLine("Length(in): {0}", eDimensions.Invoke("Length"));
                    g.WriteLine("Width (in): {0}", eDimensions.Invoke("Width"));
                    // Print dimensions in metric units:
                    g.WriteLine("Length(cm): {0}", mDimensions.Invoke("Length"));
                    g.WriteLine("Width (cm): {0}", mDimensions.Invoke("Width"));
                }
            }
        }
Esempio n. 16
0
        // example based on the MSDN User-Defined Conversions Sample (conversion.cs)
        public static void GenConversion(AssemblyGen ag)
        {
            var st  = ag.StaticFactory;
            var exp = ag.ExpressionFactory;

            TypeGen RomanNumeral = ag.Struct("RomanNumeral");
            {
                FieldGen value = RomanNumeral.Private.Field(typeof(int), "value");

                CodeGen g = RomanNumeral.Public.Constructor().Parameter(typeof(int), "value");
                {
                    g.Assign(value, g.Arg("value"));
                }

                // Declare a conversion from an int to a RomanNumeral. Note the
                // the use of the operator keyword. This is a conversion
                // operator named RomanNumeral:
                g = RomanNumeral.Public.ImplicitConversionFrom(typeof(int));
                {
                    // Note that because RomanNumeral is declared as a struct,
                    // calling new on the struct merely calls the constructor
                    // rather than allocating an object on the heap:
                    g.Return(exp.New(RomanNumeral, g.Arg("value")));
                }

                // Declare an explicit conversion from a RomanNumeral to an int:
                g = RomanNumeral.Public.ExplicitConversionTo(typeof(int), "roman");
                {
                    ITypeMapper typeMapper = ag.TypeMapper;
                    g.Return(g.Arg("roman").Field("value"));
                }

                // Declare an implicit conversion from a RomanNumeral to
                // a string:
                g = RomanNumeral.Public.ImplicitConversionTo(typeof(string));
                {
                    g.Return("Conversion not yet implemented");
                }
            }

            TypeGen Test = ag.Class("Test");
            {
                CodeGen g = Test.Public.Static.Method(typeof(void), "Main");
                {
                    var numeral = g.Local(RomanNumeral);

                    g.Assign(numeral, 10);

                    // Call the explicit conversion from numeral to int. Because it is
                    // an explicit conversion, a cast must be used:
                    g.WriteLine(numeral.Cast(typeof(int)));

                    // Call the implicit conversion to string. Because there is no
                    // cast, the implicit conversion to string is the only
                    // conversion that is considered:
                    g.WriteLine(numeral);

                    // Call the explicit conversion from numeral to int and
                    // then the explicit conversion from int to short:
                    var s = g.Local(numeral.Cast(typeof(short)));

                    g.WriteLine(s);
                }
            }
        }
Esempio n. 17
0
        // example based on the MSDN User-Defined Conversions Sample (structconversion.cs)
        public static void GenStructConversion(AssemblyGen ag)
        {
            var st  = ag.StaticFactory;
            var exp = ag.ExpressionFactory;

            TypeGen BinaryNumeral = ag.Struct("BinaryNumeral");
            {
                FieldGen value = BinaryNumeral.Private.Field(typeof(int), "value");

                CodeGen g = BinaryNumeral.Public.Constructor().Parameter(typeof(int), "value");
                {
                    g.Assign(value, g.Arg("value"));
                }

                g = BinaryNumeral.Public.ImplicitConversionFrom(typeof(int));
                {
                    g.Return(exp.New(BinaryNumeral, g.Arg("value")));
                }

                g = BinaryNumeral.Public.ImplicitConversionTo(typeof(string));
                {
                    g.Return("Conversion not yet implemented");
                }

                g = BinaryNumeral.Public.ExplicitConversionTo(typeof(int), "binary");
                {
                    ITypeMapper typeMapper = ag.TypeMapper;
                    g.Return(g.Arg("binary").Field("value"));
                }
            }

            TypeGen RomanNumeral = ag.Struct("RomanNumeral");
            {
                FieldGen value = RomanNumeral.Private.Field(typeof(int), "value");

                CodeGen g = RomanNumeral.Public.Constructor().Parameter(typeof(int), "value");
                {
                    g.Assign(value, g.Arg("value"));
                }

                g = RomanNumeral.Public.ImplicitConversionFrom(typeof(int));
                {
                    g.Return(exp.New(RomanNumeral, g.Arg("value")));
                }

                g = RomanNumeral.Public.ImplicitConversionFrom(BinaryNumeral, "binary");
                {
                    g.Return(exp.New(RomanNumeral, g.Arg("binary").Cast(typeof(int))));
                }

                g = RomanNumeral.Public.ExplicitConversionTo(typeof(int), "roman");
                {
                    ITypeMapper typeMapper = ag.TypeMapper;
                    g.Return(g.Arg("roman").Field("value"));
                }

                g = RomanNumeral.Public.ImplicitConversionTo(typeof(string));
                {
                    g.Return("Conversion not yet implemented");
                }
            }

            TypeGen Test = ag.Class("Test");
            {
                CodeGen g = Test.Public.Static.Method(typeof(void), "Main");
                {
                    var roman = g.Local(RomanNumeral);
                    g.Assign(roman, 10);
                    var binary = g.Local(BinaryNumeral);
                    // Perform a conversion from a RomanNumeral to a
                    // BinaryNumeral:
                    g.Assign(binary, roman.Cast(typeof(int)).Cast(BinaryNumeral));
                    // Performs a conversion from a BinaryNumeral to a RomanNumeral.
                    // No cast is required:
                    g.Assign(roman, binary);
                    g.WriteLine(binary.Cast(typeof(int)));
                    g.WriteLine(binary);
                }
            }
        }
Esempio n. 18
0
        public static void GenIndexer(AssemblyGen ag)
        {
            // Class to provide access to a large file
            // as if it were a byte array.
            TypeGen FileByteArray = ag.Public.Class("FileByteArray");
            {
                FieldGen stream = FileByteArray.Field <Stream>("stream");                       // Holds the underlying stream
                // used to access the file.

                // Create a new FileByteArray encapsulating a particular file.
                CodeGen g = FileByteArray.Public.Constructor().Parameter <string>("fileName");
                {
                    g.Assign(stream, Exp.New <FileStream>(g.Arg("fileName"), FileMode.Open));
                }

                // Close the stream. This should be the last thing done
                // when you are finished.
                g = FileByteArray.Public.Void("Close");
                {
                    g.Invoke(stream, "Close");
                    g.Assign(stream, null);
                }

                // Indexer to provide read/write access to the file.
                PropertyGen Item = FileByteArray.Public.Indexer <byte>().Index <long>("index");                 // long is a 64-bit integer
                {
                    // Read one byte at offset index and return it.
                    g = Item.Getter();
                    {
                        Operand buffer = g.Local(Exp.NewArray <byte>(1));
                        g.Invoke(stream, "Seek", g.Arg("index"), SeekOrigin.Begin);
                        g.Invoke(stream, "Read", buffer, 0, 1);
                        g.Return(buffer[0]);
                    }
                    // Write one byte at offset index and return it.
                    g = Item.Setter();
                    {
                        Operand buffer = g.Local(Exp.NewInitializedArray <byte>(g.PropertyValue()));
                        g.Invoke(stream, "Seek", g.Arg("index"), SeekOrigin.Begin);
                        g.Invoke(stream, "Write", buffer, 0, 1);
                    }
                }

                // Get the total length of the file.
                FileByteArray.Public.Property <long>("Length").Getter().GetCode()
                .Return(stream.Invoke("Seek", 0, SeekOrigin.End));
            }

            // Demonstrate the FileByteArray class.
            // Reverses the bytes in a file.
            TypeGen Reverse = ag.Public.Class("Reverse");
            {
                CodeGen g = Reverse.Public.Static.Void("Main").Parameter <string[]>("args");
                {
                    Operand args = g.Arg("args");

                    // Check for arguments.
                    g.If(args.ArrayLength() != 1);
                    {
                        g.WriteLine("Usage : Indexer <filename>");
                        g.Return();
                    }
                    g.End();

                    // Check for file existence
                    g.If(!Static.Invoke(typeof(File), "Exists", args[0]));
                    {
                        g.WriteLine("File " + args[0] + " not found.");
                        g.Return();
                    }
                    g.End();

                    Operand file = g.Local(Exp.New(FileByteArray, args[0]));
                    Operand len  = g.Local(file.Property("Length"));

                    // Swap bytes in the file to reverse it.
                    Operand i = g.Local <long>();
                    g.For(i.Assign(0), i < len / 2, i.Increment());
                    {
                        Operand t = g.Local();

                        // Note that indexing the "file" variable invokes the
                        // indexer on the FileByteStream class, which reads
                        // and writes the bytes in the file.
                        g.Assign(t, file[i]);
                        g.Assign(file[i], file[len - i - 1]);
                        g.Assign(file[len - i - 1], t);
                    }
                    g.End();

                    g.Invoke(file, "Close");
                }
            }
        }
        // example based on the MSDN Properties Sample (abstractshape.cs, shapes.cs, shapetest.cs)
        public static void GenShapeTest(AssemblyGen ag)
        {
            // abstractshape.cs
            TypeGen Shape = ag.Public.Abstract.Class("Shape");
            {
                FieldGen myId = Shape.Private.Field(typeof(string), "myId");

                PropertyGen Id = Shape.Public.SimpleProperty(myId, "Id");

                CodeGen g = Shape.Public.Constructor().Parameter(typeof(string), "s");
                {
                    g.Assign(Id, g.Arg("s"));                           // calling the set accessor of the Id property
                }

                // Area is a read-only property - only a get accessor is needed:
                PropertyGen Area = Shape.Public.Abstract.Property(typeof(double), "Area");
                Area.Getter();

                g = Shape.Public.Override.Method(typeof(string), "ToString");
                {
                    g.Return(Id + " Area = " + Static.Invoke(typeof(string), "Format", "{0:F2}", Area));
                }
            }

            // shapes.cs
            TypeGen Square = ag.Public.Class("Square", Shape);
            {
                FieldGen mySide = Square.Private.Field(typeof(int), "mySide");

                CodeGen g = Square.Public.Constructor().Parameter(typeof(int), "side").Parameter(typeof(string), "id");
                {
                    g.InvokeBase(g.Arg("id"));
                    g.Assign(mySide, g.Arg("side"));
                }

                PropertyGen Area = Square.Public.Override.Property(typeof(double), "Area");
                g = Area.Getter();
                {
                    // Given the side, return the area of a square:
                    g.Return(mySide * mySide);
                }
            }

            TypeGen Circle = ag.Public.Class("Circle", Shape);
            {
                FieldGen myRadius = Circle.Private.Field(typeof(int), "myRadius");

                CodeGen g = Circle.Public.Constructor().Parameter(typeof(int), "radius").Parameter(typeof(string), "id");
                {
                    g.InvokeBase(g.Arg("id"));
                    g.Assign(myRadius, g.Arg("radius"));
                }

                PropertyGen Area = Circle.Public.Override.Property(typeof(double), "Area");
                g = Area.Getter();
                {
                    // Given the radius, return the area of a circle:
                    g.Return(myRadius * myRadius * Math.PI);
                }
            }

            TypeGen Rectangle = ag.Public.Class("Rectangle", Shape);
            {
                FieldGen myWidth  = Rectangle.Private.Field(typeof(int), "myWidth");
                FieldGen myHeight = Rectangle.Private.Field(typeof(int), "myHeight");

                CodeGen g = Rectangle.Public.Constructor()
                            .Parameter(typeof(int), "width")
                            .Parameter(typeof(int), "height")
                            .Parameter(typeof(string), "id")
                ;
                {
                    g.InvokeBase(g.Arg("id"));
                    g.Assign(myWidth, g.Arg("width"));
                    g.Assign(myHeight, g.Arg("height"));
                }

                PropertyGen Area = Rectangle.Public.Override.Property(typeof(double), "Area");
                g = Area.Getter();
                {
                    // Given the width and height, return the area of a rectangle:
                    g.Return(myWidth * myHeight);
                }
            }

            // shapetest.cs
            TypeGen TestClass = ag.Public.Class("TestClass");
            {
                CodeGen g = TestClass.Public.Static.Method(typeof(void), "Main");
                {
                    Operand shapes = g.Local(Exp.NewInitializedArray(Shape,
                                                                     Exp.New(Square, 5, "Square #1"),
                                                                     Exp.New(Circle, 3, "Circle #1"),
                                                                     Exp.New(Rectangle, 4, 5, "Rectangle #1")));

                    g.WriteLine("Shapes Collection");
                    Operand s = g.ForEach(Shape, shapes);
                    {
                        g.WriteLine(s);
                    }
                    g.End();
                }
            }
        }
Esempio n. 20
0
            /// <summary>
            /// Iterate over all loaded mods and emit new types
            /// </summary>
            void Awake()
            {
                // Generate overloaded PQSMod types
                AssemblyGen assembly = new AssemblyGen(Guid.NewGuid().ToString(),
                                                       new CompilerOptions {
                    OutputPath = Path.GetTempFileName()
                });

                List <Type> modTypes = GetModTypes();

                foreach (Type modType in modTypes)
                {
                    if (typeof(PQSMod).IsAssignableFrom(modType))
                    {
                        // Get the ModLoader type we want to extend
                        Type loaderType = modTypes.FirstOrDefault(t =>
                                                                  t.BaseType != null && t.BaseType.FullName != null &&
                                                                  t.BaseType.FullName.StartsWith("Kopernicus.Configuration.ModLoader.ModLoader") &&
                                                                  t.BaseType.GetGenericArguments()[0] == modType);
                        if (loaderType == null)
                        {
                            continue;
                        }

                        // Generate the Mod Type
                        TypeGen modGen = assembly.Public.Class($"{modType.Name}Regional", modType);
                        {
                            FieldGen multiplierMap  = modGen.Public.Field(typeof(MapSO), "multiplierMap");
                            FieldGen splitChannels  = modGen.Public.Field(typeof(Boolean), "splitChannels");
                            FieldGen multiplier     = modGen.Private.Field(typeof(Color), "multiplier");
                            FieldGen preBuildColor  = modGen.Private.Field(typeof(Color), "preBuildColor");
                            FieldGen preBuildHeight = modGen.Private.Field(typeof(Double), "preBuildHeight");

                            // OnVertexBuildHeight
                            CodeGen onVertexBuild = modGen.Public.Override.Method(typeof(void), "OnVertexBuild")
                                                    .Parameter(typeof(PQS.VertexBuildData), "data");
                            {
                                ContextualOperand data = onVertexBuild.Arg("data");
                                onVertexBuild.Assign(multiplier, onVertexBuild.Local(multiplierMap.Invoke(
                                                                                         "GetPixelColor", new TypeMapper(),
                                                                                         data.Field("u"), data.Field("v"))));
                                onVertexBuild.If(!splitChannels);
                                {
                                    onVertexBuild.Assign(multiplier.Field("a", new TypeMapper()),
                                                         multiplier.Field("r", new TypeMapper()));
                                }
                                onVertexBuild.End();
                                onVertexBuild.Assign(preBuildColor, data.Field("vertColor"));
                                onVertexBuild.Assign(preBuildHeight, data.Field("vertHeight"));
                                onVertexBuild.Invoke(onVertexBuild.Base(), "OnVertexBuild", data);
                                onVertexBuild.Assign(data.Field("vertColor"),
                                                     assembly.StaticFactory.Invoke(typeof(Color), "Lerp", preBuildColor,
                                                                                   data.Field("vertColor"), multiplier.Field("a", new TypeMapper())));
                                onVertexBuild.Assign(data.Field("vertHeight"),
                                                     assembly.StaticFactory.Invoke(typeof(UtilMath), "Lerp", preBuildHeight,
                                                                                   data.Field("vertHeight"), multiplier.Field("r", new TypeMapper())));
                            }

                            // OnVertexBuildHeight
                            CodeGen onVertexBuildHeight = modGen.Public.Override.Method(typeof(void), "OnVertexBuildHeight")
                                                          .Parameter(typeof(PQS.VertexBuildData), "data");
                            {
                                ContextualOperand data = onVertexBuildHeight.Arg("data");
                                onVertexBuildHeight.Assign(multiplier, onVertexBuildHeight.Local(multiplierMap.Invoke(
                                                                                                     "GetPixelColor", new TypeMapper(),
                                                                                                     data.Field("u"), data.Field("v"))));
                                onVertexBuildHeight.If(!splitChannels);
                                {
                                    onVertexBuildHeight.Assign(multiplier.Field("a", new TypeMapper()),
                                                               multiplier.Field("r", new TypeMapper()));
                                }
                                onVertexBuildHeight.End();
                                onVertexBuildHeight.Assign(preBuildColor, data.Field("vertColor"));
                                onVertexBuildHeight.Assign(preBuildHeight, data.Field("vertHeight"));
                                onVertexBuildHeight.Invoke(onVertexBuildHeight.Base(), "OnVertexBuildHeight", data);
                                onVertexBuildHeight.Assign(data.Field("vertColor"),
                                                           assembly.StaticFactory.Invoke(typeof(Color), "Lerp", preBuildColor,
                                                                                         data.Field("vertColor"), multiplier.Field("a", new TypeMapper())));
                                onVertexBuildHeight.Assign(data.Field("vertHeight"),
                                                           assembly.StaticFactory.Invoke(typeof(UtilMath), "Lerp", preBuildHeight,
                                                                                         data.Field("vertHeight"), multiplier.Field("r", new TypeMapper())));
                            }
                        }

                        // Generate the Loader Type
                        Type    modLoader = typeof(ModLoader <>).MakeGenericType(modGen);
                        TypeGen loaderGen =
                            assembly.Public.Class($"{modType.Name.Replace("PQSMod_", "").Replace("PQS", "")}Regional",
                                                  modLoader);
                        {
                            PropertyGen multiplierMap = loaderGen.Public.Property(typeof(MapSOParserRGB <MapSO>), "multiplierMap")
                                                        .Attribute(typeof(ParserTarget), "multiplierMap");
                            {
                                CodeGen getter = multiplierMap.Getter();
                                {
                                    getter.Return(getter.Base().Property("Mod").Field("multiplierMap"));
                                }
                                CodeGen setter = multiplierMap.Setter();
                                {
                                    setter.Assign(setter.Base().Property("Mod").Field("multiplierMap"),
                                                  setter.PropertyValue());
                                }
                            }

                            PropertyGen splitChannels = loaderGen.Public.Property(typeof(NumericParser <Boolean>), "splitChannels")
                                                        .Attribute(typeof(ParserTarget), "splitChannels");
                            {
                                CodeGen getter = splitChannels.Getter();
                                {
                                    getter.Return(getter.Base().Property("Mod").Field("splitChannels"));
                                }
                                CodeGen setter = splitChannels.Setter();
                                {
                                    setter.Assign(setter.Base().Property("Mod").Field("splitChannels"),
                                                  setter.PropertyValue());
                                }
                            }

                            FieldGen loader = loaderGen.Public.Field(loaderType, "loader")
                                              .BeginAttribute(typeof(ParserTarget), "Mod").SetField("AllowMerge", true).End();

                            CodeGen create_PQS = loaderGen.Public.Override.Method(typeof(void), "Create")
                                                 .Parameter(typeof(PQS), "pqsVersion");
                            {
                                ContextualOperand pqsVersion = create_PQS.Arg("pqsVersion");
                                create_PQS.Invoke(create_PQS.Base(), "Create", pqsVersion);
                                create_PQS.Assign(loader, assembly.ExpressionFactory.New(loaderType));
                                create_PQS.Invoke(loader, "Create", create_PQS.Base().Property("Mod"), pqsVersion);
                            }
                            CodeGen create_Mod_PQS = loaderGen.Public.Override.Method(typeof(void), "Create")
                                                     .Parameter(modGen, "_mod")
                                                     .Parameter(typeof(PQS), "pqsVersion");
                            {
                                ContextualOperand _mod       = create_Mod_PQS.Arg("_mod");
                                ContextualOperand pqsVersion = create_Mod_PQS.Arg("pqsVersion");
                                create_Mod_PQS.Invoke(create_Mod_PQS.Base(), "Create", _mod, pqsVersion);
                                create_Mod_PQS.Assign(loader, assembly.ExpressionFactory.New(loaderType));
                                create_Mod_PQS.Invoke(loader, "Create", create_Mod_PQS.Base().Property("Mod"), pqsVersion);
                            }
                        }
                    }
                }
                assembly.Save();

                // Hacking into my own mod. Oh well.
                modTypes.AddRange(assembly.GetAssembly().GetTypes());
                typeof(Parser).GetField("_modTypes", BindingFlags.NonPublic | BindingFlags.Static)
                ?.SetValue(null, modTypes);
            }
Esempio n. 21
0
        // example based on the MSDN User-Defined Conversions Sample (structconversion.cs)
        public static void GenStructConversion(AssemblyGen ag)
        {
            TypeGen BinaryNumeral = ag.Struct("BinaryNumeral");
            {
                FieldGen value = BinaryNumeral.Private.Field <int>("value");

                CodeGen g = BinaryNumeral.Public.Constructor().Parameter <int>("value");
                {
                    g.Assign(value, g.Arg("value"));
                }

                g = BinaryNumeral.Public.ImplicitConversionFrom <int>();
                {
                    g.Return(Exp.New(BinaryNumeral, g.Arg("value")));
                }

                g = BinaryNumeral.Public.ImplicitConversionTo <string>();
                {
                    g.Return("Conversion not yet implemented");
                }

                g = BinaryNumeral.Public.ExplicitConversionTo <int>("binary");
                {
                    g.Return(g.Arg("binary").Field("value"));
                }
            }

            TypeGen RomanNumeral = ag.Struct("RomanNumeral");
            {
                FieldGen value = RomanNumeral.Private.Field <int>("value");

                CodeGen g = RomanNumeral.Public.Constructor().Parameter <int>("value");
                {
                    g.Assign(value, g.Arg("value"));
                }

                g = RomanNumeral.Public.ImplicitConversionFrom <int>();
                {
                    g.Return(Exp.New(RomanNumeral, g.Arg("value")));
                }

                g = RomanNumeral.Public.ImplicitConversionFrom(BinaryNumeral, "binary");
                {
                    g.Return(Exp.New(RomanNumeral, g.Arg("binary").Cast <int>()));
                }

                g = RomanNumeral.Public.ExplicitConversionTo <int>("roman");
                {
                    g.Return(g.Arg("roman").Field("value"));
                }

                g = RomanNumeral.Public.ImplicitConversionTo <string>();
                {
                    g.Return("Conversion not yet implemented");
                }
            }

            TypeGen Test = ag.Class("Test");
            {
                CodeGen g = Test.Public.Static.Void("Main");
                {
                    Operand roman = g.Local(RomanNumeral);
                    g.Assign(roman, 10);
                    Operand binary = g.Local(BinaryNumeral);
                    // Perform a conversion from a RomanNumeral to a
                    // BinaryNumeral:
                    g.Assign(binary, roman.Cast <int>().Cast(BinaryNumeral));
                    // Performs a conversion from a BinaryNumeral to a RomanNumeral.
                    // No cast is required:
                    g.Assign(roman, binary);
                    g.WriteLine(binary.Cast <int>());
                    g.WriteLine(binary);
                }
            }
        }
Esempio n. 22
0
        // example based on the MSDN Delegates Sample (bookstore.cs)
        public static void GenBookstore(AssemblyGen ag)
        {
            TypeGen Book, ProcessBookDelegate, BookDB;

            // A set of classes for handling a bookstore:
            using (ag.Namespace("Bookstore"))
            {
                // Describes a book in the book list:
                Book = ag.Public.Struct("Book");
                {
                    FieldGen Title     = Book.Public.Field <string>("Title");                      // Title of the book.
                    FieldGen Author    = Book.Public.Field <string>("Author");                     // Author of the book.
                    FieldGen Price     = Book.Public.Field <decimal>("Price");                     // Price of the book.
                    FieldGen Paperback = Book.Public.Field <bool>("Paperback");                    // Is it paperback?

                    CodeGen g = Book.Public.Constructor()
                                .Parameter <string>("title")
                                .Parameter <string>("author")
                                .Parameter <decimal>("price")
                                .Parameter <bool>("paperBack");
                    {
                        g.Assign(Title, g.Arg("title"));
                        g.Assign(Author, g.Arg("author"));
                        g.Assign(Price, g.Arg("price"));
                        g.Assign(Paperback, g.Arg("paperBack"));
                    }
                }

                // Declare a delegate type for processing a book:
                ProcessBookDelegate = ag.Public.DelegateVoid("ProcessBookDelegate").Parameter(Book, "book");

                // Maintains a book database.
                BookDB = ag.Public.Class("BookDB");
                {
                    // List of all books in the database:
                    FieldGen list = BookDB.Field <ArrayList>("list", Exp.New <ArrayList>());

                    // Add a book to the database:
                    CodeGen g = BookDB.Public.Void("AddBook")
                                .Parameter <string>("title")
                                .Parameter <string>("author")
                                .Parameter <decimal>("price")
                                .Parameter <bool>("paperBack");
                    {
                        g.Invoke(list, "Add", Exp.New(Book, g.Arg("title"), g.Arg("author"), g.Arg("price"), g.Arg("paperBack")));
                    }

                    // Call a passed-in delegate on each paperback book to process it:
                    g = BookDB.Public.Void("ProcessPaperbackBooks").Parameter(ProcessBookDelegate, "processBook");
                    {
                        Operand b = g.ForEach(Book, list);
                        {
                            g.If(b.Field("Paperback"));
                            {
                                g.InvokeDelegate(g.Arg("processBook"), b);
                            }
                            g.End();
                        }
                        g.End();
                    }
                }
            }

            // Using the Bookstore classes:
            using (ag.Namespace("BookTestClient"))
            {
                // Class to total and average prices of books:
                TypeGen PriceTotaller = ag.Class("PriceTotaller");
                {
                    FieldGen countBooks = PriceTotaller.Field <int>("countBooks", 0);
                    FieldGen priceBooks = PriceTotaller.Field <decimal>("priceBooks", 0.0m);

                    CodeGen g = PriceTotaller.Internal.Void("AddBookToTotal").Parameter(Book, "book");
                    {
                        g.AssignAdd(countBooks, 1);
                        g.AssignAdd(priceBooks, g.Arg("book").Field("Price"));
                    }

                    g = PriceTotaller.Internal.Method <decimal>("AveragePrice");
                    {
                        g.Return(priceBooks / countBooks);
                    }
                }

                // Class to test the book database:
                TypeGen Test = ag.Class("Test");
                {
                    // Print the title of the book.
                    CodeGen g = Test.Static.Void("PrintTitle").Parameter(Book, "book");
                    {
                        g.WriteLine("   {0}", g.Arg("book").Field("Title"));
                    }

                    // Initialize the book database with some test books:
                    g = Test.Static.Void("AddBooks").Parameter(BookDB, "bookDB");
                    {
                        Operand bookDB = g.Arg("bookDB");

                        g.Invoke(bookDB, "AddBook", "The C Programming Language",
                                 "Brian W. Kernighan and Dennis M. Ritchie", 19.95m, true);
                        g.Invoke(bookDB, "AddBook", "The Unicode Standard 2.0",
                                 "The Unicode Consortium", 39.95m, true);
                        g.Invoke(bookDB, "AddBook", "The MS-DOS Encyclopedia",
                                 "Ray Duncan", 129.95m, false);
                        g.Invoke(bookDB, "AddBook", "Dogbert's Clues for the Clueless",
                                 "Scott Adams", 12.00m, true);
                    }

                    // Execution starts here.
                    g = Test.Static.Void("Main");
                    {
                        Operand bookDB = g.Local(Exp.New(BookDB));

                        // Initialize the database with some books:
                        g.Invoke(Test, "AddBooks", bookDB);

                        // Print all the titles of paperbacks:
                        g.WriteLine("Paperback Book Titles:");
                        // Create a new delegate object associated with the static
                        // method Test.PrintTitle:
                        g.Invoke(bookDB, "ProcessPaperbackBooks", Exp.NewDelegate(ProcessBookDelegate, Test, "PrintTitle"));

                        // Get the average price of a paperback by using
                        // a PriceTotaller object:
                        Operand totaller = g.Local(Exp.New(PriceTotaller));
                        // Create a new delegate object associated with the nonstatic
                        // method AddBookToTotal on the object totaller:
                        g.Invoke(bookDB, "ProcessPaperbackBooks", Exp.NewDelegate(ProcessBookDelegate, totaller, "AddBookToTotal"));
                        g.WriteLine("Average Paperback Book Price: ${0:#.##}",
                                    totaller.Invoke("AveragePrice"));
                    }
                }
            }
        }
Esempio n. 23
0
        // example based on the MSDN Delegates Sample (bookstore.cs)
        public static void GenBookstore(AssemblyGen ag)
        {
            var st  = ag.StaticFactory;
            var exp = ag.ExpressionFactory;

            ITypeMapper m = ag.TypeMapper;
            TypeGen     book, processBookDelegate, BookDBLocal;

            // A set of classes for handling a bookstore:
            using (ag.Namespace("Bookstore"))
            {
                // Describes a book in the book list:
                book = ag.Public.Struct("Book");
                {
                    FieldGen title     = book.Public.Field(typeof(string), "Title");                       // Title of the book.
                    FieldGen author    = book.Public.Field(typeof(string), "Author");                      // Author of the book.
                    FieldGen price     = book.Public.Field(typeof(decimal), "Price");                      // Price of the book.
                    FieldGen paperback = book.Public.Field(typeof(bool), "Paperback");                     // Is it paperback?

                    CodeGen g = book.Public.Constructor()
                                .Parameter(typeof(string), "title")
                                .Parameter(typeof(string), "author")
                                .Parameter(typeof(decimal), "price")
                                .Parameter(typeof(bool), "paperBack");
                    {
                        g.Assign(title, g.Arg("title"));
                        g.Assign(author, g.Arg("author"));
                        g.Assign(price, g.Arg("price"));
                        g.Assign(paperback, g.Arg("paperBack"));
                    }
                }

                // Declare a delegate type for processing a book:
                processBookDelegate = ag.Public.Delegate(typeof(void), "ProcessBookDelegate").Parameter(book, "book");

                // Maintains a book database.
                BookDBLocal = ag.Public.Class("BookDB");
                {
                    // List of all books in the database:
                    FieldGen list = BookDBLocal.Field(typeof(ArrayList), "list", exp.New(typeof(ArrayList)));

                    // Add a book to the database:
                    CodeGen g = BookDBLocal.Public.Method(typeof(void), "AddBook")
                                .Parameter(typeof(string), "title")
                                .Parameter(typeof(string), "author")
                                .Parameter(typeof(decimal), "price")
                                .Parameter(typeof(bool), "paperBack")
                    ;
                    {
                        g.Invoke(list, "Add", exp.New(book, g.Arg("title"), g.Arg("author"), g.Arg("price"), g.Arg("paperBack")));
                    }

                    // Call a passed-in delegate on each paperback book to process it:
                    g = BookDBLocal.Public.Method(typeof(void), "ProcessPaperbackBooks").Parameter(processBookDelegate, "processBook");
                    {
                        var b = g.ForEach(book, list);
                        {
                            g.If(b.Field("Paperback"));
                            {
                                g.InvokeDelegate(g.Arg("processBook"), b);
                            }
                            g.End();
                        }
                        g.End();
                    }
                }
            }

            // Using the Bookstore classes:
            using (ag.Namespace("BookTestClient"))
            {
                // Class to total and average prices of books:
                TypeGen priceTotaller = ag.Class("PriceTotaller");
                {
                    FieldGen countBooks = priceTotaller.Field(typeof(int), "countBooks", 0);
                    FieldGen priceBooks = priceTotaller.Field(typeof(decimal), "priceBooks", 0.0m);

                    CodeGen g = priceTotaller.Internal.Method(typeof(void), "AddBookToTotal").Parameter(book, "book");
                    {
                        g.AssignAdd(countBooks, 1);
                        g.AssignAdd(priceBooks, g.Arg("book").Field("Price"));
                    }

                    g = priceTotaller.Internal.Method(typeof(decimal), "AveragePrice");
                    {
                        g.Return(priceBooks / countBooks);
                    }
                }

                // Class to test the book database:
                TypeGen test = ag.Class("Test");
                {
                    // Print the title of the book.
                    CodeGen g = test.Static.Method(typeof(void), "PrintTitle").Parameter(book, "book");
                    {
                        g.WriteLine("   {0}", g.Arg("book").Field("Title"));
                    }

                    // Initialize the book database with some test books:
                    g = test.Static.Method(typeof(void), "AddBooks").Parameter(BookDBLocal, "bookDB");
                    {
                        var bookDb = g.Arg("bookDB");

                        g.Invoke(bookDb, "AddBook", "The C Programming Language",
                                 "Brian W. Kernighan and Dennis M. Ritchie", 19.95m, true);
                        g.Invoke(bookDb, "AddBook", "The Unicode Standard 2.0",
                                 "The Unicode Consortium", 39.95m, true);
                        g.Invoke(bookDb, "AddBook", "The MS-DOS Encyclopedia",
                                 "Ray Duncan", 129.95m, false);
                        g.Invoke(bookDb, "AddBook", "Dogbert's Clues for the Clueless",
                                 "Scott Adams", 12.00m, true);
                    }

                    // Execution starts here.
                    g = test.Public.Static.Method(typeof(void), "Main");
                    {
                        var bookDb = g.Local(exp.New(BookDBLocal));

                        // Initialize the database with some books:
                        g.Invoke(test, "AddBooks", bookDb);

                        // Print all the titles of paperbacks:
                        g.WriteLine("Paperback Book Titles:");
                        // Create a new delegate object associated with the static
                        // method Test.PrintTitle:
                        g.Invoke(bookDb, "ProcessPaperbackBooks", (Operand)exp.NewDelegate(processBookDelegate, test, "PrintTitle"));

                        // Get the average price of a paperback by using
                        // a PriceTotaller object:
                        var totaller = g.Local(exp.New(priceTotaller));
                        // Create a new delegate object associated with the nonstatic
                        // method AddBookToTotal on the object totaller:
                        g.Invoke(bookDb, "ProcessPaperbackBooks", (Operand)exp.NewDelegate(processBookDelegate, totaller, "AddBookToTotal"));
                        g.WriteLine("Average Paperback Book Price: ${0:#.##}",
                                    totaller.Invoke("AveragePrice"));
                    }
                }
            }
        }
Esempio n. 24
0
        // example based on the MSDN Operator Overloading Sample (dbbool.cs)
        public static void GenDbBool(AssemblyGen ag)
        {
            TypeGen DBBool = ag.Public.Struct("DBBool");
            {
                // Private field that stores -1, 0, 1 for dbFalse, dbNull, dbTrue:
                FieldGen value = DBBool.Field <int>("value");

                // Private constructor. The value parameter must be -1, 0, or 1:
                CodeGen g = DBBool.Constructor().Parameter <int>("value");
                {
                    g.Assign(value, g.Arg("value"));
                }

                // The three possible DBBool values:
                FieldGen dbNull  = DBBool.Public.Static.ReadOnly.Field(DBBool, "dbNull", Exp.New(DBBool, 0));
                FieldGen dbFalse = DBBool.Public.Static.ReadOnly.Field(DBBool, "dbFalse", Exp.New(DBBool, -1));
                FieldGen dbTrue  = DBBool.Public.Static.ReadOnly.Field(DBBool, "dbTrue", Exp.New(DBBool, 1));

                // Implicit conversion from bool to DBBool. Maps true to
                // DBBool.dbTrue and false to DBBool.dbFalse:
                g = DBBool.ImplicitConversionFrom <bool>("x");
                {
                    Operand x = g.Arg("x");
                    g.Return(x.Conditional(dbTrue, dbFalse));
                }

                // Explicit conversion from DBBool to bool. Throws an
                // exception if the given DBBool is dbNull, otherwise returns
                // true or false:
                g = DBBool.ExplicitConversionTo <bool>("x");
                {
                    Operand x = g.Arg("x");
                    g.If(x.Field("value") == 0);
                    {
                        g.Throw(Exp.New(typeof(InvalidOperationException)));
                    }
                    g.End();

                    g.Return(x.Field("value") > 0);
                }

                // Equality operator. Returns dbNull if either operand is dbNull,
                // otherwise returns dbTrue or dbFalse:
                g = DBBool.Operator(Operator.Equality, DBBool, DBBool, "x", DBBool, "y");
                {
                    Operand x = g.Arg("x"), y = g.Arg("y");
                    g.If(x.Field("value") == 0 || y.Field("value") == 0);
                    {
                        g.Return(dbNull);
                    }
                    g.End();

                    g.Return((x.Field("value") == y.Field("value")).Conditional(dbTrue, dbFalse));
                }

                // Inequality operator. Returns dbNull if either operand is
                // dbNull, otherwise returns dbTrue or dbFalse:
                g = DBBool.Operator(Operator.Inequality, DBBool, DBBool, "x", DBBool, "y");
                {
                    Operand x = g.Arg("x"), y = g.Arg("y");
                    g.If(x.Field("value") == 0 || y.Field("value") == 0);
                    {
                        g.Return(dbNull);
                    }
                    g.End();

                    g.Return((x.Field("value") != y.Field("value")).Conditional(dbTrue, dbFalse));
                }

                // Logical negation operator. Returns dbTrue if the operand is
                // dbFalse, dbNull if the operand is dbNull, or dbFalse if the
                // operand is dbTrue:
                g = DBBool.Operator(Operator.LogicalNot, DBBool, DBBool, "x");
                {
                    Operand x = g.Arg("x");
                    g.Return(Exp.New(DBBool, -x.Field("value")));
                }

                // Logical AND operator. Returns dbFalse if either operand is
                // dbFalse, dbNull if either operand is dbNull, otherwise dbTrue:
                g = DBBool.Operator(Operator.And, DBBool, DBBool, "x", DBBool, "y");
                {
                    Operand x = g.Arg("x"), y = g.Arg("y");
                    g.Return(Exp.New(DBBool, (x.Field("value") < y.Field("value")).Conditional(x.Field("value"), y.Field("value"))));
                }

                // Logical OR operator. Returns dbTrue if either operand is
                // dbTrue, dbNull if either operand is dbNull, otherwise dbFalse:
                g = DBBool.Operator(Operator.Or, DBBool, DBBool, "x", DBBool, "y");
                {
                    Operand x = g.Arg("x"), y = g.Arg("y");
                    g.Return(Exp.New(DBBool, (x.Field("value") > y.Field("value")).Conditional(x.Field("value"), y.Field("value"))));
                }

                // Definitely true operator. Returns true if the operand is
                // dbTrue, false otherwise:
                g = DBBool.Operator(Operator.True, typeof(bool), DBBool, "x");
                {
                    Operand x = g.Arg("x");
                    g.Return(x.Field("value") > 0);
                }

                // Definitely false operator. Returns true if the operand is
                // dbFalse, false otherwise:
                g = DBBool.Operator(Operator.False, typeof(bool), DBBool, "x");
                {
                    Operand x = g.Arg("x");
                    g.Return(x.Field("value") < 0);
                }

                // Overload the conversion from DBBool to string:
                g = DBBool.ImplicitConversionTo(typeof(string), "x");
                {
                    Operand x = g.Arg("x");

                    g.Return((x.Field("value") > 0).Conditional("dbTrue",
                                                                (x.Field("value") < 0).Conditional("dbFalse",
                                                                                                   "dbNull")));
                }

                // Override the Object.Equals(object o) method:
                g = DBBool.Public.Override.Method <bool>("Equals").Parameter <object>("o");
                {
                    g.Try();
                    {
                        g.Return((g.This() == g.Arg("o").Cast(DBBool)).Cast <bool>());
                    }
                    g.CatchAll();
                    {
                        g.Return(false);
                    }
                    g.End();
                }

                // Override the Object.GetHashCode() method:
                g = DBBool.Public.Override.Method <int>("GetHashCode");
                {
                    g.Return(value);
                }

                // Override the ToString method to convert DBBool to a string:
                g = DBBool.Public.Override.Method <string>("ToString");
                {
                    g.Switch(value);
                    {
                        g.Case(-1);
                        g.Return("DBBool.False");
                        g.Case(0);
                        g.Return("DBBool.Null");
                        g.Case(1);
                        g.Return("DBBool.True");
                        g.DefaultCase();
                        g.Throw(Exp.New <InvalidOperationException>());
                    }
                    g.End();
                }
            }

            TypeGen Test = ag.Class("Test");
            {
                CodeGen g = Test.Static.Void("Main");
                {
                    Operand a = g.Local(DBBool), b = g.Local(DBBool);
                    g.Assign(a, Static.Field(DBBool, "dbTrue"));
                    g.Assign(b, Static.Field(DBBool, "dbNull"));

                    g.WriteLine("!{0} = {1}", a, !a);
                    g.WriteLine("!{0} = {1}", b, !b);
                    g.WriteLine("{0} & {1} = {2}", a, b, a & b);
                    g.WriteLine("{0} | {1} = {2}", a, b, a | b);
                    // Invoke the true operator to determine the Boolean
                    // value of the DBBool variable:
                    g.If(b);
                    {
                        g.WriteLine("b is definitely true");
                    }
                    g.Else();
                    {
                        g.WriteLine("b is not definitely true");
                    }
                    g.End();
                }
            }
        }
        /// <summary>
        ///   Create a wrapper class for a generic interface with more general type parameters than the wrapped interface.
        ///   Downcasts to the correct more specific type are generated where necessary.
        ///   This of course breaks type safety, and only calls to the class with the correct orginal types will work.
        ///   Incorrect calls will throw <see cref = "InvalidCastException" />.
        /// </summary>
        /// <remarks>
        ///   This is useful during reflection, when you don't want to know about specific types, but you can guarantee
        ///   that a certain call will always be done with objects of the correct type.
        ///   TODO: This non-generic method is only needed since RunSharp can't call generic methods, needed to generate wrappers recursively.
        ///   TODO: Possibly Castle DynamicProxy could replace this if it allows creating 'non-matching' proxies and thus support the downcasting.
        /// </remarks>
        /// <param name = "typeToCreate">The less-specific generic type of the wrapper which will be generated.</param>
        /// <param name = "o">The object to wrap, which should implement the desired interface, with arbitrary type parameters.</param>
        /// <returns>An instance of the specified type which wraps the given object.</returns>
        public static object CreateGenericInterfaceWrapper(Type typeToCreate, object o)
        {
            Contract.Requires(o.GetType().IsOfGenericType(typeToCreate.GetGenericTypeDefinition()));
            Contract.Requires(typeToCreate.IsInterface);

            Type typeToCreateGeneric = typeToCreate.GetGenericTypeDefinition();
            Type innerType           = o.GetType();
            Type innerMatchingType   = innerType.GetMatchingGenericType(typeToCreateGeneric);

            // Implement passed type and redirect all public calls to inner instance.
            var     assembly = new AssemblyGen("Whathecode.System.RunSharp");
            TypeGen type     = assembly.Public.Class("Wrapped" + typeToCreate.Name, typeof(object), typeToCreate);
            {
                const string inner = "inner";

                FieldGen innerInstance  = type.Private.Field(innerType, "_innerInstance");
                FieldGen returnCached   = type.Private.Field(typeof(Dictionary <int, object>), "_returnCached");
                FieldGen returnWrappers = type.Private.Field(typeof(Dictionary <int, object>), "_returnWrappers");

                // Create constructor which takes the wrapped instance as an argument.
                ConstructorGen constructor = type.Public.Constructor();
                {
                    constructor.Parameter(innerType, inner);

                    CodeGen code = constructor.GetCode();
                    {
                        code.Assign(innerInstance, code.Arg(inner));
                        code.Assign(returnCached, Exp.New(typeof(Dictionary <int, object>)));
                        code.Assign(returnWrappers, Exp.New(typeof(Dictionary <int, object>)));
                    }
                }

                // Create methods.
                int          methodCount     = 0;
                MethodInfo[] innerMethods    = innerMatchingType.GetFlattenedInterfaceMethods(ReflectionHelper.FlattenedInstanceMembers).ToArray();
                MethodInfo[] toCreateMethods = typeToCreate.GetFlattenedInterfaceMethods(ReflectionHelper.FlattenedInstanceMembers).ToArray();
                MethodInfo[] genericMethods  = typeToCreateGeneric.GetFlattenedInterfaceMethods(ReflectionHelper.FlattenedInstanceMembers).ToArray();
                foreach (var method in innerMethods
                         .Zip(toCreateMethods, genericMethods,
                              (matching, toCreate, generic) => new
                {
                    Id = methodCount++,
                    Matching = matching,
                    ToCreate = toCreate,
                    Generic = generic
                })
                         .Where(z => z.Matching.IsPublic || z.Matching.IsFamily))
                {
                    // TODO: Not quite certain why override is required for extended interfaces (DeclaringType != typeTocreate),
                    //       but this seems to work.
                    MethodInfo toCreate  = method.ToCreate;
                    MethodGen  methodGen = toCreate.DeclaringType == typeToCreate
                                                ? type.MethodImplementation(typeToCreate, toCreate.ReturnType, toCreate.Name)
                                                : type.Public.Override.Method(toCreate.ReturnType, toCreate.Name);

                    {
                        ParameterInfo[] toCreateParameters = toCreate.GetParameters();
                        var             parameters         = toCreateParameters
                                                             .Select(p =>
                        {
                            var info = methodGen.BeginParameter(p.ParameterType, p.Name);
                            info.End();
                            return(info);
                        }).ToArray();

                        CodeGen code = methodGen.GetCode();
                        {
                            // Cast arguments to the type of the inner instance.
                            Operand[] args     = parameters.Select(p => code.Arg(p.Name)).ToArray();
                            Operand[] castArgs = { };
                            if (args.Length > 0)
                            {
                                Type[] parameterTypes = method.Matching.GetParameters().Select(p => p.ParameterType).ToArray();
                                // TODO: When searching for generic methods, GetMethod returns null. http://stackoverflow.com/questions/4035719/getmethod-for-generic-method
                                //       Even when the correct method is found through custom filtering, RunSharp does not seem to be able to create generic methods yet.
                                MethodInfo methodToCall
                                         = innerType.GetMethod(toCreate.Name, ReflectionHelper.FlattenedInstanceMembers, parameterTypes);
                                castArgs = methodToCall.GetParameters()
                                           .Select((p, index) => args[index].Cast(typeof(object)).Cast(p.ParameterType)).ToArray();
                            }

                            // Call inner instance and return value when needed.
                            if (toCreate.ReturnType != typeof(void))
                            {
                                Operand result = innerInstance.Invoke(toCreate.Name, castArgs);

                                // Wrappers will recursively need to be created for generic return types.
                                Type genericReturnType = method.Generic.ReturnType;
                                if (genericReturnType.IsGenericType && genericReturnType.ContainsGenericParameters && genericReturnType.IsInterface)
                                {
                                    // Check whether a new result is returned.
                                    Operand innerCached = code.Local(typeof(object));
                                    code.If(returnCached.Invoke("TryGetValue", method.Id, innerCached.Ref()));
                                    {
                                        code.If((innerCached == result).LogicalNot());
                                        {
                                            code.Invoke(returnWrappers, "Remove", method.Id);
                                            code.Invoke(returnCached, "Remove", method.Id);
                                            code.Invoke(returnCached, "Add", method.Id, result);
                                        }
                                        code.End();
                                    }
                                    code.Else();
                                    {
                                        code.Invoke(returnCached, "Add", method.Id, result);
                                    }
                                    code.End();

                                    // Check whether a wrapper needs to be generated.
                                    Operand wrappedCached = code.Local(typeof(object));
                                    code.If(returnWrappers.Invoke("TryGetValue", method.Id, wrappedCached.Ref()).LogicalNot());
                                    {
                                        Operand proxied = Static.Invoke(typeof(Proxy), "CreateGenericInterfaceWrapper", toCreate.ReturnType, result);
                                        code.Assign(wrappedCached, proxied);
                                        code.Invoke(returnWrappers, "Add", method.Id, wrappedCached);
                                    }
                                    code.End();
                                    code.Return(wrappedCached.Cast(toCreate.ReturnType));
                                }
                                else
                                {
                                    // A simple cast will work.
                                    // TODO: Throw proper exception when this is known to fail. E.g. generic type which is not an interface?
                                    code.Return(result.Cast(toCreate.ReturnType));
                                }
                            }
                            else
                            {
                                code.Invoke(innerInstance, toCreate.Name, castArgs);
                            }
                        }
                    }
                }
            }
            Type wrapperType = type.GetCompletedType(true);

            return(Activator.CreateInstance(wrapperType, new[] { o }));
        }