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());
        }
Esempio n. 2
0
        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);
        }