Example #1
0
        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]);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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);
        }