public void TestReturnStack() { DynamicMethod dynMeth = new DynamicMethod("Run", typeof(Stack), new Type[] {}, typeof(CompilerTests).Module); ILGenerator il = dynMeth.GetILGenerator(256); var ils = new ILStack(il); ils.Push(1); ils.Push(4); ils.Push(5); ils.MakeReturnStack(3); il.Emit(OpCodes.Ret); var f = (Func <Stack>)dynMeth.CreateDelegate(typeof(Func <Stack>)); var r = new Stack(); r.Push(5); r.Push(4); r.Push(1); // Unfortunately, it's kind of backwards. Assert.Equal(r, f()); }
public static int RunOptionsAndReturnExitCode(Options opts) { var program = File.ReadAllText(opts.inputFile).ToStack(); var assemblyName = Path.GetFileNameWithoutExtension(opts.outputFile); var extension = Path.GetExtension(opts.outputFile); if (opts.target == "") { switch (extension) { case ".exe": opts.target = "exe"; break; case ".dll": opts.target = "library"; break; default: Console.Error.WriteLine($"Please provide a -target option or a '.exe' or '.dll' suffix on output file."); return(3); } } switch (opts.target) { case "exe": if (extension != ".exe") { Console.Error.WriteLine($"Warning: creating an executable without a '.exe' extension"); } break; case "library": if (extension != ".dll") { Console.Error.WriteLine($"Warning: creating a library without a '.dll' extension"); } break; default: Console.Error.WriteLine($"No such target option '{opts.target}'."); return(1); } var emitter = new Emitter(assemblyName, extension); Type resultType; if (opts.resultType == "") { resultType = typeof(Stack); } else { resultType = Type.GetType(opts.resultType); } var methodBuilder = emitter.typeBuilder .DefineMethod("Program", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, CallingConventions.Standard, resultType, Type.EmptyTypes); if (opts.target == "exe") { emitter.EmitCallWriteStack(emitter.GetMain(), methodBuilder); } // var il = emitter.methodBuilder.GetILGenerator(); var il = methodBuilder.GetILGenerator(); var ilStack = new ILStack(il); var compiler = new Compiler(); program = compiler.Compile(program, ilStack); if (opts.resultType == "") { ilStack.MakeReturnStack(ilStack.count); ilStack.ReverseStack(); // Tack on the rest of the program. ilStack.PushPush(program.Peek()); } else { ilStack.FilterStack(Type.GetType(opts.resultType)); } il.Emit(OpCodes.Ret); emitter.Close(); return(0); }