public void AddPieceType(PartialDefinition partial) { Type newtype = classFactory.CreatePieceTypeWrapper(moduleBuilder, typeof(PieceType), partial); PieceTypes.Add(partial.Name, newtype); globalEnvironment.AddSymbol(partial.Name, PieceTypes[partial.Name]); }
public override object VisitPieceTypeDeclaration([NotNull] ChessVCParser.PieceTypeDeclarationContext context) { string pieceName = getObjectName(context.identifier().GetText()); partial = new PartialDefinition(pieceName); var returnval = base.VisitPieceTypeDeclaration(context); compiler.AddPieceType(partial); return(returnval); }
public override object VisitGameDeclaration([NotNull] ChessVCParser.GameDeclarationContext context) { string gameName = getObjectName(context.identifier(0).GetText()); string baseGameName = getObjectName(context.identifier(1).GetText()); partial = new PartialDefinition(gameName, baseGameName); var returnval = base.VisitGameDeclaration(context); compiler.AddGame(partial); return(returnval); }
public Type CreatePieceTypeWrapper(ModuleBuilder module, Type basePieceType, PartialDefinition partial) { // Start building new type TypeBuilder typeBuilder = module.DefineType(getNextDynamicPieceTypeName(), TypeAttributes.Class | TypeAttributes.Public, basePieceType); // *** CREATE CONSTRUCTOR *** // Type[] constructorArgs = new Type[] { typeof(string), typeof(string), typeof(int), typeof(int), typeof(string) }; Type[] baseConstructorArgs = new Type[] { typeof(string), typeof(string), typeof(string), typeof(int), typeof(int), typeof(string) }; var baseClassConstructor = basePieceType.GetConstructor(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic, null, baseConstructorArgs, null); var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArgs); var ilGenerator = constructorBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldstr, partial.Name); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Ldarg_2); ilGenerator.Emit(OpCodes.Ldarg_3); ilGenerator.Emit(OpCodes.Ldarg_S, 4); ilGenerator.Emit(OpCodes.Ldarg_S, 5); ilGenerator.Emit(OpCodes.Call, baseClassConstructor); ilGenerator.Emit(OpCodes.Nop); ilGenerator.Emit(OpCodes.Nop); // Add any necessary instructions to initialize data members generateConstructorCode(ilGenerator, basePieceType, partial.VariableAssignments); ilGenerator.Emit(OpCodes.Ret); // *** ADD ENVIRONMENT FIELD *** // FieldBuilder environmentField = typeBuilder.DefineField("Environment", typeof(Environment), FieldAttributes.Public); // *** ADD FUNCTION CODE LOOKUP FIELD *** // FieldBuilder functionCodeLookupField = typeBuilder.DefineField("FunctionCodeLookup", typeof(Dictionary <string, Antlr4.Runtime.ParserRuleContext>), FieldAttributes.Public | FieldAttributes.Static); // *** OVERLOADED FUNCTIONS *** // foreach (KeyValuePair <string, Antlr4.Runtime.ParserRuleContext> pair in partial.FunctionDeclarations) { string functionName = pair.Key; generateFunctionWrapper(typeBuilder, basePieceType, environmentField, functionCodeLookupField, functionName); } // Complete type creation Type newtype = typeBuilder.CreateType(); // Assign the static function lookup member FieldInfo fi = newtype.GetField("FunctionCodeLookup", BindingFlags.Public | BindingFlags.Static); fi.SetValue(null, partial.FunctionDeclarations); return(newtype); }
public void AddGame(PartialDefinition partial) { object baseObj = globalEnvironment.LookupSymbol(partial.BaseName); if (baseObj == null) { throw new Exception("Specified base game is unknown: " + partial.BaseName); } if (!(baseObj is Type)) { throw new Exception("Specified base game is not of correct type: " + partial.BaseName); } Type baseGameType = (Type)baseObj; if (!baseGameType.IsSubclassOf(typeof(Game))) { throw new Exception("Specified base game is not of correct type: " + partial.BaseName); } Type newGameType = classFactory.CreateGameWrapper(moduleBuilder, baseGameType, partial); object[] attrobjs = baseGameType.GetCustomAttributes(typeof(GameAttribute), false); GameAttribute baseGameAttribute = (GameAttribute)attrobjs[0]; int[] geometryParameters = baseGameAttribute.GeometryParameters; if (geometryParameters.Length == 0) { geometryParameters = new int[] { (int)(partial.VariableAssignments["NumFiles"]), (int)(partial.VariableAssignments["NumRanks"]) } } ; GameAttribute newGameAttribute = new GameAttribute(partial.Name, baseGameAttribute.GeometryType, geometryParameters); AppearanceAttribute newAppearanceAttr = new AppearanceAttribute(); bool appearancePropertiesEncountered = false; if (partial.VariableAssignments.ContainsKey("Invented")) { newGameAttribute.Invented = (string)partial.VariableAssignments["Invented"]; } if (partial.VariableAssignments.ContainsKey("InventedBy")) { newGameAttribute.InventedBy = (string)partial.VariableAssignments["InventedBy"]; } if (partial.VariableAssignments.ContainsKey("GameDescription1")) { newGameAttribute.GameDescription1 = (string)partial.VariableAssignments["GameDescription1"]; if (partial.VariableAssignments.ContainsKey("GameDescription2")) { newGameAttribute.GameDescription2 = (string)partial.VariableAssignments["GameDescription2"]; } } if (partial.VariableAssignments.ContainsKey("Tags")) { newGameAttribute.Tags = (string)partial.VariableAssignments["Tags"]; } else { newGameAttribute.Tags = ""; } if (partial.VariableAssignments.ContainsKey("ColorScheme")) { appearancePropertiesEncountered = true; newAppearanceAttr.ColorScheme = (string)partial.VariableAssignments["ColorScheme"]; } if (partial.VariableAssignments.ContainsKey("NumberOfColors")) { appearancePropertiesEncountered = true; newAppearanceAttr.NumberOfSquareColors = Convert.ToInt32(partial.VariableAssignments["NumberOfColors"]); } if (partial.VariableAssignments.ContainsKey("PieceSet")) { appearancePropertiesEncountered = true; newAppearanceAttr.PieceSet = (string)partial.VariableAssignments["PieceSet"]; } if (partial.VariableAssignments.ContainsKey("Player1Color")) { appearancePropertiesEncountered = true; newAppearanceAttr.Player1Color = (string)partial.VariableAssignments["Player1Color"]; } if (partial.VariableAssignments.ContainsKey("Player2Color")) { appearancePropertiesEncountered = true; newAppearanceAttr.Player1Color = (string)partial.VariableAssignments["Player2Color"]; } GameTypes.Add(partial.Name, newGameType); GameAttributes.Add(partial.Name, newGameAttribute); if (appearancePropertiesEncountered) { GameAppearances.Add(partial.Name, newAppearanceAttr); } }
public Type CreateGameWrapper(ModuleBuilder module, Type baseGameType, PartialDefinition partial) { // Start building new type TypeBuilder typeBuilder = module.DefineType(getNextDynamicGameName(), TypeAttributes.Class | TypeAttributes.Public, baseGameType); // *** CREATE CONSTRUCTOR *** // Type[] constructorArgs = new Type[] { }; var baseClassConstructor = baseGameType.GetConstructor(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, constructorArgs, null); ConstructorInfo baseSymmetryConstructor = null; int numFiles = -1; int numRanks = -1; if (baseClassConstructor == null) { // First, check for a constructor taking only Symmetry baseClassConstructor = baseGameType.GetConstructor(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(Symmetry) }, null); if (baseClassConstructor != null) { Type baseSymmetryType = partial.VariableAssignments["Symmetry"].GetType(); baseSymmetryConstructor = baseSymmetryType.GetConstructor(constructorArgs); if (baseSymmetryConstructor == null) { throw new Exception("Abstract Game requires a Symmetry to be defined"); } } else { // Next, check for a constructor taking Symmetry, number of files, and number of ranks baseClassConstructor = baseGameType.GetConstructor(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(int), typeof(int), typeof(Symmetry) }, null); if (baseClassConstructor != null) { Type baseSymmetryType = partial.VariableAssignments["Symmetry"].GetType(); baseSymmetryConstructor = baseSymmetryType.GetConstructor(constructorArgs); if (baseSymmetryConstructor == null) { throw new Exception("Abstract Game requires a Symmetry to be defined"); } object numFilesObject = partial.VariableAssignments["NumFiles"]; if (numFilesObject == null || numFilesObject.GetType() != typeof(int)) { throw new Exception("Error defining game - NumFiles not defined"); } numFiles = (int)numFilesObject; object numRanksObject = partial.VariableAssignments["NumRanks"]; if (numRanksObject == null || numRanksObject.GetType() != typeof(int)) { throw new Exception("Error defining game - NumRanks not defined"); } numRanks = (int)numRanksObject; } else { throw new Exception("The base Game class is not supported - too many undefined parameters"); } } } var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArgs); var ilGenerator = constructorBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); if (numFiles != -1) { ilGenerator.Emit(OpCodes.Ldc_I4, numFiles); } if (numRanks != -1) { ilGenerator.Emit(OpCodes.Ldc_I4, numRanks); } if (baseSymmetryConstructor != null) { ilGenerator.Emit(OpCodes.Newobj, baseSymmetryConstructor); } ilGenerator.Emit(OpCodes.Call, baseClassConstructor); ilGenerator.Emit(OpCodes.Nop); ilGenerator.Emit(OpCodes.Nop); // Add any necessary instructions to initialize data members generateConstructorCode(ilGenerator, baseGameType, partial.VariableAssignments); ilGenerator.Emit(OpCodes.Ret); // *** ADD GAME VARIABLE MEMBERS *** // foreach (KeyValuePair <string, Type> pair in partial.MemberVariableDeclarations) { // Create a property for each of these with private member, getter, // and setter methods and apply the GameVariableAttribute to the property // create private field to hold value string fieldname = "_" + pair.Key.ToLower(); var field = typeBuilder.DefineField(fieldname, pair.Value, FieldAttributes.Private); // create property var propertyBuilder = typeBuilder.DefineProperty(pair.Key, PropertyAttributes.None, pair.Value, null); // create getter method var getter = typeBuilder.DefineMethod("get_" + pair.Key, MethodAttributes.Public, pair.Value, Type.EmptyTypes); var il = getter.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); // Push "this" on the stack il.Emit(OpCodes.Ldfld, field); // Load the field "_name" il.Emit(OpCodes.Ret); // Return propertyBuilder.SetGetMethod(getter); // create setter method var setter = typeBuilder.DefineMethod("set_" + pair.Key, MethodAttributes.Public, null, new Type[] { pair.Value }); il = setter.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); // Push "this" on the stack il.Emit(OpCodes.Ldarg_1); // Push "value" on the stack il.Emit(OpCodes.Stfld, field); // Set the field "_name" to "value" il.Emit(OpCodes.Ret); // Return propertyBuilder.SetSetMethod(setter); ConstructorInfo ci = typeof(GameVariableAttribute).GetConstructor(Type.EmptyTypes); CustomAttributeBuilder cab = new CustomAttributeBuilder(ci, new object[] { }); propertyBuilder.SetCustomAttribute(cab); } // *** ADD ENVIRONMENT FIELD *** // FieldBuilder environmentField = typeBuilder.DefineField("Environment", typeof(Environment), FieldAttributes.Public); // *** ADD FUNCTION CODE LOOKUP FIELD *** // FieldBuilder functionCodeLookupField = typeBuilder.DefineField("FunctionCodeLookup", typeof(Dictionary <string, Antlr4.Runtime.ParserRuleContext>), FieldAttributes.Public | FieldAttributes.Static); // *** OVERLOADED FUNCTIONS *** // foreach (KeyValuePair <string, Antlr4.Runtime.ParserRuleContext> pair in partial.FunctionDeclarations) { string functionName = pair.Key; generateFunctionWrapper(typeBuilder, baseGameType, environmentField, functionCodeLookupField, functionName); } // Complete type creation Type newtype = typeBuilder.CreateType(); // Assign the static function lookup member FieldInfo fi = newtype.GetField("FunctionCodeLookup", BindingFlags.Public | BindingFlags.Static); fi.SetValue(null, partial.FunctionDeclarations); return(newtype); }