Example #1
0
        public static IMatched <IObject> YieldAction(Machine machine)
        {
            var topFrame = machine.CurrentFrame;
            var frames   = machine.PopFrames();
            IMatched <IObject> returnValue;

            if (topFrame.IsEmpty)
            {
                returnValue = None.NoneValue.Matched();
            }
            else if (topFrame.Pop().If(out var popped, out var exception))
            {
                if (popped is None)
                {
                    returnValue = popped.Matched();
                }
                else
                {
                    IObject copy;
                    if (popped is IPristineCopy pc)
                    {
                        copy = pc.Copy();
                    }
                    else
                    {
                        copy = popped;
                    }

                    if (copy is ICopyFields cf)
                    {
                        cf.CopyFields(frames.Fields);
                    }

                    popped      = copy;
                    returnValue = new YieldReturn(popped, machine.Address, frames).Matched <IObject>();
                }
            }
            else
            {
                return(failedMatch <IObject>(exception));
            }

            if (frames.FunctionFrame.If(out var frame))
            {
                var returnAddress = frame.Address;

                if (machine.GoTo(returnAddress))
                {
                    return(returnValue);
                }
                else
                {
                    return(failedMatch <IObject>(badAddress(returnAddress)));
                }
            }
            else
            {
                return(failedMatch <IObject>(invalidStack()));
            }
        }
        protected internal override Statement VisitYieldReturn(YieldReturn inst)
        {
            var elementType = currentMethod.ReturnType.GetElementTypeFromIEnumerable(currentMethod.Compilation, true, out var isGeneric);

            return(new YieldReturnStatement {
                Expression = exprBuilder.Translate(inst.Value).ConvertTo(elementType, exprBuilder)
            });
        }
 public void RunYieldReturnNumbers()
 {
     YieldReturn.RunNumbers();
 }
Example #4
0
 protected internal override void VisitYieldReturn(YieldReturn inst)
 {
     DebugStartPoint(inst);
     inst.Value.AcceptVisitor(this);
     DebugEndPoint(inst);
 }
