public void GenerateAssembly(string path)
 {
     _assemblyGen = new AssemblyGen("output", new CompilerOptions {
         OutputPath = path, SymbolInfo = true, TargetFrameworkName = "4.5", TargetFrameworkDisplayName = "4.5"
     });
     using (_assemblyGen.Namespace("Language"))
     {
         _currentProgram = _assemblyGen.Public.Class("Program");
         {
             Visit(_program);
         }
         var type = _currentProgram.GetCompletedType(true);
         _currentProgram = _assemblyGen.Public.Class("Runner");
         {
             CodeGen method = _currentProgram.Public.Static.Method(typeof(void), "Main");
             {
                 Operand obj = method.Local(_currentProgram.ExpressionFactory.New(type));
                 method.Invoke(obj, "main");
                 method.WriteLine("Press any key...");
                 method.Invoke(typeof(Console), "ReadKey");
             }
         }
     }
     _assemblyGen.Save();
 }
Esempio n. 2
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. 3
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");
                    }
                }
            }
        }
Esempio n. 4
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(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.
                BookDB = ag.Public.Class("BookDB");
                {
                    // List of all books in the database:
                    FieldGen list = BookDB.Field(typeof(ArrayList), "list", Exp.New(typeof(ArrayList)));

                    // Add a book to the database:
                    CodeGen g = BookDB.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 = BookDB.Public.Method(typeof(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(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(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.Method(typeof(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. 5
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");
                    }
                }
            }
        }
Esempio n. 6
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. 7
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"));
                    }
                }
            }
        }