Ejemplo n.º 1
0
        /// <summary>
        /// Generate code for the entrypoint function
        /// </summary>
        public void GenerateCode(ASTNode node)
        {
            #region Early testing
            //MethodInfo stringtoint = typeof(Convert).GetMethod("ToInt32", new[] { typeof(string) });
            //ILGenerator generator = EntryPoint.GetILGenerator();

            #region Testing built in functions

            #region testing print

            //generator.Emit(OpCodes.Ldstr, "Hello World");
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["print"]);

            #endregion

            #region testing printi

            //generator.Emit(OpCodes.Ldc_I4, 255);
            //generator.Emit(OpCodes.Call,BuiltInFunctiontoBuilder["printi"]);

            #endregion

            #region testing printline

            //generator.Emit(OpCodes.Ldstr, "Hello World");
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]);

            #endregion

            #region testing flush

            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["flush"]);

            #endregion

            #region testing getchar

            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getchar"]);
            //generator.DeclareLocal(typeof (string));
            //generator.Emit(OpCodes.Stloc_0);
            //generator.Emit(OpCodes.Ldloc_0);
            //generator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(string)},null));

            #endregion

            #region testing getline

            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]);

            #endregion

            #region testing ord

            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["ord"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printi"]);

            #endregion

            #region testing chr

            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]);
            //generator.Emit(OpCodes.Call, stringtoint);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["chr"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]);

            #endregion

            #region testing size

            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["size"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printi"]);

            #endregion

            #region testing substring

            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]);
            //generator.Emit(OpCodes.Ldc_I4_0);
            //generator.Emit(OpCodes.Ldc_I4_2);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["substring"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]);

            #endregion

            #region testing concat

            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["concat"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]);

            #endregion

            #region testing not

            //generator.Emit(OpCodes.Ldc_I4_0);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["not"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printi"]);
            //generator.Emit(OpCodes.Ldc_I4_2);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["not"]);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printi"]);

            #endregion

            #region testing exit

            //generator.Emit(OpCodes.Ldc_I4_0);
            //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["exit"]);

            #endregion

            #endregion

            #region Testing Type and Array Creation

            //TypeBuilder builder = ILModule.DefineType("Person");
            //FieldBuilder fieldBuilder0 = builder.DefineField("Name", typeof(string), FieldAttributes.Public);
            //FieldBuilder fieldBuilder1 = builder.DefineField("Age", typeof(int), FieldAttributes.Public);
            //ConstructorBuilder ctor = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard,
            //                          new Type[] { typeof(string), typeof(int) });
            //ILGenerator ctorIlgen = ctor.GetILGenerator();

            //ctorIlgen.Emit(OpCodes.Ldarg_0);
            //ctorIlgen.Emit(OpCodes.Ldarg_1);
            //ctorIlgen.Emit(OpCodes.Stfld, fieldBuilder0);
            //ctorIlgen.Emit(OpCodes.Ldarg_0);
            //ctorIlgen.Emit(OpCodes.Ldarg_2);
            //ctorIlgen.Emit(OpCodes.Stfld, fieldBuilder1);
            //ctorIlgen.Emit(OpCodes.Ret);
            //builder.CreateType();

            //LocalBuilder person = IlGenerator.DeclareLocal(builder);
            //LocalBuilder arrayofperson = IlGenerator.DeclareLocal(builder.MakeArrayType());
            //IlGenerator.Emit(OpCodes.Ldstr, "Frank");
            //IlGenerator.Emit(OpCodes.Ldc_I4, 22);
            //IlGenerator.Emit(OpCodes.Newobj, ctor);
            //IlGenerator.Emit(OpCodes.Stloc_0);
            //IlGenerator.Emit(OpCodes.Ldloc_0);
            //IlGenerator.Emit(OpCodes.Ldfld, fieldBuilder0);
            //IlGenerator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]);

            //IlGenerator.Emit(OpCodes.Ldc_I4_1);
            //IlGenerator.Emit(OpCodes.Newarr, builder);
            //IlGenerator.Emit(OpCodes.Stloc_1);
            //IlGenerator.Emit(OpCodes.Ldloc_1);
            //IlGenerator.Emit(OpCodes.Ldc_I4_0);
            //IlGenerator.Emit(OpCodes.Ldloc_0);
            //IlGenerator.Emit(OpCodes.Stelem, builder);
            //IlGenerator.Emit(OpCodes.Ldloc_1);
            //IlGenerator.Emit(OpCodes.Ldc_I4_0);
            //IlGenerator.Emit(OpCodes.Ldelem, builder);
            //IlGenerator.Emit(OpCodes.Ldfld, fieldBuilder0);
            //IlGenerator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]);

            #endregion

            #region Testing Field Acces an Store
            #endregion
            #endregion

            //All the needed resources to handle exceptions
            Type       exception      = typeof(Exception);
            MethodInfo geterroroutput = typeof(Console).GetProperty("Error").GetGetMethod();
            MethodInfo writeline      = typeof(TextWriter).GetMethod("WriteLine", new [] { typeof(string), typeof(object) });
            MethodInfo readline       = typeof(Console).GetMethod("ReadLine");
            MethodInfo gettype        = typeof(Exception).GetMethod("GetType");
            MethodInfo exit           = typeof(Environment).GetMethod("Exit", new [] { typeof(int) });

            LocalBuilder exceptioninstance = IlGenerator.DeclareLocal(exception);


            //To enclose all the generated code in an enormous try
            IlGenerator.BeginExceptionBlock();
            node.GenerateCode(this);

            // To handle exceptions thrown by IL execution code
            IlGenerator.BeginCatchBlock(exception);
            //the launched exception will be in the top of the stack so we must store it
            IlGenerator.Emit(OpCodes.Stloc, exceptioninstance);

            //Getting the std error output
            IlGenerator.Emit(OpCodes.Call, geterroroutput);
            //Get the parameters to report to the error output
            IlGenerator.Emit(OpCodes.Ldstr, "\nException of type '{0}' was thrown");
            IlGenerator.Emit(OpCodes.Ldloc, exceptioninstance);
            IlGenerator.Emit(OpCodes.Call, gettype);

            //Calling the writeline method of the error output
            IlGenerator.Emit(OpCodes.Call, writeline);

            // Set a readline son the user can see the exception thrown, comment this line if there is any problem
            //IlGenerator.EmitCall(OpCodes.Call, readline, null);

            //Exiting with code 1
            IlGenerator.Emit(OpCodes.Ldc_I4_1);
            IlGenerator.Emit(OpCodes.Call, exit);

            //Exception management is done
            IlGenerator.EndExceptionBlock();

            // No exception was thrown finish with exit code 0
            IlGenerator.Emit(OpCodes.Ldc_I4_0);
            IlGenerator.Emit(OpCodes.Call, exit);

            // Don't forget the ret
            IlGenerator.Emit(OpCodes.Ret);
            Program.CreateType();
        }