示例#1
0
        public static ZilResult COND(Context ctx, [NotNull][Required] CondClause[] clauses)
        {
            ZilResult result = null;

            foreach (var clause in clauses)
            {
                result = clause.Condition.Eval(ctx);
                if (result.ShouldPass())
                {
                    break;
                }

                if (((ZilObject)result).IsTrue)
                {
                    foreach (var inner in clause.Body)
                    {
                        result = inner.Eval(ctx);
                        if (result.ShouldPass())
                        {
                            break;
                        }
                    }

                    break;
                }
            }

            return(result);
        }
示例#2
0
        public static ZilResult IFFLAG([NotNull] Context ctx, [NotNull][Required] CondClause[] args)
        {
            foreach (var clause in args)
            {
                bool      match;
                ZilObject value;

                switch (clause.Condition)
                {
                case ZilAtom atom when(value  = ctx.GetCompilationFlagValue(atom)) != null:
                case ZilString str when(value = ctx.GetCompilationFlagValue(str.Text)) != null:
                    // name of a defined compilation flag
                    match = value.IsTrue;

                    break;

                case ZilForm form:
                    form = SubstituteIfflagForm(ctx, form);
                    var zr = form.Eval(ctx);
                    if (zr.ShouldPass())
                    {
                        return(zr);
                    }
                    match = ((ZilObject)zr).IsTrue;
                    break;

                default:
                    match = true;
                    break;
                }

                if (!match)
                {
                    continue;
                }

                ZilResult result = clause.Condition;

                foreach (var expr in clause.Body)
                {
                    result = expr.Eval(ctx);
                    if (result.ShouldPass())
                    {
                        break;
                    }
                }

                return(result);
            }

            // no match
            return(ctx.FALSE);
        }
示例#3
0
        public static ZilResult AGAIN(Context ctx, ZilActivation activation = null)
        {
            if (activation == null)
            {
                activation = ctx.GetEnclosingProgActivation();
                if (activation == null)
                {
                    throw new InterpreterError(InterpreterMessages._0_No_Enclosing_PROGREPEAT, "AGAIN");
                }
            }

            return(ZilResult.Again(activation));
        }
示例#4
0
        public bool ShouldPass([CanBeNull] ZilActivation currentActivation, ref ZilResult resultToPass)
        {
            switch (outcome)
            {
            case Outcome.Value:
                return(false);

            case Outcome.Return when currentActivation != null && activation == currentActivation:
                resultToPass = value;
                return(true);

            default:
                resultToPass = this;
                return(true);
            }
        }
示例#5
0
        public static ZilResult RETURN(Context ctx, ZilObject value = null, ZilActivation activation = null)
        {
            if (value == null)
            {
                value = ctx.TRUE;
            }

            if (activation == null)
            {
                activation = ctx.GetEnclosingProgActivation();
                if (activation == null)
                {
                    throw new InterpreterError(InterpreterMessages._0_No_Enclosing_PROGREPEAT, "RETURN");
                }
            }

            return(ZilResult.Return(activation, value));
        }
示例#6
0
        public static bool TryToZilObjectArray([NotNull] this IEnumerable <ZilResult> inputs, [CanBeNull] out ZilObject[] array, out ZilResult result)
        {
            List <ZilObject> list;

            if (inputs is ICollection <ZilResult> coll)
            {
                list = new List <ZilObject>(coll.Count);
            }
            else
            {
                list = new List <ZilObject>();
            }

            foreach (var zr in inputs)
            {
                if (zr.ShouldPass())
                {
                    array  = null;
                    result = zr;
                    return(false);
                }

                list.Add((ZilObject)zr);
            }

            array  = list.ToArray();
            result = default;
            return(true);
        }
示例#7
0
        public bool ShouldPass()
        {
            ZilResult dummy = default;

            return(ShouldPass(null, ref dummy));
        }
示例#8
0
 public static ZilResult MAPLEAVE(Context ctx, [CanBeNull] ZilObject value = null)
 {
     return(ZilResult.MapLeave(value ?? ctx.TRUE));
 }
示例#9
0
 public static ZilResult MAPSTOP(Context ctx, [NotNull] ZilObject[] args)
 {
     return(ZilResult.MapStop(args));
 }
示例#10
0
 public static ZilResult MAPRET(Context ctx, [NotNull] ZilObject[] args)
 {
     return(ZilResult.MapRet(args));
 }
示例#11
0
 public SortAbortedException(ZilResult zilResult)
 {
     ZilResult = zilResult;
 }
示例#12
0
        static ZilResult PerformProg([NotNull][ProvidesContext] Context ctx, [CanBeNull] ZilAtom activationAtom,
                                     BindingParams.BindingList bindings, [CanBeNull] ZilDecl bodyDecl, [ItemNotNull][NotNull] ZilObject[] body,
                                     [NotNull] string name, bool repeat, bool catchy)
        {
            using (var activation = new ZilActivation(ctx.GetStdAtom(StdAtom.PROG)))
            {
                using (var innerEnv = ctx.PushEnvironment())
                {
                    if (activationAtom != null)
                    {
                        innerEnv.Rebind(activationAtom, activation);
                    }

                    var bodyAtomDecls = bodyDecl?.GetAtomDeclPairs().ToLookup(p => p.Key, p => p.Value);

                    foreach (var b in bindings.Bindings)
                    {
                        var atom        = b.Atom;
                        var initializer = b.Initializer;

                        ZilObject value;

                        if (initializer != null)
                        {
                            var initResult = initializer.Eval(ctx);
                            if (initResult.ShouldPass(activation, ref initResult))
                            {
                                return(initResult);
                            }
                            value = (ZilObject)initResult;
                        }
                        else
                        {
                            value = null;
                        }

                        var previousDecl  = b.Decl;
                        var firstBodyDecl = bodyAtomDecls?[atom].FirstOrDefault();
                        if (firstBodyDecl != null && (previousDecl != null || bodyAtomDecls[atom].Skip(1).Any()))
                        {
                            throw new InterpreterError(InterpreterMessages._0_Conflicting_DECLs_For_Atom_1, name, atom);
                        }

                        var decl = previousDecl ?? firstBodyDecl;

                        if (value != null)
                        {
                            ctx.MaybeCheckDecl(initializer, value, decl, "LVAL of {0}", atom);
                        }

                        innerEnv.Rebind(atom, value, decl);
                    }

                    if (catchy)
                    {
                        innerEnv.Rebind(ctx.EnclosingProgActivationAtom, activation);
                    }

                    // evaluate body
                    ZilResult result = null;
                    bool      again;
                    do
                    {
                        again = false;
                        foreach (var expr in body)
                        {
                            result = expr.Eval(ctx);

                            if (result.IsAgain(activation))
                            {
                                again = true;
                            }
                            else if (result.ShouldPass(activation, ref result))
                            {
                                return(result);
                            }
                        }
                    } while (repeat || again);

                    return(result);
                }
            }
        }