/// <summary> /// Загрузка всех классов (наследование учитывается). /// Допущение - классы-наследники должны располагаться после базовых классов /// и иерархий наследования должно быть не более 1. /// </summary> /// <param name="root">Базовый символ</param> /// <param name="ag">Сборка</param> private void LoadClassesExtends(BaseSymbol root, AssemblyGen ag) { root.Symbols.ForEach(s => { if (s.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = s as NonTerm; switch (nonTerm.TypeNonTerm) { case NonTermType.Class: Token termClassId; NonTerm extends; NonTermFactory.GetClassDecl(nonTerm, out termClassId, out extends); string classId = termClassId.Value; if (extends == null) { TypeGen cl = ag.Class(classId); _classesTable.Add(cl.Name, cl); } else { Token baseClassId; NonTermFactory.GetClassId(extends, out baseClassId); TypeGen cl = _classesTable[baseClassId.Value]; cl = ag.Class(classId, cl); _classesTable.Add(cl.Name, cl); } break; } } }); }
// 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")); } } }
public static void GenBreakContinue(AssemblyGen ag) { CodeGen g = ag.Class("Test").Public.Static.Method(typeof(void), "Main"); g.WriteLine("Break test:"); var i = g.Local(); g.For(i.Assign(1), i <= 100, i.Increment()); { g.If(i == 5); { g.Break(); } g.End(); g.WriteLine(i); } g.End(); g.WriteLine("Continue test:"); g.For(i.Assign(1), i <= 10, i.Increment()); { g.If(i > 3 && i < 8); { g.Continue(); } g.End(); g.WriteLine(i); } g.End(); }
public static void GenIsNull(AssemblyGen ag) { TypeGen Test = ag.Class("Test"); { CodeGen g = Test.Static.Method(typeof(void), "Main"); { Operand a = g.Local(typeof(object), "notnull"); Operand b = g.Local(typeof(object), null); g.If(a == null); { g.WriteLine("a is null"); } g.Else(); { g.WriteLine("a is not null"); } g.End(); g.If(b == null); { g.WriteLine("b is null"); } g.Else(); { g.WriteLine("b is not null"); } g.End(); } } }
// example based on the MSDN Arrays Sample (arrays.cs) public static void GenArrays(AssemblyGen ag) { TypeGen DeclareArraysSample = ag.Class("DecalreArraysSample"); { CodeGen g = DeclareArraysSample.Public.Static.Void("Main"); { // Single-dimensional array Operand numbers = g.Local(Exp.NewArray <int>(5)); // Multidimensional array Operand names = g.Local(Exp.NewArray <string>(5, 4)); // Array-of-arrays (jagged array) Operand scores = g.Local(Exp.NewArray <byte[]>(5)); // Create the jagged array Operand i = g.Local(); g.For(i.Assign(0), i < scores.ArrayLength(), i.Increment()); { g.Assign(scores[i], Exp.NewArray <byte>(i + 3)); } g.End(); // Print length of each row g.For(i.Assign(0), i < scores.ArrayLength(), i.Increment()); { g.WriteLine("Length of row {0} is {1}", i, scores[i].ArrayLength()); } g.End(); } } }
// example based on the MSDN Arrays Sample (arrays.cs) public static void GenArrays(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; TypeGen DeclareArraysSample = ag.Class("DecalreArraysSample"); { CodeGen g = DeclareArraysSample.Public.Static.Method(typeof(void), "Main"); { // Single-dimensional array var numbers = g.Local(exp.NewArray(typeof(int), 5)); // Multidimensional array var names = g.Local(exp.NewArray(typeof(string), 5, 4)); // Array-of-arrays (jagged array) var scores = g.Local(exp.NewArray(typeof(byte[]), 5)); // Create the jagged array var i = g.Local(); g.For(i.Assign(0), i < scores.ArrayLength(), i.Increment()); { g.Assign(scores[i], exp.NewArray(typeof(byte), i + 3)); } g.End(); // Print length of each row from 3 g.For(i.Assign(2), i < scores.ArrayLength(), i.Increment()); { g.WriteLine("Length of row {0} is {1}", i, scores[i].ArrayLength()); } g.End(); } } }
public static void GenBreakContinue(AssemblyGen ag) { CodeGen g = ag.Class("Test").Static.Void("Main"); g.WriteLine("Break test:"); Operand i = g.Local(); g.For(i.Assign(1), i <= 100, i.Increment()); { g.If(i == 5); { g.Break(); } g.End(); g.WriteLine(i); } g.End(); g.WriteLine("Continue test:"); g.For(i.Assign(1), i <= 10, i.Increment()); { g.If(i > 3 && i < 8); { g.Continue(); } g.End(); g.WriteLine(i); } g.End(); }
public static void GenTypeAttributeTest(AssemblyGen ag) { TypeGen MyAttribute = ag.Public.Class("MyAttribute", typeof(Attribute)) .BeginAttribute <AttributeUsageAttribute>(AttributeTargets.Class).Set("AllowMultiple", true).End(); FieldGen testField = MyAttribute.Field <object>("testField") .Attribute <DescriptionAttribute>("Test field"); PropertyGen testProperty = MyAttribute.Public.SimpleProperty(testField, "TestProperty") .Attribute <ObsoleteAttribute>("Do not use this"); testProperty.Getter().Attribute <DescriptionAttribute>("Getter method"); testProperty.Getter().ReturnParameter.Attribute <DescriptionAttribute>("Getter return value"); testProperty.Setter().Attribute <DescriptionAttribute>("Setter method"); TypeGen tg = ag.Class("Test") .BeginAttribute(MyAttribute).Set("TestProperty", 3).End() .Attribute <DescriptionAttribute>("Test class"); tg.Static.Void("Main") .BeginAttribute(MyAttribute).Set("TestProperty", 3).End(); TypeGen SimpleDelegate = ag.DelegateVoid("SimpleDelegate") .Attribute <DescriptionAttribute>("Test delegate"); EventGen TestEvent = tg.Static.Event(SimpleDelegate, "TestEvent") .Attribute <DescriptionAttribute>("Test event"); TestEvent.AddMethod().Attribute <DescriptionAttribute>("Event add method"); TestEvent.RemoveMethod().Attribute <DescriptionAttribute>("Event remove method"); }
public static void ClassImpl(AssemblyGen ag, bool impl) { ITypeMapper m = ag.TypeMapper; TypeGen Test = ag.Class("Test"); { CodeGen g = Test.Public.Static.Method(typeof(void), "Main"); { // test calling virtual member directly on a literal // g.Local(Operand.FromObject(3).Invoke("GetHashCode")); // test special case where the value type target doesn't implement the virtual function var value = g.Local(Test); g.Assign(value, ag.ExpressionFactory.New(Test)); g.WriteLine("Hash code of {0} is {1}", value, value.Invoke("GetHashCode")); } if (impl) { g = Test.Public.Override.Method(typeof(int), "GetHashCode"); { g.Return(-1); } } } }
public static void GenOriginalTest(AssemblyGen ag) { TypeGen Test = ag.Class("Test"); { CodeGen g = Test.Static.Method(typeof(void), "Main"); { Operand value = g.Local(typeof(int), 3); g.WriteLine("Hash code of {0} is {1}", value, value.Invoke("GetHashCode")); } } }
// 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")); } } }
// example based on the MSDN Structs Sample (struct2.cs) public static void GenStruct2(AssemblyGen ag) { 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"); { g.Assign(g.Arg("s").Field("x"), 5); } g = TestClass.Public.Static.Method(typeof(void), "classtaker").Parameter(TheClass, "c"); { g.Assign(g.Arg("c").Field("x"), 5); } g = TestClass.Public.Static.Method(typeof(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")); } } }
// 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"); } } }
// example based on the MSDN Versioning Sample (versioning.cs) public static void GenVersioning(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; ITypeMapper m = ag.TypeMapper; TypeGen MyBase = ag.Public.Class("MyBase"); { MyBase.Public.Virtual.Method(typeof(string), "Meth1").GetCode() .Return("MyBase-Meth1"); MyBase.Public.Virtual.Method(typeof(string), "Meth2").GetCode() .Return("MyBase-Meth2"); MyBase.Public.Virtual.Method(typeof(string), "Meth3").GetCode() .Return("MyBase-Meth3"); } TypeGen MyDerived = ag.Class("MyDerived", MyBase); { // Overrides the virtual method Meth1 using the override keyword: MyDerived.Public.Override.Method(typeof(string), "Meth1").GetCode() .Return("MyDerived-Meth1"); // Explicitly hide the virtual method Meth2 using the new // keyword: // remark: new is not supported/required in RunSharp MyDerived.Public.Method(typeof(string), "Meth2").GetCode() .Return("MyDerived-Meth2"); // Because no keyword is specified in the following declaration // a warning will be issued to alert the programmer that // the method hides the inherited member MyBase.Meth3(): // remark: this warning is not supported in RunSharp MyDerived.Public.Method(typeof(string), "Meth3").GetCode() .Return("MyDerived-Meth3"); CodeGen g = MyDerived.Public.Static.Method(typeof(void), "Main"); { var mD = g.Local(exp.New(MyDerived)); var mB = g.Local(mD.Cast(MyBase)); g.WriteLine(mB.Invoke("Meth1")); g.WriteLine(mB.Invoke("Meth2")); g.WriteLine(mB.Invoke("Meth3")); } } }
// example based on the MSDN Properties Sample (person.cs) public static void GenPerson(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; TypeGen Person = ag.Class("Person"); { FieldGen myName = Person.Private.Field(typeof(string), "myName", "N/A"); FieldGen myAge = Person.Private.Field(typeof(int), "myAge", 0); // Declare a Name property of type string: PropertyGen Name = Person.Public.SimpleProperty(myName, "Name"); // Declare an Age property of type int: PropertyGen Age = Person.Public.SimpleProperty(myAge, "Age"); CodeGen g = Person.Public.Override.Method(typeof(string), "ToString"); { g.Return("Name = " + Name + ", Age = " + Age); } g = Person.Public.Static.Method(typeof(void), "Main"); { g.WriteLine("Simple Properties"); // Create a new Person object: var person = g.Local(exp.New(Person)); // Print out the name and the age associated with the person: g.WriteLine("Person details - {0}", person); // Set some values on the person object: ITypeMapper typeMapper = ag.TypeMapper; g.Assign(person.Property("Name"), "Joe"); ITypeMapper typeMapper1 = ag.TypeMapper; g.Assign(person.Property("Age"), 99); g.WriteLine("Person details - {0}", person); // Increment the Age property: ITypeMapper typeMapper2 = ag.TypeMapper; g.AssignAdd(person.Property("Age"), 1); g.WriteLine("Person details - {0}", person); } } }
private void EmitMainClass(NonTerm nonTerm) { Token termClassId; List <BaseSymbol> declarations; NonTermFactory.GetMainClassDecl(nonTerm, out termClassId, out declarations); _currentClass = _asm.Class(termClassId.Value); _classesTable.Add(_currentClass.Name, _currentClass); _g = _currentClass.Public.Static.Method(typeof(void), "Main"); GeneratePreInitLocalVariables(nonTerm); declarations.ForEach(symbol => Generate(symbol)); ClearCurrentBlockLocalVariables(); }
// 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"); } } }
// example based on the MSDN Versioning Sample (versioning.cs) public static void GenVersioning(AssemblyGen ag) { TypeGen MyBase = ag.Public.Class("MyBase"); { MyBase.Public.Virtual.Method(typeof(string), "Meth1").GetCode() .Return("MyBase-Meth1"); MyBase.Public.Virtual.Method(typeof(string), "Meth2").GetCode() .Return("MyBase-Meth2"); MyBase.Public.Virtual.Method(typeof(string), "Meth3").GetCode() .Return("MyBase-Meth3"); } TypeGen MyDerived = ag.Class("MyDerived", MyBase); { // Overrides the virtual method Meth1 using the override keyword: MyDerived.Public.Override.Method(typeof(string), "Meth1").GetCode() .Return("MyDerived-Meth1"); // Explicitly hide the virtual method Meth2 using the new // keyword: // remark: new is not supported/required in RunSharp MyDerived.Public.Method(typeof(string), "Meth2").GetCode() .Return("MyDerived-Meth2"); // Because no keyword is specified in the following declaration // a warning will be issued to alert the programmer that // the method hides the inherited member MyBase.Meth3(): // remark: this warning is not supported in RunSharp MyDerived.Public.Method(typeof(string), "Meth3").GetCode() .Return("MyDerived-Meth3"); CodeGen g = MyDerived.Public.Static.Method(typeof(void), "Main"); { Operand mD = g.Local(Exp.New(MyDerived)); Operand mB = g.Local(mD.Cast(MyBase)); g.WriteLine(mB.Invoke("Meth1")); g.WriteLine(mB.Invoke("Meth2")); g.WriteLine(mB.Invoke("Meth3")); } } }
public static void GenStaticCtor(AssemblyGen ag) { TypeGen Test = ag.Class("Test"); { FieldGen a = Test.Static.Field(typeof(int), "a"); CodeGen g = Test.StaticConstructor(); { g.WriteLine("Hello from .cctor!"); g.Assign(a, 3); } g = Test.Static.Method(typeof(void), "Main"); { g.Invoke(typeof(System.Diagnostics.Debug), "Assert", a == 3); g.WriteLine(".cctor works now..."); } } }
// example based on the MSDN Structs Sample (struct1.cs) public static void GenStruct1(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; CodeGen g; TypeGen SimpleStruct = ag.Struct("SimpleStruct"); { FieldGen xval = SimpleStruct.Field(typeof(int), "xval"); PropertyGen X = SimpleStruct.Public.Property(typeof(int), "X"); { X.Getter().GetCode().Return(xval); g = X.Setter(); { g.If(g.PropertyValue() < 100); { g.Assign(xval, g.PropertyValue()); } g.End(); } } g = SimpleStruct.Public.Method(typeof(void), "DisplayX"); { g.WriteLine("The stored value is: {0}", xval); } } TypeGen TestClass = ag.Class("TestClass"); { g = TestClass.Public.Static.Method(typeof(void), "Main"); { var ss = g.Local(SimpleStruct); g.InitObj(ss); ITypeMapper typeMapper = ag.TypeMapper; g.Assign(ss.Property("X"), 5); g.Invoke(ss, "DisplayX"); } } }
/// <summary> /// Загрузка всех классов (наследование не учитывается). /// </summary> /// <param name="root">Базовый символ</param> /// <param name="ag">Сборка</param> private void LoadClasses(BaseSymbol root, AssemblyGen ag) { root.Symbols.ForEach(s => { if (s.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = s as NonTerm; switch (nonTerm.TypeNonTerm) { case NonTermType.Class: Token termClassId; NonTermFactory.GetClassId(nonTerm, out termClassId); string classId = termClassId.Value; TypeGen cl = ag.Class(classId); _classesTable.Add(cl.Name, cl); break; } } }); }
// example based on the MSDN Properties Sample (person.cs) public static void GenPerson(AssemblyGen ag) { TypeGen Person = ag.Class("Person"); { FieldGen myName = Person.Private.Field(typeof(string), "myName", "N/A"); FieldGen myAge = Person.Private.Field(typeof(int), "myAge", 0); // Declare a Name property of type string: PropertyGen Name = Person.Public.SimpleProperty(myName, "Name"); // Declare an Age property of type int: PropertyGen Age = Person.Public.SimpleProperty(myAge, "Age"); CodeGen g = Person.Public.Override.Method(typeof(string), "ToString"); { g.Return("Name = " + Name + ", Age = " + Age); } g = Person.Public.Static.Method(typeof(void), "Main"); { g.WriteLine("Simple Properties"); // Create a new Person object: Operand person = g.Local(Exp.New(Person)); // Print out the name and the age associated with the person: g.WriteLine("Person details - {0}", person); // Set some values on the person object: g.Assign(person.Property("Name"), "Joe"); g.Assign(person.Property("Age"), 99); g.WriteLine("Person details - {0}", person); // Increment the Age property: g.AssignAdd(person.Property("Age"), 1); g.WriteLine("Person details - {0}", person); } } }
// example based on the MSDN Properties Sample (person.cs) public static void GenPerson(AssemblyGen ag) { TypeGen Person = ag.Class("Person"); { FieldGen myName = Person.Private.Field <string>("myName", "N/A"); FieldGen myAge = Person.Private.Field <int>("myAge", 0); // Declare a Name property of type string: PropertyGen Name = Person.Public.SimpleProperty(myName, "Name"); // Declare an Age property of type int: PropertyGen Age = Person.Public.SimpleProperty(myAge, "Age"); CodeGen g = Person.Public.Override.Method <string>("ToString"); { g.Return("Name = " + Name + ", Age = " + Age); } g = Person.Public.Static.Void("Main"); { g.WriteLine("Simple Properties"); // Create a new Person object: Operand person = g.Local(Exp.New(Person)); // Print out the name and the age associated with the person: g.WriteLine("Person details - {0}", person); // Set some values on the person object: g.Assign(person.Property("Name"), "Joe"); g.Assign(person.Property("Age"), 99); g.WriteLine("Person details - {0}", person); // Increment the Age property: g.AssignAdd(person.Property("Age"), 1); g.WriteLine("Person details - {0}", person); } } }
// example based on the MSDN Structs Sample (struct1.cs) public static void GenStruct1(AssemblyGen ag) { CodeGen g; TypeGen SimpleStruct = ag.Struct("SimpleStruct"); { FieldGen xval = SimpleStruct.Field <int>("xval"); PropertyGen X = SimpleStruct.Public.Property <int>("X"); { X.Getter().GetCode().Return(xval); g = X.Setter(); { g.If(g.PropertyValue() < 100); { g.Assign(xval, g.PropertyValue()); } g.End(); } } g = SimpleStruct.Public.Void("DisplayX"); { g.WriteLine("The stored value is: {0}", xval); } } TypeGen TestClass = ag.Class("TestClass"); { g = TestClass.Public.Static.Void("Main"); { Operand ss = g.Local(SimpleStruct); g.InitObj(ss); g.Assign(ss.Property("X"), 5); g.Invoke(ss, "DisplayX"); } } }
// example based on the MSDN Structs Sample (struct1.cs) public static void GenStruct1(AssemblyGen ag) { CodeGen g; TypeGen SimpleStruct = ag.Struct("SimpleStruct"); { FieldGen xval = SimpleStruct.Field(typeof(int), "xval"); PropertyGen X = SimpleStruct.Public.Property(typeof(int), "X"); { X.Getter().GetCode().Return(xval); g = X.Setter(); { g.If(g.PropertyValue() < 100); { g.Assign(xval, g.PropertyValue()); } g.End(); } } g = SimpleStruct.Public.Method(typeof(void), "DisplayX"); { g.WriteLine("The stored value is: {0}", xval); } } TypeGen TestClass = ag.Class("TestClass"); { g = TestClass.Public.Static.Method(typeof(void), "Main"); { Operand ss = g.Local(SimpleStruct); g.InitObj(ss); g.Assign(ss.Property("X"), 5); g.Invoke(ss, "DisplayX"); } } }
public static void GenTypeAttributeTest(AssemblyGen ag) { TypeGen MyAttribute = ag.Public.Class("MyAttribute", typeof(Attribute)) .BeginAttribute(typeof(AttributeUsageAttribute), AttributeTargets.Class).Set("AllowMultiple", true).End() ; FieldGen testField = MyAttribute.Field(typeof(object), "testField") .Attribute(typeof(DescriptionAttribute), "Test field") ; PropertyGen testProperty = MyAttribute.Public.SimpleProperty(testField, "TestProperty") .Attribute(typeof(ObsoleteAttribute), "Do not use this") ; testProperty.Getter().Attribute(typeof(DescriptionAttribute), "Getter method"); testProperty.Getter().ReturnParameter.Attribute(typeof(DescriptionAttribute), "Getter return value"); testProperty.Setter().Attribute(typeof(DescriptionAttribute), "Setter method"); TypeGen tg = ag.Class("Test") .BeginAttribute(MyAttribute).Set("TestProperty", 3).End() .Attribute(typeof(System.ComponentModel.DescriptionAttribute), "Test class") ; tg.Public.Static.Method(typeof(void), "Main") .BeginAttribute(MyAttribute).Set("TestProperty", 3).End() ; TypeGen SimpleDelegate = ag.Delegate(typeof(void), "SimpleDelegate") .Attribute(typeof(DescriptionAttribute), "Test delegate") ; EventGen TestEvent = tg.Static.Event(SimpleDelegate, "TestEvent") .Attribute(typeof(DescriptionAttribute), "Test event") ; TestEvent.AddMethod().Attribute(typeof(DescriptionAttribute), "Event add method"); TestEvent.RemoveMethod().Attribute(typeof(DescriptionAttribute), "Event remove method"); }
// 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")); } } }
// 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); } } }
// 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); } } }
// 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(typeof(int), "value"); // Private constructor. The value parameter must be -1, 0, or 1: CodeGen g = DBBool.Constructor().Parameter(typeof(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(typeof(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(typeof(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(typeof(bool), "Equals").Parameter(typeof(object), "o"); { g.Try(); { g.Return((g.This() == g.Arg("o").Cast(DBBool)).Cast(typeof(bool))); } g.CatchAll(); { g.Return(false); } g.End(); } // Override the Object.GetHashCode() method: g = DBBool.Public.Override.Method(typeof(int), "GetHashCode"); { g.Return(value); } // Override the ToString method to convert DBBool to a string: g = DBBool.Public.Override.Method(typeof(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(typeof(InvalidOperationException))); } g.End(); } } TypeGen Test = ag.Class("Test"); { CodeGen g = Test.Static.Method(typeof(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(); } } }
// 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")); } } } }
// example based on the MSDN Indexed Properties Sample (indexedproperty.cs) public static void GenIndexedProperty(AssemblyGen ag) { CodeGen g; TypeGen Document = ag.Public.Class("Document"); { FieldGen TextArray = Document.Private.Field(typeof(char[]), "TextArray"); // The text of the document. // Type allowing the document to be viewed like an array of words: TypeGen WordCollection = Document.Public.Class("WordCollection"); { FieldGen document = WordCollection.ReadOnly.Field(Document, "document"); // The containing document Operand document_TextArray = document.Field("TextArray"); // example of a saved expression - it is always re-evaluated when used g = WordCollection.Internal.Constructor().Parameter(Document, "d"); { g.Assign(document, g.Arg("d")); } // Helper function -- search character array "text", starting at // character "begin", for word number "wordCount." Returns false // if there are less than wordCount words.Sets "start" and // length" to the position and length of the word within text: g = WordCollection.Private.Method(typeof(bool), "GetWord") .Parameter(typeof(char[]), "text") .Parameter(typeof(int), "begin") .Parameter(typeof(int), "wordCount") .Out.Parameter(typeof(int), "start") .Out.Parameter(typeof(int), "length") ; { Operand text = g.Arg("text"), begin = g.Arg("begin"), wordCount = g.Arg("wordCount"), start = g.Arg("start"), length = g.Arg("length"); Operand end = g.Local(text.ArrayLength()); Operand count = g.Local(0); Operand inWord = g.Local(-1); g.Assign(start, length.Assign(0)); Operand i = g.Local(); g.For(i.Assign(begin), i <= end, i.Increment()); { Operand isLetter = g.Local(i < end && Static.Invoke(typeof(char), "IsLetterOrDigit", text[i])); g.If(inWord >= 0); { g.If(!isLetter); { g.If(count.PostIncrement() == wordCount); { g.Assign(start, inWord); g.Assign(length, i - inWord); g.Return(true); } g.End(); g.Assign(inWord, -1); } g.End(); } g.Else(); { g.If(isLetter); { g.Assign(inWord, i); } g.End(); } g.End(); } g.End(); g.Return(false); } // Indexer to get and set words of the containing document: PropertyGen Item = WordCollection.Public.Indexer(typeof(string)).Index(typeof(int), "index"); { g = Item.Getter(); { Operand index = g.Arg("index"); Operand start = g.Local(0), length = g.Local(0); g.If(g.This().Invoke("GetWord", document_TextArray, 0, index, start.Ref(), length.Ref())); { g.Return(Exp.New(typeof(string), document_TextArray, start, length)); } g.Else(); { g.Throw(Exp.New(typeof(IndexOutOfRangeException))); } g.End(); } g = Item.Setter(); { Operand index = g.Arg("index"); Operand value = g.PropertyValue(); Operand start = g.Local(0), length = g.Local(0); g.If(g.This().Invoke("GetWord", document_TextArray, 0, index, start.Ref(), length.Ref())); { // Replace the word at start/length with the // string "value": g.If(length == value.Property("Length")); { g.Invoke(typeof(Array), "Copy", value.Invoke("ToCharArray"), 0, document_TextArray, start, length); } g.Else(); { Operand newText = g.Local(Exp.NewArray(typeof(char), document_TextArray.ArrayLength() + value.Property("Length") - length)); g.Invoke(typeof(Array), "Copy", document_TextArray, 0, newText, 0, start); g.Invoke(typeof(Array), "Copy", value.Invoke("ToCharArray"), 0, newText, start, value.Property("Length")); g.Invoke(typeof(Array), "Copy", document_TextArray, start + length, newText, start + value.Property("Length"), document_TextArray.ArrayLength() - start - length); g.Assign(document_TextArray, newText); } g.End(); } g.Else(); { g.Throw(Exp.New(typeof(IndexOutOfRangeException))); } g.End(); } } // Get the count of words in the containing document: g = WordCollection.Public.Property(typeof(int), "Count").Getter(); { Operand count = g.Local(0), start = g.Local(0), length = g.Local(0); g.While(g.This().Invoke("GetWord", document_TextArray, start + length, 0, start.Ref(), length.Ref())); { g.Increment(count); } g.End(); g.Return(count); } } // Type allowing the document to be viewed like an "array" // of characters: TypeGen CharacterCollection = Document.Public.Class("CharacterCollection"); { FieldGen document = CharacterCollection.ReadOnly.Field(Document, "document"); // The containing document Operand document_TextArray = document.Field("TextArray"); g = CharacterCollection.Internal.Constructor().Parameter(Document, "d"); { g.Assign(document, g.Arg("d")); } // Indexer to get and set characters in the containing document: PropertyGen Item = CharacterCollection.Public.Indexer(typeof(char)).Index(typeof(int), "index"); { g = Item.Getter(); { g.Return(document_TextArray[g.Arg("index")]); } g = Item.Setter(); { g.Assign(document_TextArray[g.Arg("index")], g.PropertyValue()); } } // Get the count of characters in the containing document: g = CharacterCollection.Public.Property(typeof(int), "Count").Getter(); { g.Return(document_TextArray.ArrayLength()); } } // Because the types of the fields have indexers, // these fields appear as "indexed properties": FieldGen Words = Document.Public.ReadOnly.Field(WordCollection, "Words"); FieldGen Characters = Document.Public.ReadOnly.Field(CharacterCollection, "Characters"); g = Document.Public.Constructor().Parameter(typeof(string), "initialText"); { g.Assign(TextArray, g.Arg("initialText").Invoke("ToCharArray")); g.Assign(Words, Exp.New(WordCollection, g.This())); g.Assign(Characters, Exp.New(CharacterCollection, g.This())); } g = Document.Public.Property(typeof(string), "Text").Getter(); { g.Return(Exp.New(typeof(string), TextArray)); } } TypeGen Test = ag.Class("Test"); { g = Test.Public.Static.Method(typeof(void), "Main"); { Operand d = g.Local(Exp.New(Document, "peter piper picked a peck of pickled peppers. How many pickled peppers did peter piper pick?")); // Change word "peter" to "penelope": Operand i = g.Local(); g.For(i.Assign(0), i < d.Field("Words").Property("Count"), i.Increment()); { g.If(d.Field("Words")[i] == "peter"); { g.Assign(d.Field("Words")[i], "penelope"); } g.End(); } g.End(); // Change character "p" to "P" g.For(i.Assign(0), i < d.Field("Characters").Property("Count"), i.Increment()); { g.If(d.Field("Characters")[i] == 'p'); { g.Assign(d.Field("Characters")[i], 'P'); } g.End(); } g.End(); g.WriteLine(d.Property("Text")); } } }
// example based on the MSDN User-Defined Conversions Sample (conversion.cs) public static void GenConversion(AssemblyGen ag) { 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"); { 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"); { Operand 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: Operand s = g.Local(numeral.Cast(typeof(short))); g.WriteLine(s); } } }
// 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(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"); { 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"); { 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"); { 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(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); } } }
// example based on the MSDN Indexed Properties Sample (indexedproperty.cs) public static void GenIndexedProperty(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; CodeGen g; ITypeMapper m = ag.TypeMapper; TypeGen Document = ag.Public.Class("Document"); { FieldGen TextArray = Document.Private.Field(typeof(char[]), "TextArray"); // The text of the document. // Type allowing the document to be viewed like an array of words: TypeGen WordCollection = Document.Public.Class("WordCollection"); { FieldGen document = WordCollection.ReadOnly.Field(Document, "document"); // The containing document var document_TextArray = document.Field("TextArray", m); // example of a saved expression - it is always re-evaluated when used g = WordCollection.Internal.Constructor().Parameter(Document, "d"); { g.Assign(document, g.Arg("d")); } // Helper function -- search character array "text", starting at // character "begin", for word number "wordCount." Returns false // if there are less than wordCount words.Sets "start" and // length" to the position and length of the word within text: g = WordCollection.Private.Method(typeof(bool), "GetWord") .Parameter(typeof(char[]), "text") .Parameter(typeof(int), "begin") .Parameter(typeof(int), "wordCount") .Out.Parameter(typeof(int), "start") .Out.Parameter(typeof(int), "length") ; { ContextualOperand text = g.Arg("text"), begin = g.Arg("begin"), wordCount = g.Arg("wordCount"), start = g.Arg("start"), length = g.Arg("length"); var end = g.Local(text.ArrayLength()); var count = g.Local(0); var inWord = g.Local(-1); g.Assign(start, length.Assign(0)); var i = g.Local(); g.For(i.Assign(begin), i <= end, i.Increment()); { var isLetter = g.Local(i < end && st.Invoke(typeof(char), "IsLetterOrDigit", text[i])); g.If(inWord >= 0); { g.If(!isLetter); { g.If(count.PostIncrement() == wordCount); { g.Assign(start, inWord); g.Assign(length, i - inWord); g.Return(true); } g.End(); g.Assign(inWord, -1); } g.End(); } g.Else(); { g.If(isLetter); { g.Assign(inWord, i); } g.End(); } g.End(); } g.End(); g.Return(false); } // Indexer to get and set words of the containing document: PropertyGen Item = WordCollection.Public.Indexer(typeof(string)).Index(typeof(int), "index"); { g = Item.Getter(); { var index = g.Arg("index"); var start = g.Local(0); var length = g.Local(0); g.If(g.This().Invoke("GetWord", document_TextArray, 0, index, start.Ref(), length.Ref())); { g.Return(exp.New(typeof(string), document_TextArray, start, length)); } g.Else(); { g.Throw(exp.New(typeof(IndexOutOfRangeException))); } g.End(); } g = Item.Setter(); { var index = g.Arg("index"); var value = g.PropertyValue(); var start = g.Local(0); var length = g.Local(0); g.If(g.This().Invoke("GetWord", document_TextArray, 0, index, start.Ref(), length.Ref())); { // Replace the word at start/length with the // string "value": g.If(length == value.Property("Length")); { g.Invoke(typeof(Array), "Copy", value.Invoke("ToCharArray"), 0, document_TextArray, start, length); } g.Else(); { var newText = g.Local(exp.NewArray(typeof(char), document_TextArray.ArrayLength() + value.Property("Length") - length)); g.Invoke(typeof(Array), "Copy", document_TextArray, 0, newText, 0, start); g.Invoke(typeof(Array), "Copy", value.Invoke("ToCharArray"), 0, newText, start, value.Property("Length")); g.Invoke(typeof(Array), "Copy", document_TextArray, start + length, newText, start + value.Property("Length"), document_TextArray.ArrayLength() - start - length); g.Assign(document_TextArray, newText); } g.End(); } g.Else(); { g.Throw(exp.New(typeof(IndexOutOfRangeException))); } g.End(); } } // Get the count of words in the containing document: g = WordCollection.Public.Property(typeof(int), "Count").Getter(); { ContextualOperand count = g.Local(0), start = g.Local(0), length = g.Local(0); g.While(g.This().Invoke("GetWord", document_TextArray, start + length, 0, start.Ref(), length.Ref())); { g.Increment(count); } g.End(); g.Return(count); } } // Type allowing the document to be viewed like an "array" // of characters: TypeGen CharacterCollection = Document.Public.Class("CharacterCollection"); { FieldGen document = CharacterCollection.ReadOnly.Field(Document, "document"); // The containing document var document_TextArray = document.Field("TextArray", m); g = CharacterCollection.Internal.Constructor().Parameter(Document, "d"); { g.Assign(document, g.Arg("d")); } // Indexer to get and set characters in the containing document: PropertyGen Item = CharacterCollection.Public.Indexer(typeof(char)).Index(typeof(int), "index"); { g = Item.Getter(); { g.Return(document_TextArray[g.Arg("index")]); } g = Item.Setter(); { g.Assign(document_TextArray[g.Arg("index")], g.PropertyValue()); } } // Get the count of characters in the containing document: g = CharacterCollection.Public.Property(typeof(int), "Count").Getter(); { g.Return(document_TextArray.ArrayLength()); } } // Because the types of the fields have indexers, // these fields appear as "indexed properties": FieldGen Words = Document.Public.ReadOnly.Field(WordCollection, "Words"); FieldGen Characters = Document.Public.ReadOnly.Field(CharacterCollection, "Characters"); g = Document.Public.Constructor().Parameter(typeof(string), "initialText"); { g.Assign(TextArray, g.Arg("initialText").Invoke("ToCharArray")); g.Assign(Words, exp.New(WordCollection, g.This())); g.Assign(Characters, exp.New(CharacterCollection, g.This())); } g = Document.Public.Property(typeof(string), "Text").Getter(); { g.Return(exp.New(typeof(string), TextArray)); } } TypeGen Test = ag.Class("Test"); { g = Test.Public.Static.Method(typeof(void), "Main"); { var d = g.Local(exp.New(Document, "peter piper picked a peck of pickled peppers. How many pickled peppers did peter piper pick?")); // Change word "peter" to "penelope": var i = g.Local(); g.For(i.Assign(0), i < d.Field("Words").Property("Count"), i.Increment()); { g.If(d.Field("Words")[i] == "peter"); { g.Assign(d.Field("Words")[i], "penelope"); } g.End(); } g.End(); // Change character "p" to "P" g.For(i.Assign(0), i < d.Field("Characters").Property("Count"), i.Increment()); { g.If(d.Field("Characters")[i] == 'p'); { g.Assign(d.Field("Characters")[i], 'P'); } g.End(); } g.End(); g.WriteLine(d.Property("Text")); } } }
// 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")); } } } }
// example based on the MSDN Delegates Sample (compose.cs) public static void GenCompose(AssemblyGen ag) { 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"); { 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"); } } }
// 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); } } }
// example based on the MSDN Explicit Interface Implementation Sample (explicit.cs) public static void GenExplicit2(AssemblyGen ag) { // 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": Operand myBox = g.Local(Exp.New(Box, 30.0f, 20.0f)); // Declare an instance of the English units interface: Operand eDimensions = g.Local(myBox.Cast(IEnglishDimensions)); // Declare an instance of the metric units interface: Operand 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")); } } }
// 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")); } } } }
// 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(); } } }
// 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"); } } } }