コード例 #1
0
        public ZilResult ApplyNoEval(Context ctx, ZilObject[] args)
        {
            try
            {
                switch (args.Length)
                {
                case 1:
                    return(Subrs.NTH(ctx, (IStructure)args[0], value));

                case 2:
                    return(Subrs.PUT(ctx, (IStructure)args[0], value, args[1]));

                default:
                    throw new InterpreterError(
                              InterpreterMessages._0_Expected_1_After_2,
                              InterpreterMessages.NoFunction,
                              "1 or 2 args",
                              "the FIX");
                }
            }
            catch (InvalidCastException)
            {
                throw new InterpreterError(
                          InterpreterMessages._0_Expected_1_After_2,
                          InterpreterMessages.NoFunction,
                          "a structured value",
                          "the FIX");
            }
        }
コード例 #2
0
        internal IOperand CompileIFFLAG([NotNull] IRoutineBuilder rb, [NotNull] ZilListoidBase clauses, [NotNull] ISourceLine src,
                                        bool wantResult, [CanBeNull] IVariable resultStorage)
        {
            resultStorage = resultStorage ?? rb.Stack;

            while (!clauses.IsEmpty)
            {
                ZilObject clause;

                (clause, clauses) = clauses;

                if (!(clause is ZilListoidBase list) || list.IsEmpty)
                {
                    throw new CompilerError(CompilerMessages.All_Clauses_In_0_Must_Be_Lists, "IFFLAG");
                }

                var(flag, body) = list;

                ZilObject value;
                bool      match, isElse = false;
                ZilAtom   shadyElseAtom = null;

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

                    break;

                case ZilForm form:
                    form  = Subrs.SubstituteIfflagForm(Context, form);
                    match = ((ZilObject)form.Eval(Context)).IsTrue;
                    break;

                case ZilAtom atom when atom.StdAtom != StdAtom.ELSE && atom.StdAtom != StdAtom.T:
                    shadyElseAtom = atom;
                    goto default;

                default:
                    match = isElse = true;
                    break;
                }

                // does this clause match?
                if (!match)
                {
                    continue;
                }

                // emit code for clause
                var clauseResult = CompileClauseBody(rb, body, wantResult, resultStorage);

                // warn if this is an else clause and there are more clauses below
                if (!isElse || clauses.IsEmpty)
                {
                    return(wantResult ? clauseResult : null);
                }

                var warning = new CompilerError(src, CompilerMessages._0_Clauses_After_Else_Part_Will_Never_Be_Evaluated, "IFFLAG");

                if (shadyElseAtom != null)
                {
                    // if the else clause wasn't introduced with ELSE or T, it might not have been meant as an else clause
                    warning = warning.Combine(new CompilerError(
                                                  flag.SourceLine,
                                                  CompilerMessages.Undeclared_Compilation_Flag_0,
                                                  shadyElseAtom));
                }
                Context.HandleError(warning);

                return(wantResult ? clauseResult : null);
            }

            // no matching clauses
            if (wantResult)
            {
                rb.EmitStore(resultStorage, Game.Zero);
            }

            return(wantResult ? resultStorage : null);
        }