Ejemplo n.º 1
0
        static ZilResult PerformMap([NotNull] Context ctx, ZilObject finalf, IApplicable loopf, [NotNull] IStructure[] structs, bool first)
        {
            if (structs == null)
            {
                throw new ArgumentNullException(nameof(structs));
            }

            var finalf_app = finalf.AsApplicable(ctx);

            int numStructs = structs.Length;
            var loopArgs   = new ZilObject[numStructs];

            var  results = new List <ZilObject>();
            bool running = true;

            while (running)
            {
                // prepare loop args
                int i;
                for (i = 0; i < numStructs; i++)
                {
                    var st = structs[i];
                    if (st == null || st.IsEmpty)
                    {
                        break;
                    }

                    if (first)
                    {
                        loopArgs[i] = st.GetFirst();
                    }
                    else
                    {
                        loopArgs[i] = (ZilObject)st;
                    }

                    structs[i] = st.GetRest(1);
                }

                if (i < numStructs)
                {
                    break;
                }

                // apply loop function
                var result = loopf.ApplyNoEval(ctx, loopArgs);

                if (result.IsMapControl(out var outcome, out var value))
                {
                    switch (outcome)
                    {
                    case ZilResult.Outcome.MapStop:
                        // add values to results and exit loop
                        results.AddRange((IEnumerable <ZilObject>)value);
                        running = false;
                        continue;

                    case ZilResult.Outcome.MapRet:
                        // add values to results and continue
                        results.AddRange((IEnumerable <ZilObject>)value);
                        continue;

                    case ZilResult.Outcome.MapLeave:
                        // discard results, skip finalf, and return this value from the map
                        return(value);

                    default:
                        throw new UnhandledCaseException(outcome.ToString());
                    }
                }

                if (result.ShouldPass())
                {
                    return(result);
                }

                results.Add((ZilObject)result);
            }

            // apply final function
            if (finalf_app != null)
            {
                return(finalf_app.ApplyNoEval(ctx, results.ToArray()));
            }

            return(results.Count > 0 ? results[results.Count - 1] : ctx.FALSE);
        }
Ejemplo n.º 2
0
 public static ZilResult APPLY([NotNull] Context ctx, [NotNull] IApplicable ap, [NotNull] ZilObject[] args)
 {
     return(ap.ApplyNoEval(ctx, args));
 }