Exemple #1
0
        public override void GenerateCode(ModuleBuilder moduleBuilder, TypeBuilder program, ILGenerator generator)
        {
            if (FunctionInfo.IsStandard)
            {
                foreach (var Argument in this.Arguments)
                {
                    Argument.GenerateCode(moduleBuilder, program, generator);
                }
                generator.Emit(OpCodes.Call, this.FunctionInfo.MethodBuilder);
            }
            else
            {
                //--------------------------------------------------
                // Guarda Los Argumentos En El Stack Auxiliar.
                //--------------------------------------------------
                for (int i = 0; i < this.Arguments.Count(); i++)
                {
                    var Argument = this.Arguments.ElementAt(i);
                    generator.Emit(OpCodes.Ldsfld, Argument.ExpressionType.VirtualStack2);
                    Argument.GenerateCode(moduleBuilder, program, generator);
                    generator.Emit(OpCodes.Callvirt,
                                   GenericStackHelper.GetMethod("Push", Argument.ExpressionType.UnderlyingSystemType)
                                   );
                }

                //--------------------------------------------------
                // Salva El Valor De Las Variables Locales (Stack1)
                //--------------------------------------------------
                VariableInfo[] Locals = this.FunctionInfo.Scope.GetDescendingVariableInfos().ToArray();
                for (int i = 0; i < Locals.Length; i++)
                {
                    Locals[i].DeclareVariable(program);
                    generator.Emit(OpCodes.Ldsfld, Locals[i].TypeNode.VirtualStack1);
                    generator.Emit(OpCodes.Ldsfld, Locals[i].FieldBuilder);
                    generator.Emit(OpCodes.Callvirt,
                                   GenericStackHelper.GetMethod("Push", Locals[i].TypeNode.UnderlyingSystemType)
                                   );
                }

                //--------------------------------------------------
                // Traer De Stack2 Los Argumentos Para El LLamado De La Función.
                //--------------------------------------------------
                for (int i = this.Arguments.Count() - 1; i >= 0; i--)
                {
                    var Argument = this.Arguments.ElementAt(i);
                    generator.Emit(OpCodes.Ldsfld, Argument.ExpressionType.VirtualStack2);
                    generator.Emit(OpCodes.Callvirt,
                                   GenericStackHelper.GetMethod("Pop", Argument.ExpressionType.UnderlyingSystemType)
                                   );
                    generator.Emit(OpCodes.Stsfld, this.FunctionInfo.Parameters[i].FieldBuilder);
                }

                //--------------------------------------------------
                // [Stack Status]
                // 1. func( arg_1, arg_2, ..., arg_n ) [Si 'func' Retorna]
                // (...)
                //--------------------------------------------------
                generator.Emit(OpCodes.Call, this.FunctionInfo.MethodBuilder);

                LocalBuilder Ret = null;

                if (this.FunctionInfo.ReturnType != PredefinedTypes.VoidType)
                {
                    Ret = generator.DeclareLocal(this.FunctionInfo.ReturnType.UnderlyingSystemType);
                    generator.Emit(OpCodes.Stloc, Ret.LocalIndex);
                }

                for (int i = Locals.Length - 1; i >= 0; i--)
                {
                    generator.Emit(OpCodes.Ldsfld, Locals[i].TypeNode.VirtualStack1);
                    generator.Emit(OpCodes.Callvirt,
                                   GenericStackHelper.GetMethod("Pop", Locals[i].TypeNode.UnderlyingSystemType)
                                   );
                    generator.Emit(OpCodes.Stsfld, Locals[i].FieldBuilder);
                }

                if (this.FunctionInfo.ReturnType != PredefinedTypes.VoidType)
                {
                    generator.Emit(OpCodes.Ldloc, Ret.LocalIndex);
                }
            }
        }
