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)); }
private void AddExtraTrivia(ITexlSource trivia) { if (_extraTrivia == null) { _extraTrivia = trivia; } else { _extraTrivia = new SpreadSource(_extraTrivia, trivia); } }
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)); }
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)); }
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)); }
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)); } }
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)); }
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))); }
// 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)); }
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)); }