/// <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(); }