コード例 #1
0
        public static bool Matches <T1>([NotNull] this IStructure structure, [CanBeNull] out T1 obj1)
            where T1 : ZilObject
        {
            if (structure.HasLength(1) && structure.GetFirst() is T1 elem1)
            {
                obj1 = elem1;
                return(true);
            }

            obj1 = default;
            return(false);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }