Пример #1
0
		/// <summary>Converts a list of LNodes to a single LNode by using the list 
		/// as the argument list in a call to the specified identifier, or, if the 
		/// list contains a single item, by returning that single item.</summary>
		/// <param name="listIdentifier">Target of the node that is created if <c>list</c>
		/// does not contain exactly one item. Typical values include "{}" and "#splice".</param>
		/// <remarks>This is the reverse of the operation performed by <see cref="AsList(LNode,Symbol)"/>.</remarks>
		public static LNode AsLNode(this RVList<LNode> list, Symbol listIdentifier)
		{
			if (list.Count == 1)
				return list[0];
			else {
				var r = SourceRange.Nowhere;
				if (list.Count != 0) {
					r = list[0].Range;
					r = new SourceRange(r.Source, r.StartIndex, list.Last.Range.EndIndex - r.StartIndex);
				}
 				return LNode.Call(listIdentifier, list, r);
			}
		}
Пример #2
0
        private Maybe <Trivia> CurrentTrivia(out SourceRange range)
        {
            var trivia = SortedTrivia.TryGet(NextIndex);

            if (trivia.HasValue)
            {
                range = GetRange(trivia.Value);
            }
            else
            {
                range = default(SourceRange);
            }
            return(trivia);
        }
Пример #3
0
 /// <summary>Converts a list of LNodes to a single LNode by using the list
 /// as the argument list in a call to the specified identifier, or, if the
 /// list contains a single item, by returning that single item.</summary>
 /// <param name="listIdentifier">Target of the node that is created if <c>list</c>
 /// does not contain exactly one item. Typical values include "{}" and "#splice".</param>
 /// <remarks>This is the reverse of the operation performed by <see cref="AsList(LNode,Symbol)"/>.</remarks>
 public static LNode AsLNode(this RVList <LNode> list, Symbol listIdentifier)
 {
     if (list.Count == 1)
     {
         return(list[0]);
     }
     else
     {
         var r = SourceRange.Nowhere;
         if (list.Count != 0)
         {
             r = list[0].Range;
             r = new SourceRange(r.Source, r.StartIndex, list.Last.Range.EndIndex - r.StartIndex);
         }
         return(LNode.Call(listIdentifier, list, r));
     }
 }
Пример #4
0
        /// <summary>Called to transform a trivia token into a trivia attribute.</summary>
        /// <remarks>If a trivia token is not recognized, null is returned to ignore the trivia.</remarks>
        protected virtual LNode MakeTriviaAttribute(Token t)
        {
            if (t.TypeInt == NewlineTypeInt)
            {
                return(_trivia_newline);
            }
            else
            {
                Symbol  commentType = null;
                UString text;
                if (t.Value == null || t.Value == WhitespaceTag.Value)
                {
                    text = SourceFile.Text.Slice(t.StartIndex, t.Length);
                }
                else
                {
                    text = t.Value is UString ? ((UString)t.Value) : t.Value.ToString();
                }

                if (MLCommentPrefix != null && text.StartsWith(MLCommentPrefix))
                {
                    commentType = S.TriviaMLComment;
                    text        = text.Substring(MLCommentPrefix.Length);
                    if (text.EndsWith(MLCommentSuffix))
                    {
                        text = text.Left(text.Length - MLCommentSuffix.Length);
                    }
                }
                else if (SLCommentPrefix != null && text.StartsWith(SLCommentPrefix))
                {
                    commentType = S.TriviaSLComment;
                    text        = text.Substring(SLCommentPrefix.Length);
                    if (SLCommentSuffix != null && text.EndsWith(SLCommentSuffix))
                    {
                        text = text.Left(text.Length - SLCommentSuffix.Length);
                    }
                }
                if (commentType == null)
                {
                    return(null);
                }
                return(LNode.Trivia(commentType, text.ToString(), SourceRange.New(SourceFile, t)));
            }
        }
