Beispiel #1
0
        private TexlNode ParseBinary(TexlNode left, ITexlSource leftTrivia, BinaryOp op, Precedence precedence)
        {
            var opToken     = _curs.TokMove();
            var rightTrivia = ParseTrivia();
            var right       = ParseExpr(precedence);

            return(MakeBinary(op, left, leftTrivia, opToken, rightTrivia, right));
        }
Beispiel #2
0
 private void AddExtraTrivia(ITexlSource trivia)
 {
     if (_extraTrivia == null)
     {
         _extraTrivia = trivia;
     }
     else
     {
         _extraTrivia = new SpreadSource(_extraTrivia, trivia);
     }
 }
Beispiel #3
0
        public ITexlSource Clone(Dictionary <TexlNode, TexlNode> newNodes, Span newSpan)
        {
            Contracts.AssertValue(newNodes);
            Contracts.AssertAllValues(newNodes.Values);
            Contracts.AssertAllValues(newNodes.Keys);
            ITexlSource[] newItems = new ITexlSource[Sources.Count()];
            int           i        = 0;

            foreach (var source in Sources)
            {
                newItems[i] = source.Clone(newNodes, newSpan);
                i          += 1;;
            }
            return(new SpreadSource(newItems));
        }
Beispiel #4
0
 private TexlNode MakeBinary(BinaryOp op, TexlNode left, ITexlSource leftTrivia, Token opToken, ITexlSource rightTrivia, TexlNode right)
 {
     return(new BinaryOpNode(
                ref _idNext,
                opToken,
                new SourceList(
                    new NodeSource(left),
                    new SpreadSource(leftTrivia),
                    new TokenSource(opToken),
                    new SpreadSource(rightTrivia),
                    new NodeSource(right)),
                op,
                left,
                right));
 }
Beispiel #5
0
        public SourceList Clone(Span span, Dictionary <TexlNode, TexlNode> newNodes)
        {
            Contracts.AssertValue(newNodes);
            Contracts.AssertAllValues(newNodes.Values);
            Contracts.AssertAllValues(newNodes.Keys);
            ITexlSource[] newItems = new ITexlSource[Sources.Count()];
            int           i        = 0;

            foreach (var source in Sources)
            {
                newItems[i] = source.Clone(newNodes, span);
                i          += 1;
            }
            return(new SourceList(newItems));
        }
Beispiel #6
0
        private ITexlSource ParseTrivia(TokenCursor cursor = null)
        {
            cursor = cursor ?? _curs;
            var sources = new List <ITexlSource>();

            if (_extraTrivia != null)
            {
                sources.Add(_extraTrivia);
                _extraTrivia = null;
            }

            bool triviaFound;

            do
            {
                triviaFound = false;
                var tokens = cursor.SkipWhitespace();
                if (tokens.Any())
                {
                    sources.Add(new WhitespaceSource(tokens));
                    triviaFound = true;
                }
                if (cursor.TidCur == TokKind.Comment)
                {
                    var comment = cursor.TokMove().As <CommentToken>();
                    sources.Add(new TokenSource(comment));

                    if (comment.IsOpenBlock)
                    {
                        PostError(comment, TexlStrings.ErrMissingEndOfBlockComment);
                    }

                    _comments.Add(comment);
                    triviaFound = true;
                }
            } while (triviaFound);

            if (sources.Count() == 1)
            {
                return(sources.Single());
            }
            else
            {
                return(new SpreadSource(sources));
            }
        }
Beispiel #7
0
        private TexlNode ParseAs(TexlNode left, ITexlSource leftTrivia)
        {
            var opToken       = _curs.TokMove();
            var rightTrivia   = ParseTrivia();
            var rhsIdentifier = ParseIdentifier();

            return(new AsNode(
                       ref _idNext,
                       opToken,
                       new SourceList(
                           new NodeSource(left),
                           new SpreadSource(leftTrivia),
                           new TokenSource(opToken),
                           new SpreadSource(rightTrivia),
                           new IdentifierSource(rhsIdentifier)),
                       left,
                       rhsIdentifier));
        }
