Пример #1
0
        protected void runProgram(string program, Dictionary <string, object> variablesIn, List <ISpecFinder> moduleSpecFinders, int expectedIterations, out FrameContext context)
        {
            CodeObject compiledProgram = null;

            try
            {
                compiledProgram = ByteCodeCompiler.Compile(program, variablesIn);
            }
            catch (CloacaParseException parseFailed)
            {
                Assert.Fail(parseFailed.Message);
            }

            Dis.dis(compiledProgram);

            // TODO: This dependency association is kind of gross. It's almost circular and is broken by assigning
            // the interpreter reference to the schedular after its initial constructor.
            var scheduler   = new Scheduler();
            var interpreter = new Interpreter(scheduler);

            interpreter.DumpState = true;
            foreach (var finder in moduleSpecFinders)
            {
                interpreter.AddModuleFinder(finder);
            }
            scheduler.SetInterpreter(interpreter);

            var receipt = scheduler.Schedule(compiledProgram);

            context = receipt.Frame;
            foreach (string varName in variablesIn.Keys)
            {
                context.SetVariable(varName, variablesIn[varName]);
            }

            // Waiting on the task makes sure we get punched in the face by any exceptions it throws.
            // But they'll come rolling in as AggregateExceptions so we'll have to unpack them.
            var scheduler_task = scheduler.RunUntilDone();

            scheduler_task.Wait();
            Assert.That(receipt.Completed);
            if (receipt.EscapedExceptionInfo != null)
            {
                receipt.EscapedExceptionInfo.Throw();
            }

            Assert.That(scheduler.TickCount, Is.EqualTo(expectedIterations));
        }
Пример #2
0
        protected async Task <FrameContext> runProgram(string program, Dictionary <string, object> variablesIn, List <ISpecFinder> moduleSpecFinders, int expectedIterations, bool checkExceptions = true)
        {
            // TODO: This dependency association is kind of gross. It's almost circular and is broken by assigning
            // the interpreter reference to the schedular after its initial constructor.
            var scheduler   = new Scheduler();
            var interpreter = new Interpreter(scheduler);

            interpreter.DumpState = true;
            foreach (var finder in moduleSpecFinders)
            {
                interpreter.AddModuleFinder(finder);
            }
            scheduler.SetInterpreter(interpreter);
            scheduler.OnTaskScheduled += whenTaskScheduled;

            escapedExceptions = new List <ExceptionDispatchInfo>();
            CodeObject        compiledProgram = null;
            Task <CodeObject> compiledTask    = null;

            try
            {
                // This is awaitable now but relies on the scheduler. We'll tick the scheduler
                // awhile until this resolves.
                compiledTask = ByteCodeCompiler.Compile(program, variablesIn, scheduler);
            }
            catch (CloacaParseException parseFailed)
            {
                Assert.Fail(parseFailed.Message);
            }

            for (int tries = 1; tries < 1000 && !compiledTask.IsCompleted && escapedExceptions.Count == 0; ++tries)
            {
                await scheduler.Tick();
            }

            if (!compiledTask.IsCompleted)
            {
                Assert.Fail("Compilation did not finish with interpreter after 1,000 scheduler ticks");
            }
            else if (escapedExceptions.Count > 0)
            {
                escapedExceptions[0].Throw();
            }
            compiledProgram = await compiledTask;
            Dis.dis(compiledProgram);

            receipt = scheduler.Schedule(compiledProgram);
            FrameContext context = receipt.Frame;

            foreach (string varName in variablesIn.Keys)
            {
                context.SetVariable(varName, variablesIn[varName]);
            }

            // Waiting on the task makes sure we get punched in the face by any exceptions it throws.
            // But they'll come rolling in as AggregateExceptions so we'll have to unpack them.
            var scheduler_task = scheduler.RunUntilDone();

            scheduler_task.Wait();
            Assert.That(receipt.Completed);

            if (checkExceptions)
            {
                AssertNoExceptions();
            }

            Assert.That(scheduler.TickCount, Is.EqualTo(expectedIterations));
            return(context);
        }