예제 #1
0
파일: Collection.cs 프로젝트: Seti-0/NSprak
        public static List <CollectedIndex> Indices(MatchIterator iterator)
        {
            List <CollectedIndex> indices = new List <CollectedIndex>();

            iterator.AssertNext();

            while (iterator.HasNext)
            {
                iterator.AssertKeySymbol(Symbols.OpenSquareBracket, out Token open);
                iterator.AssertExpression(out Expression index);
                iterator.AssertKeySymbol(Symbols.CloseSquareBracket, out Token close);

                CollectedIndex entry = new CollectedIndex
                {
                    Open  = open,
                    Index = index,
                    Close = close
                };

                indices.Add(entry);
            }

            return(indices);
        }
예제 #2
0
        public static Expression Create(MatchIterator iterator)
        {
            LinkedList <object> items = new LinkedList <object>();

            iterator.AssertNext();

            // postfix unary operators are not supported here
            // (Like i--, etc)
            // I don't think they are really needed for sprak, and defaulting
            // to assuming prefix simplifies things.

            while (true)
            {
                items.AddLast(GetValue(iterator));

                if (iterator.AtEnd())
                {
                    break;
                }

                iterator.AssertTokenType(TokenType.Operator, out Token op);
                items.AddLast(op);

                if (iterator.AtEnd())
                {
                    break;
                }
            }

            void ParseOperatorToken(LinkedListNode <object> opNode)
            {
                Token token = (Token)opNode.Value;
                LinkedListNode <object> leftNode  = opNode.Previous;
                LinkedListNode <object> rightNode = opNode.Next;

                Expression   left   = (Expression)leftNode.Value;
                Expression   right  = (Expression)rightNode?.Value;
                OperatorCall result = new OperatorCall(token, left, right);

                items.AddBefore(leftNode, result);

                items.Remove(leftNode);
                items.Remove(opNode);

                if (rightNode != null)
                {
                    items.Remove(rightNode);
                }
            }

            LinkedListNode <object> current, next;

            foreach (Operator[] group in Operator.OperatorPrecedenceGroups)
            {
                current = items.First.Next;

                while (current != null)
                {
                    next = current.Next?.Next;

                    Token token = (Token)current.Value;
                    if (Operator.TryParse(out Operator op, text:token.Content))
                    {
                        if (group.Contains(op))
                        {
                            ParseOperatorToken(current);
                        }
                    }

                    current = next;
                }
            }

            current = items.First.Next;
            while (current != null)
            {
                ParseOperatorToken(current);
                current = current.Next?.Next;
            }

            if (items.First.Next != null)
            {
                throw new Exception("Unable to parse all operators");
            }

            return((Expression)items.First.Value);
        }