Beispiel #8
0
        private TexlNode ParseExprChain(TexlNode node, ITexlSource leftTrivia)
        {
            Contracts.AssertValue(node);
            Contracts.Assert(_curs.TidCur == TokKind.Semicolon);

            var delimiters  = new List <Token>(1);
            var expressions = new List <TexlNode>(2);

            expressions.Add(node);

            var sourceList = new List <ITexlSource>();

            sourceList.Add(new NodeSource(node));
            sourceList.Add(leftTrivia);

            while (_curs.TidCur == TokKind.Semicolon)
            {
                var delimiter = _curs.TokMove();
                delimiters.Add(delimiter);
                sourceList.Add(new TokenSource(delimiter));
                sourceList.Add(ParseTrivia());

                if (_curs.TidCur == TokKind.Eof || _curs.TidCur == TokKind.Comma || _curs.TidCur == TokKind.ParenClose)
                {
                    break;
                }

                // SingleExpr here means we don't want chains on the RHS, but individual expressions.
                var expression = ParseExpr(Precedence.SingleExpr);
                expressions.Add(expression);
                sourceList.Add(new NodeSource(expression));
                sourceList.Add(ParseTrivia());
            }

            return(new VariadicOpNode(
                       ref _idNext,
                       VariadicOp.Chain,
                       expressions.ToArray(),
                       delimiters.ToArray(),
                       new SourceList(sourceList)));
        }
Beispiel #9
0
        // Parse a record expression of the form: {id:expr, id:expr, ...}
        // or of the form ident@{id:expr, id:expr}
        private RecordNode ParseRecordExpr(ITexlSource sourceRestrictionTrivia, Identifier sourceRestriction = null)
        {
            Contracts.Assert(_curs.TidCur == TokKind.CurlyOpen || _curs.TidCur == TokKind.At);
            Contracts.AssertValueOrNull(sourceRestriction);

            Token curlyClose;

            var      commas                = new List <Token>();
            var      colons                = new List <Token>();
            var      ids                   = new List <Identifier>();
            var      exprs                 = new List <TexlNode>();
            var      sourceList            = new List <ITexlSource>();
            TexlNode sourceRestrictionNode = null;

            Token primaryToken = _curs.TokMove();

            if (primaryToken.Kind == TokKind.At)
            {
                Contracts.AssertValue(sourceRestriction);
                sourceList.Add(sourceRestrictionTrivia);
                sourceList.Add(new TokenSource(primaryToken));
                sourceList.Add(ParseTrivia());

                primaryToken          = sourceRestriction.Token;
                sourceRestrictionNode = new FirstNameNode(ref _idNext, sourceRestriction.Token, sourceRestriction);

                if (_curs.TidCur != TokKind.CurlyOpen)
                {
                    ErrorTid(_curs.TokCur, TokKind.CurlyOpen);
                    curlyClose = TokEat(TokKind.CurlyClose);
                    return(new RecordNode(
                               ref _idNext,
                               sourceRestriction.Token,
                               new SourceList(
                                   new SpreadSource(sourceList),
                                   curlyClose != null ? (ITexlSource) new TokenSource(curlyClose) : new SpreadSource()),
                               ids.ToArray(),
                               exprs.ToArray(),
                               null,
                               null,
                               curlyClose,
                               sourceRestrictionNode));
                }

                sourceList.Add(new TokenSource(_curs.TokMove()));
                sourceList.Add(ParseTrivia());
            }
            else
            {
                sourceList.Add(new TokenSource(primaryToken));
                sourceList.Add(ParseTrivia());
            }

            while (_curs.TidCur != TokKind.CurlyClose)
            {
                // id
                Identifier ident = ParseIdentifier();
                sourceList.Add(new IdentifierSource(ident));
                sourceList.Add(ParseTrivia());

                // :
                if (_curs.TidCur != TokKind.Colon)
                {
                    ErrorTid(_curs.TokCur, TokKind.Colon);
                    var      errorToken = _curs.TokMove();
                    TexlNode errorExp   = CreateError(errorToken, TexlStrings.ErrColonExpected);
                    sourceList.Add(new TokenSource(errorToken));
                    sourceList.Add(ParseTrivia());
                    ids.Add(ident);
                    exprs.Add(errorExp);
                    break;
                }
                var colon = _curs.TokMove();
                colons.Add(colon);
                sourceList.Add(new TokenSource(colon));
                sourceList.Add(ParseTrivia());

                // expr
                // SingleExpr here means we don't want chains, but individual expressions.
                TexlNode expr = ParseExpr(Precedence.SingleExpr);

                ids.Add(ident);
                exprs.Add(expr);
                sourceList.Add(new NodeSource(expr));
                sourceList.Add(ParseTrivia());

                // ,
                if (_curs.TidCur != TokKind.Comma)
                {
                    break;
                }

                var comma = _curs.TokMove();
                commas.Add(comma);
                sourceList.Add(new TokenSource(comma));
                sourceList.Add(ParseTrivia());

                if (_curs.TidCur == TokKind.CurlyClose)
                {
                    TexlNode errorExp = CreateError(comma, TexlStrings.ErrColonExpected);
                    exprs.Add(errorExp);
                    ids.Add(ParseIdentifier());
                }
            }

            Contracts.Assert(ids.Count == exprs.Count);

            Token[] commaArray = (commas != null) ? commas.ToArray() : null;
            Token[] colonArray = (colons != null) ? colons.ToArray() : null;

            curlyClose = TokEat(TokKind.CurlyClose);
            if (curlyClose != null)
            {
                sourceList.Add(new TokenSource(curlyClose));
            }

            return(new RecordNode(
                       ref _idNext,
                       primaryToken,
                       new SourceList(sourceList),
                       ids.ToArray(),
                       exprs.ToArray(),
                       commaArray,
                       colonArray,
                       curlyClose,
                       sourceRestrictionNode));
        }
