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"); } }
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); }