상속: ExecutionEnvironment
예제 #1
0
        public IEnumerable <Position> Execute(QuipuEnv qee)
        {
            // Empty program: exit immediately
            if (qee.ThreadValues.Count == 0)
            {
                yield break;
            }

            while (true)
            {
                var instr = Threads[qee.CurrentThread].Knots[qee.CurrentKnot];
                yield return(instr.Position);

                var result = instr.Instruction(qee);
                if (result != null)
                {
                    if (result.Value == -1)
                    {
                        yield break;
                    }
                    if (result.Value < -1 || result.Value >= Threads.Length)
                    {
                        throw new InvalidOperationException(@"Jump to invalid thread {0}.".Fmt(result));
                    }
                    qee.ThreadValues[qee.CurrentThread] = qee.Stack.Pop();
                    qee.CurrentThread = result.Value;
                    qee.CurrentKnot   = 0;
                    qee.Stack.Clear();
                    qee.Stack.Push(qee.ThreadValues[result.Value]);
                }
                else
                {
                    qee.CurrentKnot++;
                    if (qee.CurrentKnot >= Threads[qee.CurrentThread].Knots.Count)
                    {
                        qee.ThreadValues[qee.CurrentThread] = qee.Stack.Pop();
                        qee.CurrentThread++;
                        if (qee.CurrentThread >= Threads.Length)
                        {
                            break;
                        }
                        qee.CurrentKnot = 0;
                        qee.Stack.Clear();
                        qee.Stack.Push(qee.ThreadValues[qee.CurrentThread]);
                    }
                }
            }

            yield return(new Position(SourceLength, 0));
        }
예제 #2
0
        public IEnumerable<Position> Execute(QuipuEnv qee)
        {
            // Empty program: exit immediately
            if (qee.ThreadValues.Count == 0)
                yield break;

            while (true)
            {
                var instr = Threads[qee.CurrentThread].Knots[qee.CurrentKnot];
                yield return instr.Position;
                var result = instr.Instruction(qee);
                if (result != null)
                {
                    if (result.Value == -1)
                        yield break;
                    if (result.Value < -1 || result.Value >= Threads.Length)
                        throw new InvalidOperationException(@"Jump to invalid thread {0}.".Fmt(result));
                    qee.ThreadValues[qee.CurrentThread] = qee.Stack.Pop();
                    qee.CurrentThread = result.Value;
                    qee.CurrentKnot = 0;
                    qee.Stack.Clear();
                    qee.Stack.Push(qee.ThreadValues[result.Value]);
                }
                else
                {
                    qee.CurrentKnot++;
                    if (qee.CurrentKnot >= Threads[qee.CurrentThread].Knots.Count)
                    {
                        qee.ThreadValues[qee.CurrentThread] = qee.Stack.Pop();
                        qee.CurrentThread++;
                        if (qee.CurrentThread >= Threads.Length)
                            break;
                        qee.CurrentKnot = 0;
                        qee.Stack.Clear();
                        qee.Stack.Push(qee.ThreadValues[qee.CurrentThread]);
                    }
                }
            }

            yield return new Position(SourceLength, 0);
        }