// 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);
                }
            }
        }
示例#2
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();
                }
            }
        }