Ejemplo n.º 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 <LNodeList, LNodeList> > GetCases(LNodeList body, IMessageSink sink)
        {
            var pairs = VList <Pair <LNodeList, LNodeList> > .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(UnwrapBraces);
                    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 ? LNodeList.Empty : body[i].Args.SmartSelect(UnwrapBraces);
                    int bodyStart = ++i;
                    for (; i < body.Count && !IsDefaultLabel(body[i]) && !body[i].CallsMin(S.Case, 1); i++)
                    {
                    }
                    var handler = new LNodeList(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);
        }