public static ZilObject REST(Context ctx, [NotNull] IStructure st, int skip = 1) { var result = (ZilObject)st.GetRest(skip); if (result == null) { throw new InterpreterError(InterpreterMessages._0_Not_Enough_Elements, "REST"); } return(result); }
static ZilObject PerformMember(Context ctx, [NotNull] ZilObject needle, [NotNull] IStructure haystack, [NotNull] Func <ZilObject, ZilObject, bool> equality) { while (haystack != null && !haystack.IsEmpty) { if (equality(needle, haystack.GetFirst())) { return((ZilObject)haystack); } haystack = haystack.GetRest(1); } return(ctx.FALSE); }
static bool CheckElements([NotNull] Context ctx, [NotNull] IStructure structure, [NotNull] ZilListoidBase elements, bool segment, bool ignoreErrors) { foreach (var subpattern in elements) { ZilObject first; if (subpattern is ZilVector vector) { var len = vector.GetLength(); if (len > 0 && vector[0] is ZilAtom atom) { int i; // ReSharper disable once SwitchStatementMissingSomeCases switch (atom.StdAtom) { case StdAtom.REST: i = 1; while (!structure.IsEmpty) { first = structure.GetFirst(); Debug.Assert(first != null); if (!Check(ctx, first, vector[i])) { return(false); } i++; if (i >= len) { i = 1; } structure = structure.GetRest(1); Debug.Assert(structure != null); } // !<FOO [REST A B C]> must repeat A B C a whole number of times // (ZILF extension) if (segment && i != 1) { return(false); } return(true); case StdAtom.OPT: case StdAtom.OPTIONAL: // greedily match OPT elements until the structure ends or a match fails for (i = 1; i < len; i++) { if (structure.IsEmpty) { break; } first = structure.GetFirst(); Debug.Assert(first != null); if (!Check(ctx, first, vector[i])) { break; } structure = structure.GetRest(1); Debug.Assert(structure != null); } // move on to the next subpattern, if any continue; } } else if (len > 0 && vector[0] is ZilFix fix) { var count = fix.Value; for (int i = 0; i < count; i++) { for (int j = 1; j < vector.GetLength(); j++) { if (structure.IsEmpty) { return(false); } first = structure.GetFirst(); Debug.Assert(first != null); if (!Check(ctx, first, vector[j])) { return(false); } structure = structure.GetRest(1); Debug.Assert(structure != null); } } // move on to the next subpattern, if any continue; } if (ignoreErrors) { return(false); } throw new InterpreterError( InterpreterMessages.Unrecognized_0_1, "vector in DECL pattern", vector.ToStringContext(ctx, false)); } if (structure.IsEmpty) { return(false); } first = structure.GetFirst(); Debug.Assert(first != null); if (!Check(ctx, first, subpattern)) { return(false); } structure = structure.GetRest(1); Debug.Assert(structure != null); } return(!segment || structure.IsEmpty); }