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