Beispiel #10
0
        private CallNode ParseInvocation(Identifier head, ITexlSource headTrivia, TexlNode headNode)
        {
            Contracts.AssertValue(head);
            Contracts.AssertValueOrNull(headNode);
            Contracts.Assert(_curs.TidCur == TokKind.ParenOpen);

            Token leftParen  = _curs.TokMove();
            var   leftTrivia = ParseTrivia();

            if (_curs.TidCur == TokKind.ParenClose)
            {
                var rightParen = _curs.TokMove();
                var right      = new ListNode(
                    ref _idNext,
                    _curs.TokCur,
                    new TexlNode[0],
                    null,
                    new SourceList(
                        new TokenSource(leftParen),
                        leftTrivia,
                        new TokenSource(rightParen)));

                var sources = new List <ITexlSource>();
                if (headNode != null)
                {
                    sources.Add(new NodeSource(headNode));
                }
                else
                {
                    sources.Add(new IdentifierSource(head));
                }

                sources.Add(headTrivia);
                sources.Add(new NodeSource(right));

                return(new CallNode(
                           ref _idNext,
                           leftParen,
                           new SourceList(sources),
                           head,
                           headNode,
                           right,
                           rightParen));
            }

            var rgtokCommas = new List <Token>();
            var arguments   = new List <TexlNode>();
            var sourceList  = new List <ITexlSource>();

            sourceList.Add(new TokenSource(leftParen));
            sourceList.Add(leftTrivia);
            for (;;)
            {
                while (_curs.TidCur == TokKind.Comma)
                {
                    Token commaToken = _curs.TokMove();
                    arguments.Add(CreateError(commaToken, TexlStrings.ErrBadToken));
                    sourceList.Add(new TokenSource(commaToken));
                    sourceList.Add(ParseTrivia());
                    rgtokCommas.Add(commaToken);
                }

                var argument = ParseExpr(Precedence.None);
                arguments.Add(argument);
                sourceList.Add(new NodeSource(argument));
                sourceList.Add(ParseTrivia());

                if (_curs.TidCur != TokKind.Comma)
                {
                    break;
                }
                var comma = _curs.TokMove();
                rgtokCommas.Add(comma);
                sourceList.Add(new TokenSource(comma));
                sourceList.Add(ParseTrivia());
            }

            var parenClose = TokEat(TokKind.ParenClose);

            if (parenClose != null)
            {
                sourceList.Add(new TokenSource(parenClose));
            }

            var list = new ListNode(
                ref _idNext,
                leftParen,
                arguments.ToArray(),
                CollectionUtils.ToArray(rgtokCommas),
                new SourceList(sourceList));

            ITexlSource headNodeSource = new IdentifierSource(head);

            if (headNode != null)
            {
                headNodeSource = new NodeSource(headNode);
            }

            return(new CallNode(
                       ref _idNext,
                       leftParen,
                       new SourceList(
                           headNodeSource,
                           headTrivia,
                           new NodeSource(list)),
                       head,
                       headNode,
                       list,
                       parenClose));
        }