Example #5
0
        //public override void Cancel(object context, object id)
        //{
        //    MonoBehaviour unity = unityScheduler;
        //    if (id is UnityEngine.Coroutine)
        //    {
        //        var co = (UnityEngine.Coroutine)id;
        //        unity.StopCoroutine(co);
        //    }
        //    else if (id is string)
        //    {
        //        unity.StopCoroutine((string)id);
        //    }
        //    else if (id is IEnumerator)
        //    {
        //        unity.StopCoroutine((IEnumerator)id);
        //    }
        //}

        //public override void CancelAll(object context)
        //{
        //    MonoBehaviour unity = unityScheduler;
        //    unity.StopAllCoroutines();
        //}



        private IEnumerator AsCoroutine(COROUTINE coroutine, IEnumerator routine)
        {
            object            yieldReturn;
            bool              hasNext;
            Exception         exception         = null;
            COROUTINE         waitForCoroutine  = null;
            CancellationToken cancellationToken = GetCancelToken(coroutine);

            while (true)
            {
                if (!coroutine.IsDone)
                {
                    waitForCoroutine = GetWaitForCoroutine(coroutine);
                    if (waitForCoroutine != null)
                    {
                        //wait done
                        while (!waitForCoroutine.IsDone && !coroutine.IsDone)
                        {
                            if (cancellationToken != null && cancellationToken.IsCancellationRequested)
                            {
                                SetCoroutineCanceled(coroutine);
                                break;
                            }
                            yield return(null);
                        }
                        SetWaitForCoroutine(coroutine, null);

                        var ex = waitForCoroutine.Exception;
                        if (!coroutine.IsDone)
                        {
                            if (ex != null)
                            {
                                ICatchable catchable = waitForCoroutine as ICatchable;
                                if (catchable != null)
                                {
                                    try
                                    {
                                        catchable.HandleException(ex);
                                    }
                                    catch (Exception ex2)
                                    {
                                        var newEx = new CoroutineAggregateException(ex2);
                                        newEx = newEx.Flatten();
                                        SetCoroutineException(coroutine, newEx, true);
                                        break;
                                    }
                                }
                                else
                                {
                                    SetCoroutineException(coroutine, ex, false);
                                    break;
                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        hasNext = false;


                        if (cancellationToken != null && cancellationToken.IsCancellationRequested)
                        {
                            SetCoroutineCanceled(coroutine);
                            break;
                        }

                        lock (lockObj)
                        {
                            PushCurrent();

                            try
                            {
                                hasNext = routine.MoveNext();
                                if (!hasNext)
                                {
                                    CheckReturnValue(coroutine);
                                }
                            }
                            catch (Exception ex)
                            {
                                exception = ex;
                            }
                            finally
                            {
                                PopCurrent();
                            }
                        }

                        if (exception != null)
                        {
                            var aggEx = new CoroutineAggregateException(exception);
                            aggEx = aggEx.Flatten();
                            SetCoroutineException(coroutine, aggEx, true);
                            break;
                        }

                        if (!hasNext)
                        {
                            break;
                        }

                        yieldReturn = routine.Current;

                        //if (yieldReturn != null)
                        //{
                        //    IEnumerator convertRoutine;
                        //    if (ConvertToRoutine(yieldReturn, out convertRoutine))
                        //        yieldReturn = convertRoutine;
                        //}

                        if (yieldReturn != null)
                        {
                            if (yieldReturn is IYield)
                            {
                                if (yieldReturn is COROUTINE)
                                {
                                    waitForCoroutine = (COROUTINE)yieldReturn;
                                    SetWaitForCoroutine(coroutine, waitForCoroutine);
                                }
                                else if (yieldReturn is WaitForMilliseconds)
                                {
                                    float atTime = (float)(Time + ((WaitForMilliseconds)yieldReturn).Milliseconds * 0.001f);
                                    while (Time < atTime)
                                    {
                                        if (cancellationToken != null && cancellationToken.IsCancellationRequested)
                                        {
                                            SetCoroutineCanceled(coroutine);
                                            break;
                                        }
                                        yield return(null);
                                    }
                                }
                                else if (yieldReturn is WaitForFrame)
                                {
                                    int frameCount = ((WaitForFrame)yieldReturn).FrameCount;
                                    if (frameCount <= 0)
                                    {
                                        yield return(null);
                                    }
                                    else
                                    {
                                        for (int i = 0; i < frameCount; i++)
                                        {
                                            if (cancellationToken != null && cancellationToken.IsCancellationRequested)
                                            {
                                                SetCoroutineCanceled(coroutine);
                                                break;
                                            }
                                            yield return(null);
                                        }
                                    }
                                }
                                else if (yieldReturn is YieldReturn)
                                {
                                    YieldReturn ret = (YieldReturn)yieldReturn;
                                    SetCoroutineReturnValue(coroutine, ret);
                                }
                                else if (yieldReturn is CustomYield)
                                {
                                    CustomYield customYield = (CustomYield)yieldReturn;
                                    SetWaitForCoroutine(coroutine, QueueRoutine(customYield));
                                }
                                else
                                {
                                    throw new CoroutineUnknownYieldTypeException(yieldReturn.GetType());
                                }
                            }
                            else if (yieldReturn is IEnumerable)
                            {
                                SetWaitForCoroutine(coroutine, QueueRoutine(((IEnumerable)yieldReturn).GetEnumerator()));
                            }
                            else if (yieldReturn is IEnumerator)
                            {
                                SetWaitForCoroutine(coroutine, QueueRoutine((IEnumerator)yieldReturn));
                            }
                            else
                            {
                                IEnumerator tmp;
                                if (ConvertToRoutine(yieldReturn, out tmp))
                                {
                                    SetWaitForCoroutine(coroutine, QueueRoutine(tmp));
                                }
                                else
                                {
                                    // ignore handle
                                    yield return(yieldReturn);
                                }
                            }
                        }
                        else
                        {
                            yield return(null);
                        }
                    }
                }


                if (coroutine.IsDone)
                {
                    break;
                }
            }

            if (!coroutine.IsDone)
            {
                SetCoroutineDone(coroutine);
            }
            else
            {
                if (!coroutine.IsRanToCompletion)
                {
                    exception = coroutine.Exception;
                    if (exception != null && !IsCoroutineHandleException(coroutine))
                    {
                        if (!IsReady(coroutine))
                        {
                            yield return(null);
                        }
                        if (!IsCoroutineHandleException(coroutine))
                        {
                            throw exception;
                        }
                    }
                }
            }
        }