/// <summary> /// The main list matching logic. /// </summary> /// <returns>Returns whether the list match was successful. /// If the method returns true, it adds the capture groups (if any) to the match. /// If the method returns false, the match object remains in a partially-updated state and needs to be restored /// before it can be reused.</returns> internal static bool DoMatch(IReadOnlyList <ILInstruction> patterns, IReadOnlyList <ILInstruction> syntaxList, ref Match match) { ListMatch listMatch = new ListMatch(syntaxList); do { if (PerformMatchSequence(patterns, ref listMatch, ref match)) { // If we have a successful match and it matches the whole list, // we are done. if (listMatch.SyntaxIndex == syntaxList.Count) { return(true); } } // Otherwise, restore a savepoint created by PerformMatch() and resume the matching logic at that savepoint. } while (listMatch.RestoreSavePoint(ref match)); return(false); }
/// <summary> /// PerformMatch() for a sequence of patterns. /// </summary> /// <param name="patterns">List of patterns to match.</param> /// <param name="listMatch">Stores state about the current list match.</param> /// <param name="match">The match object, used to store global state during the match (such as the results of capture groups).</param> /// <returns>Returns whether all patterns were matched successfully against a part of the list. /// If the method returns true, it updates listMatch.SyntaxIndex to point to the next node that was not part of the match, /// and adds the capture groups (if any) to the match. /// If the method returns false, the listMatch and match objects remain in a partially-updated state and need to be restored /// before they can be reused.</returns> internal static bool PerformMatchSequence(IReadOnlyList <ILInstruction> patterns, ref ListMatch listMatch, ref Match match) { // The patterns may create savepoints, so we need to save the 'i' variable // as part of those checkpoints. for (int i = listMatch.PopFromSavePoint() ?? 0; i < patterns.Count; i++) { int startMarker = listMatch.GetSavePointStartMarker(); bool success = patterns[i].PerformMatch(ref listMatch, ref match); listMatch.PushToSavePoints(startMarker, i); if (!success) { return(false); } } return(true); }