示例#1
0
        /// <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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
		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;
		}
示例#5
0
		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;
		}
示例#6
0
		/// <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;
		}