static bool CaptureGroup(ref int c, ref int p, RVList <LNode> cArgs, RVList <LNode> pArgs, ref MMap <Symbol, LNode> captures, ref RVList <LNode> attrs) { Debug.Assert(IsParamsCapture(pArgs[p])); // The goal now is to find a sequence of nodes in cArgs that matches // the sequence pArgs[p+1 .. p+x] where x is the maximum value such // that none of the nodes in the sequence are $(params caps). int saved_p = p, saved_c = c; var savedCaptures = captures.AsImmutable(); var savedAttrs = attrs; int captureSize = 0; for (;; captureSize++) { for (p++, c += captureSize; ; c++, p++) { // If we run out of pArgs, great, we're done; if we run out // of cArgs, the match fails, unless all remaining pArgs are // $(params caps). if (p >= pArgs.Count || IsParamsCapture(pArgs[p])) { goto done_group; } else { if (c >= cArgs.Count) { return(false); } if (!MatchesPatternNested(cArgs[c], pArgs[p], ref captures, ref attrs)) { goto continue_group; } } } continue_group :; p = saved_p; c = saved_c; attrs = savedAttrs; captures = savedCaptures.AsMutable(); } done_group: AddCapture(captures, pArgs[saved_p], cArgs.Slice(saved_c, captureSize)); return(true); }
static RVList <Pair <RVList <LNode>, LNode> > GetCases(RVList <LNode> body, IMessageSink sink) { var pairs = RVList <Pair <RVList <LNode>, LNode> > .Empty; for (int i = 0; i < body.Count; i++) { bool isDefault; if (body[i].Calls(S.Lambda, 2)) { var key = new RVList <LNode>(body[i][0].WithoutOuterParens()); pairs.Add(Pair.Create(key, AutoStripBraces(body[i][1]))); } else if ((isDefault = IsDefaultLabel(body[i])) || body[i].CallsMin(S.Case, 1)) { var alts = isDefault ? RVList <LNode> .Empty : body[i].Args.SmartSelect(pat => AutoStripBraces(pat)); int bodyStart = ++i; for (; i < body.Count && !IsDefaultLabel(body[i]) && !body[i].CallsMin(S.Case, 1); i++) { } LNode handler; if (i == bodyStart + 1) { handler = body[bodyStart]; } else { handler = F.Braces(body.Slice(bodyStart, i - bodyStart)); } pairs.Add(Pair.Create(alts, handler)); i--; } else { Reject(sink, body[i], "expected 'case _:' or '_ => _'"); break; } } return(pairs); }
static bool CaptureGroup(ref int c, ref int p, RVList<LNode> cArgs, RVList<LNode> pArgs, ref MMap<Symbol, LNode> captures, ref RVList<LNode> attrs) { Debug.Assert(IsParamsCapture(pArgs[p])); // The goal now is to find a sequence of nodes in cArgs that matches // the sequence pArgs[p+1 .. p+x] where x is the maximum value such // that none of the nodes in the sequence are $(params caps). int saved_p = p, saved_c = c; var savedCaptures = captures.AsImmutable(); var savedAttrs = attrs; int captureSize = 0; for (;; captureSize++) { for (p++, c += captureSize; ; c++, p++) { // If we run out of pArgs, great, we're done; if we run out // of cArgs, the match fails, unless all remaining pArgs are // $(params caps). if (p >= pArgs.Count || IsParamsCapture(pArgs[p])) { goto done_group; } else { if (c >= cArgs.Count) return false; if (!MatchesPatternNested(cArgs[c], pArgs[p], ref captures, ref attrs)) goto continue_group; } } continue_group:; p = saved_p; c = saved_c; attrs = savedAttrs; captures = savedCaptures.AsMutable(); } done_group: AddCapture(captures, pArgs[saved_p], cArgs.Slice(saved_c, captureSize)); return true; }
static RVList<Pair<RVList<LNode>,LNode>> GetCases(RVList<LNode> body, IMessageSink sink) { var pairs = RVList<Pair<RVList<LNode>,LNode>>.Empty; for (int i = 0; i < body.Count; i++) { bool isDefault; if (body[i].Calls(S.Lambda, 2)) { var key = new RVList<LNode>(body[i][0].WithoutOuterParens()); pairs.Add(Pair.Create(key, AutoStripBraces(body[i][1]))); } else if ((isDefault = IsDefaultLabel(body[i])) || body[i].CallsMin(S.Case, 1)) { var alts = isDefault ? RVList<LNode>.Empty : body[i].Args.SmartSelect(pat => AutoStripBraces(pat)); int bodyStart = ++i; for (; i < body.Count && !IsDefaultLabel(body[i]) && !body[i].CallsMin(S.Case, 1); i++) { } LNode handler; if (i == bodyStart + 1) handler = body[bodyStart]; else handler = F.Braces(body.Slice(bodyStart, i - bodyStart)); pairs.Add(Pair.Create(alts, handler)); i--; } else { Reject(sink, body[i], "expected 'case _:' or '_ => _'"); break; } } return pairs; }