/// <summary>Given the contents of case statement like `matchCode` or /// `switch`, this method gets a list of the cases.</summary> /// <returns>The first item in each pair is a list of the cases associated /// with a single handler (for `default:`, the list is empty). The second /// item is the handler code.</returns> static internal VList <Pair <VList <LNode>, VList <LNode> > > GetCases(VList <LNode> body, IMessageSink sink) { var pairs = VList <Pair <VList <LNode>, VList <LNode> > > .Empty; for (int i = 0; i < body.Count; i++) { bool isDefault; if (body[i].Calls(S.Lambda, 2)) { var alts = body[i][0].WithoutOuterParens().AsList(S.Tuple).SmartSelect(AutoStripBraces); pairs.Add(Pair.Create(alts, body[i][1].AsList(S.Braces))); } else if ((isDefault = IsDefaultLabel(body[i])) || body[i].CallsMin(S.Case, 1)) { var alts = isDefault ? VList <LNode> .Empty : body[i].Args.SmartSelect(AutoStripBraces); int bodyStart = ++i; for (; i < body.Count && !IsDefaultLabel(body[i]) && !body[i].CallsMin(S.Case, 1); i++) { } var handler = new VList <LNode>(body.Slice(bodyStart, i - bodyStart)); pairs.Add(Pair.Create(alts, handler)); i--; // counteract i++ when loop repeats (redo) } else { Reject(sink, body[i], "expected 'case _:' or '_ => _'"); break; } } return(pairs); }
static bool CaptureGroup(ref int c, ref int p, VList <LNode> cArgs, VList <LNode> pArgs, ref MMap <Symbol, LNode> captures, ref VList <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 VList <Pair <VList <LNode>, LNode> > GetCases(VList <LNode> body, IMessageSink sink) { var pairs = VList <Pair <VList <LNode>, LNode> > .Empty; for (int i = 0; i < body.Count; i++) { bool isDefault; if (body[i].Calls(S.Lambda, 2)) { var key = new VList <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 ? VList <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, VList<LNode> cArgs, VList<LNode> pArgs, ref MMap<Symbol, LNode> captures, ref VList<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 VList<Pair<VList<LNode>,LNode>> GetCases(VList<LNode> body, IMessageSink sink) { var pairs = VList<Pair<VList<LNode>,LNode>>.Empty; for (int i = 0; i < body.Count; i++) { bool isDefault; if (body[i].Calls(S.Lambda, 2)) { var key = new VList<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 ? VList<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; }
/// <summary>Given the contents of case statement like `matchCode` or /// `switch`, this method gets a list of the cases.</summary> /// <returns>The first item in each pair is a list of the cases associated /// with a single handler (for `default:`, the list is empty). The second /// item is the handler code.</returns> static internal VList<Pair<VList<LNode>, VList<LNode>>> GetCases(VList<LNode> body, IMessageSink sink) { var pairs = VList<Pair<VList<LNode>, VList<LNode>>>.Empty; for (int i = 0; i < body.Count; i++) { bool isDefault; if (body[i].Calls(S.Lambda, 2)) { var alts = body[i][0].WithoutOuterParens().AsList(S.Tuple).SmartSelect(AutoStripBraces); pairs.Add(Pair.Create(alts, body[i][1].AsList(S.Braces))); } else if ((isDefault = IsDefaultLabel(body[i])) || body[i].CallsMin(S.Case, 1)) { var alts = isDefault ? VList<LNode>.Empty : body[i].Args.SmartSelect(AutoStripBraces); int bodyStart = ++i; for (; i < body.Count && !IsDefaultLabel(body[i]) && !body[i].CallsMin(S.Case, 1); i++) { } var handler = new VList<LNode>(body.Slice(bodyStart, i - bodyStart)); pairs.Add(Pair.Create(alts, handler)); i--; // counteract i++ when loop repeats (redo) } else { Reject(sink, body[i], "expected 'case _:' or '_ => _'"); break; } } return pairs; }