Exemple #2
0
        public override void GenerateCode(ModuleBuilder moduleBuilder, TypeBuilder program, ILGenerator generator)
        {
            //--------------------------------------------------
            // Generate Stack Fields For Builtin Types (int & string).
            //--------------------------------------------------
            PredefinedTypes.IntType.VirtualStack1 = program.DefineField(
                string.Format("STACK_{0}", ++TigerNode.VariablesDeclared),
                typeof(Stack <>).MakeGenericType(new Type[] { typeof(int) }),
                FieldAttributes.Static
                );

            PredefinedTypes.IntType.VirtualStack2 = program.DefineField(
                string.Format("STACK_{0}", ++TigerNode.VariablesDeclared),
                typeof(Stack <>).MakeGenericType(new Type[] { typeof(int) }),
                FieldAttributes.Static
                );

            PredefinedTypes.StrType.VirtualStack1 = program.DefineField(
                string.Format("STACK_{0}", ++TigerNode.VariablesDeclared),
                typeof(Stack <>).MakeGenericType(new Type[] { typeof(string) }),
                FieldAttributes.Static
                );

            PredefinedTypes.StrType.VirtualStack2 = program.DefineField(
                string.Format("STACK_{0}", ++TigerNode.VariablesDeclared),
                typeof(Stack <>).MakeGenericType(new Type[] { typeof(string) }),
                FieldAttributes.Static
                );

            //--------------------------------------------------
            // [Stack Status]
            // 1. expression [Si 'expression' Retorna]
            //--------------------------------------------------
            this.Expression.GenerateCode(moduleBuilder, program, generator);

            //--------------------------------------------------
            // [Stack Status]
            //--------------------------------------------------
            if (this.Expression.ExpressionType != PredefinedTypes.VoidType)
            {
                generator.Emit(OpCodes.Pop);
            }

            //--------------------------------------------------
            // Main Return.
            //--------------------------------------------------
            generator.Emit(OpCodes.Ret);

            //--------------------------------------------------
            // Define Ctor For Program
            //--------------------------------------------------
            var ConstructorBuilder = program.DefineConstructor(MethodAttributes.SpecialName |
                                                               MethodAttributes.Static |
                                                               MethodAttributes.Private |
                                                               MethodAttributes.HideBySig |
                                                               MethodAttributes.RTSpecialName,
                                                               CallingConventions.Standard, System.Type.EmptyTypes);

            var ConstructorGenerator = ConstructorBuilder.GetILGenerator();

            /* Stack1 - int */
            ConstructorGenerator.Emit(OpCodes.Newobj, GenericStackHelper.GetDefaultConstructor(typeof(int)));
            ConstructorGenerator.Emit(OpCodes.Stsfld, PredefinedTypes.IntType.VirtualStack1);

            /* Stack2 - int */
            ConstructorGenerator.Emit(OpCodes.Newobj, GenericStackHelper.GetDefaultConstructor(typeof(int)));
            ConstructorGenerator.Emit(OpCodes.Stsfld, PredefinedTypes.IntType.VirtualStack2);

            /* Stack1 - string */
            ConstructorGenerator.Emit(OpCodes.Newobj, GenericStackHelper.GetDefaultConstructor(typeof(string)));
            ConstructorGenerator.Emit(OpCodes.Stsfld, PredefinedTypes.StrType.VirtualStack1);

            /* Stack2 - string */
            ConstructorGenerator.Emit(OpCodes.Newobj, GenericStackHelper.GetDefaultConstructor(typeof(string)));
            ConstructorGenerator.Emit(OpCodes.Stsfld, PredefinedTypes.StrType.VirtualStack2);

            /* Stack1 & Stack2 - other types */
            foreach (var TI in Program.scope.GetDescendingTypeInfos())
            {
                if (!(TI.TypeNode is AliasTypeNode || TI.TypeNode is BuiltinType))
                {
                    /* Stack1 - <> */
                    ConstructorGenerator.Emit(OpCodes.Newobj,
                                              GenericStackHelper.GetDefaultConstructor(TI.TypeNode.UnderlyingSystemType)
                                              );
                    ConstructorGenerator.Emit(OpCodes.Stsfld, TI.TypeNode.VirtualStack1);
                    /* Stack2 - <> */
                    ConstructorGenerator.Emit(OpCodes.Newobj,
                                              GenericStackHelper.GetDefaultConstructor(TI.TypeNode.UnderlyingSystemType)
                                              );
                    ConstructorGenerator.Emit(OpCodes.Stsfld, TI.TypeNode.VirtualStack2);
                }
            }

            ConstructorGenerator.Emit(OpCodes.Ret);
        }