Esempio n. 1
0
        private void Execute(Continuation cont)
        {
            _current = cont;
            while (Next())
            {
                if (!_break)
                {
                    continue;
                }

                _break   = false;
                _current = PopContext();
            }
        }
Esempio n. 2
0
        public void Continue(Continuation continuation)
        {
            PushContext(continuation);

            while (true)
            {
                Execute(_current);
                _break = false;

                _current = PopContext();
                if (_current == null)
                {
                    break;
                }
            }
        }
Esempio n. 3
0
        private Continuation PopContext()
        {
            for (var n = ContextStack.Count - 1; n >= 0; --n)
            {
                var cont = ContextStack[n];
                if (!cont.Active || !cont.Running)
                {
                    continue;
                }

                ContextStack.RemoveAt(n);
                return(_current = cont.Start(this));
            }

            return(null);
        }
Esempio n. 4
0
        /// <summary>
        /// Resume the continuation that spawned the current one
        /// </summary>
        private new void Resume()
        {
            if (!RPop(out var next))
            {
                Break();
                return;
            }

            switch (next)
            {
            case ICallable call:
                call.Invoke(_registry, DataStack);
                break;

            case IClassBase @class:
                Push(@class.NewInstance());
                break;

            case MethodInfo mi:
                var numArgs = mi.GetParameters().Length;
                if (DataStack.Count < numArgs + 1)
                {
                    var servant = DataStack.Count > 0 ? DataStack.Peek() : "null";
                    throw new NotEnoughArgumentsException($"{servant}.{mi.Name} expects {numArgs} args");
                }

                var obj  = Pop();
                var args = new object[numArgs];
                for (var n = 0; n < numArgs; ++n)
                {
                    args[numArgs - n - 1] = Pop();
                }
                var ret = mi.Invoke(obj, args);
                if (mi.ReturnType != typeof(void))
                {
                    Push(ret);
                }
                break;

            default:
                PushContext(next);
                _current = null;
                break;
            }

            Break();
        }
Esempio n. 5
0
 /// <summary>
 /// Stop the current continuation and resume whatever is on the
 /// context stack.
 /// </summary>
 private void Break()
 {
     _break   = true;
     _current = null;
 }
Esempio n. 6
0
 private void PushContext(Continuation continuation)
 {
     ContextStack.Add(continuation);
     _current = null;
 }