Пример #5
0
 public StdSimpleCallNodeWithAttrs(RVList <LNode> attrs, Symbol name, RVList <LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(name, args, range, style)
 {
     _attrs = attrs; NoNulls(attrs, "Attrs");
 }
Пример #6
0
 public StdSimpleCallNode(Symbol name, RVList <LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(args, range, style)
 {
     _name = name ?? GSymbol.Empty; DetectTargetRange();
 }
Пример #7
0
 public StdLiteralNodeWithAttrs(RVList <LNode> attrs, object value, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(value, range, style)
 {
     _attrs = attrs; NoNulls(attrs, "Attrs");
 }
Пример #8
0
 public StdTriviaNode(Symbol name, object value, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(range, style)
 {
     _name = name ?? GSymbol.Empty; _tokenValue = value;
 }
Пример #9
0
 private Maybe <Trivia> AdvanceTrivia(out SourceRange range)
 {
     ++NextIndex;
     return(CurrentTrivia(out range));
 }
Пример #10
0
        private void InjectTriviaInChildren(LNode parent, out SourceRange triviaRange, out Maybe <Trivia> trivia, int indexInParent, ref LNode node)
        {
            // Current trivia's range is within node's range: Apply it to
            // the node's children, if any. First gather list of children
            // and sort by source-code order, if necessary:
            int min = node.Min;
            InternalList <Pair <LNode, int> > children = InternalList <Pair <LNode, int> > .Empty;

            children.Resize(node.Max - min + 1);
            bool inOrder = true;
            int  start, prevStart = int.MinValue;

            for (int i = 0; i < children.Count; i++, prevStart = start)
            {
                children[i] = Pair.Create(node[i + min], i + min);
                start       = children[i].A.Range.StartIndex;
                if (prevStart > start)
                {
                    inOrder = false;
                }
            }
            if (!inOrder)
            {
                children.Sort((a, b) => a.Item1.Range.StartIndex.CompareTo(b.Item1.Range.StartIndex));
            }

            // Call ourself recursively to apply trivia to children. Usually,
            // newChildren is the same length as children, but it may have extra
            // trivia attributes added.
            InternalList <Pair <LNode, int> > newChildren = new InternalList <Pair <LNode, int> >(children.Count);
            var  output  = RunCore(children.GetEnumerator(), node);
            bool changed = false;

            while (output.MoveNext())
            {
                var @new = output.Current;
                newChildren.Add(@new);
                if (@new.Item1 != children[@new.Item2 - min].Item1)
                {
                    changed = true;
                }
            }

            // At the end, gather up any remaining trivia
            InternalList <Trivia> triviaList = InternalList <Trivia> .Empty;

            trivia = CurrentTrivia(out triviaRange);
            while (trivia.HasValue && triviaRange.EndIndex <= node.Range.EndIndex)
            {
                triviaList.Add(trivia.Value);
                trivia  = AdvanceTrivia(out triviaRange);
                changed = true;
            }

            if (changed)
            {
                // If this is a call, attach any remaining trivia to the last child.
                if (node.IsCall && !triviaList.IsEmpty)
                {
                    int i    = newChildren.Count - 1;
                    var last = newChildren.InternalArray[i];
                    newChildren.InternalArray[i].A = AttachTriviaTo(last.A, triviaList, TriviaLocation.TrailingExtra, node, last.B) ?? last.A;
                }

                // Put the children back in their "conceptual" order
                if (!inOrder)
                {
                    newChildren.StableSort((a, b) => a.Item2.CompareTo(b.Item2));
                }

                // Update node's attributes, if any
                int numAttrs = newChildren.TakeWhile(p => p.B < -1).Count();
                if (numAttrs > 0)
                {
                    var attrs = LNode.List(newChildren.Slice(0, numAttrs).SelectArray(p => p.A));
                    node = node.WithAttrs(attrs);
                }

                if (node.IsCall)
                {
                    Debug.Assert(newChildren[numAttrs].B == -1);
                    var newArgs = newChildren.Slice(numAttrs + 1).SelectArray(p => p.A);
                    node = node.With(newChildren[numAttrs].A, LNode.List(newArgs));
                }
                else if (!triviaList.IsEmpty)
                {
                    // If current node is not a call, attach any remaining trivia to it.
                    node = AttachTriviaTo(node, triviaList, TriviaLocation.Ambiguous, parent, indexInParent);
                }
            }
        }
Пример #11
0
 public bool Contains(SourceRange inner)
 {
     return Source == inner.Source && StartIndex <= inner.StartIndex && EndIndex >= inner.EndIndex;
 }
Пример #12
0
		public StdSimpleCallNodeWithAttrs(RVList<LNode> attrs, Symbol name, RVList<LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default) 
			: base(name, args, range, style) { _attrs = attrs; NoNulls(attrs, "Attrs"); }
Пример #13
0
		public StdLiteralNodeWithAttrs(VList<LNode> attrs, object value, SourceRange range, NodeStyle style = NodeStyle.Default) 
			: base(value, range, style) { _attrs = attrs; NoNulls(attrs, "Attrs"); }
Пример #14
0
		public StdLiteralNode(object value, SourceRange range, NodeStyle style = NodeStyle.Default) 
			: base(range, style) { _value = value; }
Пример #15
0
 public StdTriviaNode(Symbol name, object value, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(name, range, style)
 {
     _value = value;
 }
Пример #16
0
        private void InjectTriviaInChildren(LNode parent, out SourceRange triviaRange, out Maybe <Trivia> trivia, int indexInParent, ref LNode node)
        {
            // Current trivia's range is within node's range: Apply it to
            // the node's children, if any. First gather list of children
            // and sort by source-code order, if necessary:
            int min = node.Min;
            InternalList <Pair <LNode, int> > children = InternalList <Pair <LNode, int> > .Empty;

            children.Resize(node.Max - min + 1);
            bool inOrder = true;
            int  start, prevStart = int.MinValue;

            for (int i = 0; i < children.Count; i++, prevStart = start)
            {
                children[i] = Pair.Create(node[i + min], i + min);
                start       = children[i].A.Range.StartIndex;
                if (prevStart > start)
                {
                    inOrder = false;
                }
            }
            if (!inOrder)
            {
                children.Sort((a, b) => a.Item1.Range.StartIndex.CompareTo(b.Item1.Range.StartIndex));
            }

            // Call ourself recursively to apply trivia to children. Usually,
            // newChildren is the same length as children, but it may have extra
            // trivia attributes added.
            InternalList <Pair <LNode, int> > newChildren = new InternalList <Pair <LNode, int> >(children.Count);
            var  output  = RunCore(children.GetEnumerator(), node);
            bool changed = false;

            while (output.MoveNext())
            {
                var @new = output.Current;
                newChildren.Add(@new);
                if (@new.Item1 != children[@new.Item2 - min].Item1)
                {
                    changed = true;
                }
            }

            // At the end, gather up any remaining trivia in the node's range that wasn't
            // associated with a child.
            //
            // A newline is treated specially here, because sometimes (e.g. in LES3 token
            // lists) a newline can be reified into its own node but also exist in the trivia
            // list. In this case, node will be something like `'\n` when triviaRange equals
            // node.Range. So let's say the node stream is something like Ann, `'\n`, Bob. If
            // we attach the newline to the `'\n` node as usual (using the
            // TriviaLocation.Ambiguous attachment mode, since the newline is neither leading
            // nor trailing), the output node list will be something rather complicated:
            //   Ann, @`%appendStatement` @(`%trailing`(`%newline`)) `'\n`, @`%appendStatement` Bob
            // If we ignore the newline temporarily so that it gets treated as leading trivia
            // of Bob instead, we get simpler output:
            //   Ann, @`%appendStatement` `'\n`, Bob
            InternalList <Trivia> triviaList = InternalList <Trivia> .Empty;

            trivia = CurrentTrivia(out triviaRange);
            while (trivia.HasValue && triviaRange.EndIndex <= node.Range.EndIndex &&
                   !(IsNewline(trivia.Value) && triviaRange == node.Range))
            {
                triviaList.Add(trivia.Value);
                trivia  = AdvanceTrivia(out triviaRange);
                changed = true;
            }

            if (changed)
            {
                // If this is a call, attach any remaining trivia to the last child.
                if (node.IsCall && !triviaList.IsEmpty)
                {
                    int i    = newChildren.Count - 1;
                    var last = newChildren.InternalArray[i];
                    newChildren.InternalArray[i].A = AttachTriviaTo(last.A, triviaList, TriviaLocation.TrailingExtra, node, last.B) ?? last.A;
                }

                // Put the children back in their "conceptual" order
                if (!inOrder)
                {
                    newChildren.StableSort((a, b) => a.Item2.CompareTo(b.Item2));
                }

                // Update node's attributes, if any
                int numAttrs = newChildren.TakeWhile(p => p.B < -1).Count();
                if (numAttrs > 0)
                {
                    var attrs = LNode.List(newChildren.Slice(0, numAttrs).SelectArray(p => p.A));
                    node = node.WithAttrs(attrs);
                }

                if (node.IsCall)
                {
                    Debug.Assert(newChildren[numAttrs].B == -1);
                    var newArgs = newChildren.Slice(numAttrs + 1).SelectArray(p => p.A);
                    node = node.With(newChildren[numAttrs].A, LNode.List(newArgs));
                }
                else if (!triviaList.IsEmpty)
                {
                    // If current node is not a call, attach any remaining trivia to it.
                    node = AttachTriviaTo(node, triviaList, TriviaLocation.Ambiguous, parent, indexInParent);
                }
            }
        }
Пример #17
0
		public StdSimpleCallNode(Symbol name, VList<LNode> args, SourceRange range, int targetStart, int targetEnd, NodeStyle style = NodeStyle.Default) 
			: base(args, range, style)
		{
			_name = name ?? GSymbol.Empty;
			_targetOffs = ClipUShort(targetStart - RAS.StartIndex);
			_targetLen = ClipUShort(targetEnd - targetStart);
		}
Пример #18
0
 public StdComplexCallNode(LNode target, RVList <LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(args, range, style)
 {
     CheckParam.IsNotNull("target", target); _target = target;
 }
Пример #19
0
		public StdCallNode(VList<LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
			: base(range, style) { _args = args; NoNulls(args, "Args"); }
Пример #20
0
 /// <summary>Returns the same node with a parentheses attribute added.</summary>
 /// <remarks>The node's range is changed to the provided <see cref="SourceRange"/>.</remarks>
 public static LNode InParens(this LNode node, SourceRange range)
 {
     return(node.WithRange(range).PlusAttrBefore(LNode.Id(CodeSymbols.TriviaInParens)));
 }
Пример #21
0
		protected LiteralNode(SourceRange range, NodeStyle style) : base(range, style) { }
Пример #22
0
		public StdSimpleCallNode(Symbol name, VList<LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default) 
			: base(args, range, style) { _name = name ?? GSymbol.Empty; DetectTargetRange(); }
Пример #23
0
 protected CallNode(SourceRange range, NodeStyle style) : base(range, style)
 {
 }
Пример #24
0
		public StdSimpleCallNode(Loyc.Syntax.Lexing.Token targetToken, VList<LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
			: base(args, range, style)
		{
			_name = (Symbol)(targetToken.Value ?? GSymbol.Empty); 
			_targetOffs = ClipUShort(targetToken.StartIndex - RAS.StartIndex);
			_targetLen = ClipUShort(targetToken.Length);
		}
Пример #25
0
		public StdIdNode(Symbol name, SourceRange range, NodeStyle style = NodeStyle.Default) : base(range, style) 
		{
			if ((_name = name) == null)
				throw new ArgumentException("Cannot set IdNode.Name to null.");
		}
Пример #26
0
		public StdSimpleCallNodeWithAttrs(VList<LNode> attrs, Loyc.Syntax.Lexing.Token targetToken, VList<LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
			: base(targetToken, args, range, style) { _attrs = attrs; NoNulls(attrs, "Attrs"); }
Пример #27
0
		/// <summary>Returns the same node with a parentheses attribute added.</summary>
		/// <remarks>The node's range is changed to the provided <see cref="SourceRange"/>
        /// and the original range of the node is assigned to the parentheses attribute.</remarks>
		public static LNode InParens(this LNode node, SourceRange range)
		{
			return node.WithRange(range).PlusAttrBefore(LNode.Id(CodeSymbols.TriviaInParens));
		}
Пример #28
0
		public StdComplexCallNode(LNode target, VList<LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
			: base(args, range, style) { CheckParam.IsNotNull("target", target); _target = target; }
Пример #29
0
 public StdLiteralNode(object value, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(range, style)
 {
     _value = value;
 }
Пример #30
0
		public StdComplexCallNodeWithAttrs(VList<LNode> attrs, LNode target, VList<LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
			: base(target, args, range, style) { _attrs = attrs; NoNulls(attrs, "Attrs"); }
Пример #31
0
 public StdCallNode(RVList <LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(range, style)
 {
     _args = args; NoNulls(args, "Args");
 }
Пример #32
0
		public StdIdNodeWithAttrs(VList<LNode> attrs, Symbol name, SourceRange range, NodeStyle style = NodeStyle.Default) 
			: base(name, range, style) { _attrs = attrs; NoNulls(attrs, "Attrs"); }
Пример #33
0
 public StdSimpleCallNode(Loyc.Syntax.Lexing.Token targetToken, RVList <LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(args, range, style)
 {
     _name       = (Symbol)(targetToken.Value ?? GSymbol.Empty);
     _targetOffs = ClipUShort(targetToken.StartIndex - RAS.StartIndex);
     _targetLen  = ClipUShort(targetToken.Length);
 }
Пример #34
0
		public StdTriviaNode(Symbol name, object value, SourceRange range, NodeStyle style = NodeStyle.Default) 
			: base(range, style) { _name = name ?? GSymbol.Empty; _tokenValue = value; }
Пример #35
0
 public StdSimpleCallNodeWithAttrs(RVList <LNode> attrs, Loyc.Syntax.Lexing.Token targetToken, RVList <LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(targetToken, args, range, style)
 {
     _attrs = attrs; NoNulls(attrs, "Attrs");
 }
Пример #36
0
		void MissingEndMarker(LNode previousExpr, TokenType endMarker) {
			var location = new SourceRange(SourceFile, LT(-1).EndIndex + 1);
			ErrorSink.Write(Severity.Error, location, "Expected '{0}'", endMarker == TT.Comma ? ',' : ';');
		}
Пример #37
0
 public StdComplexCallNodeWithAttrs(RVList <LNode> attrs, LNode target, RVList <LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(target, args, range, style)
 {
     _attrs = attrs; NoNulls(attrs, "Attrs");
 }
Пример #38
0
		public void CheckForSpaceAtEndOfAttribute() {
			if (LT0.StartIndex == LT(-1).EndIndex) {
				var location = new SourceRange(SourceFile, LT0.StartIndex);
				ErrorSink.Write(Severity.Error, location, "Expected space after attribute");
			}
		}
Пример #39
0
 public StdIdNodeWithAttrs(LNodeList attrs, Symbol name, SourceRange range, NodeStyle style = NodeStyle.Default)
     : base(name, range, style)
 {
     _attrs = attrs; NoNulls(attrs, "Attrs");
 }
Пример #40
0
 public bool Contains(SourceRange inner)
 {
     return(Source == inner.Source && StartIndex <= inner.StartIndex && EndIndex >= inner.EndIndex);
 }