Пример #1
0
        /// <summary>
        /// Generates a sequence of nodes separated by the specified unary delimiter.
        /// </summary>
        /// <param name="delimiter">The type of unary delimiter.</param>
        /// <param name="sequence">The sequence of nodes to be delimited.</param>
        /// <param name="addTrailing">Include a trailing delimiter, false by default.</param>
        /// <returns>The root node of this sequence AST.</returns>
        public static Node Generate(UnaryDelimiterType delimiter, IReadOnlyList <Node> sequence, bool addTrailing = false)
        {
            if (sequence.Count == 0)
            {
                throw new ArgumentException("sequence is empty");
            }

            // build a comma separated list of params
            Node paramSeq = null;

            // create an array of dilimiter nodes if there is more than
            // one item in the sequence and build a tree with them.
            UnaryDelimiter[] delimiters = null;
            if (sequence.Count > 1 || addTrailing)
            {
                var count = addTrailing ? sequence.Count : sequence.Count - 1;
                delimiters = new UnaryDelimiter[count];
                for (int i = 0; i < count; ++i)
                {
                    delimiters[i] = new UnaryDelimiter(delimiter);
                }
                paramSeq = delimiters[0];
            }

            for (int i = 0, j = 0; i < sequence.Count; ++i)
            {
                var seq = sequence[i];

                if (delimiters != null)
                {
                    // if the current delimiter has all of
                    // its children move to the next one
                    if (delimiters[j].Children.Count == 2)
                    {
                        ++j;
                    }

                    delimiters[j].AddChild(seq);

                    // if there's one or more delimiters left add
                    // the next one as a child of the current one
                    if (j + 1 < delimiters.Length)
                    {
                        delimiters[j].AddChild(delimiters[j + 1]);
                    }
                }
                else
                {
                    // only one param and no trailing delimiter
                    paramSeq = seq;
                }
            }

            if (addTrailing)
            {
                delimiters[delimiters.Length - 1].AddChild(new Terminal());
            }

            return(paramSeq);
        }
Пример #2
0
        public void Visit(UnaryDelimiter delimiter)
        {
            switch (delimiter.Type)
            {
            case UnaryDelimiterType.Colon:
                _sb.Append(":");
                if (_prev is Case)
                {
                    _sb.AppendLine();
                    AddIndentation();
                }
                break;

            case UnaryDelimiterType.Comma:
                _sb.Append(',');
                // if the comma is under a StructDef or struct literal then append a new line
                var  node      = delimiter.Parent;
                bool braceTrip = false;
                while (node != null)
                {
                    if (node is OpenDelimiter && ((OpenDelimiter)node).Type == BinaryDelimiterType.Brace)
                    {
                        braceTrip = true;
                    }

                    if (node is StructDef || (node is Identifier && braceTrip))
                    {
                        _sb.AppendLine();

                        // if this is the last line in a struct literal don't indent
                        if (!braceTrip || !(delimiter.Children[1] is Terminal))
                        {
                            AddIndentation();
                        }
                        break;
                    }
                    node = node.Parent;
                }

                // reached the end, not under StructDef so append a space
                if (node == null)
                {
                    _sb.Append(' ');
                }

                break;

            default:
                throw new InvalidOperationException($"unsupported sequence delimiter {delimiter.Type}");
            }

            _prev = delimiter;
        }