kOS.Safe.Compilation.KS.Token.ToString C# (CSharp) Method

ToString() public method

public ToString ( ) : string
return string
        public override string ToString()
        {
            if (Text != null)
                return Type.ToString() + " '" + Text + "'";
            else
                return Type.ToString();
        }

Usage Example

Ejemplo n.º 1
0
        /// <summary>
        /// Edit the parse branch for a loopfrom statement, rearranging its component
        /// parts into a simpler unrolled form.<br/>
        /// When given this rule:<br/>
        /// <br/>
        /// FROM {(init statements)} UNTIL expr STEP {(inc statements)} DO {(body statements)} <br/>
        /// <br/>
        /// It will edit its own child nodes and transform them into a new parse tree branch as if this had
        /// been what was in the source code instead:<br/>
        /// <br/>
        /// { (init statements) UNTIL expr { (body statements) (inc statements) } }<br/>
        /// <br/>
        /// Thus any variables declared inside (init statements) are in scope during the body of the loop.<br/>
        /// The actual logic of doing an UNTIL loop will fall upon VisitUntilNode to deal with later in the compile.<br/>
        /// </summary>
        /// <param name="node"></param>
        private void RearrangeLoopFromNode(ParseNode node)
        {
            // Safety check to see if I've already been rearranged into my final form, just in case
            // the recursion logic is messed up and this gets called twice on the same node:
            if (node.Nodes.Count == 1 && node.Nodes[0].Token.Type == TokenType.instruction_block)
                return;

            // ReSharper disable RedundantDefaultFieldInitializer
            ParseNode initBlock = null;
            ParseNode checkExpression = null;
            ParseNode untilTokenNode = null;
            ParseNode stepBlock = null;
            ParseNode doBlock = null;
            // ReSharper enable RedundantDefaultFieldInitializer

            for( int index = 0 ; index < node.Nodes.Count - 1 ; index += 2 )
            {
                switch (node.Nodes[index].Token.Type)
                {
                    case TokenType.FROM:
                        initBlock = node.Nodes[index+1];
                        break;
                    case TokenType.UNTIL:
                        untilTokenNode = node.Nodes[index];
                        checkExpression = node.Nodes[index+1];
                        break;
                    case TokenType.STEP:
                        stepBlock = node.Nodes[index+1];
                        break;
                    case TokenType.DO:
                        doBlock = node.Nodes[index+1];
                        break;
                    // no default because anything else is a syntax error and it won't even get as far as this method in that case.
                }
            }

            // These probably can't happen because the parser would have barfed before it got to this method:
            if (initBlock == null)
                throw new KOSCompileException("Missing FROM block in FROM loop.");
            if (checkExpression == null || untilTokenNode == null)
                throw new KOSCompileException("Missing UNTIL check expression in FROM loop.");
            if (stepBlock == null)
                throw new KOSCompileException("Missing STEP block in FROM loop.");
            if (doBlock == null)
                throw new KOSCompileException("Missing loop body (DO block) in FROM loop.");

            // Append the step instructions to the tail end of the body block's instructions:
            foreach (ParseNode child in stepBlock.Nodes)
                doBlock.Nodes.Add(child);

            // Make a new empty until loop node, which will get added to the init block eventually:
            var untilStatementTok = new Token
            {
                Type = TokenType.until_stmt,
                Line = untilTokenNode.Token.Line,
                Column = untilTokenNode.Token.Column,
                File = untilTokenNode.Token.File
            };

            ParseNode untilNode = initBlock.CreateNode(untilStatementTok, untilStatementTok.ToString());

            // (The direct manipulation of the tree's parent pointers, seen below, is bad form,
            // but TinyPg doesn't seem to have given us good primitives to append an existing node to the tree to do it for us.
            // CreateNode() makes a brand new empty node attached to the parent, but there seems to be no way to take an
            // existing node and attach it elsewhere without directly changing the Parent property as seen in the lines below:)

            // Populate that until loop node with the parts from this rule:
            untilNode.Nodes.Add(untilTokenNode); untilTokenNode.Parent = untilNode;
            untilNode.Nodes.Add(checkExpression); checkExpression.Parent = untilNode;
            untilNode.Nodes.Add(doBlock); doBlock.Parent = untilNode;

            // And now append that until loop to the tail end of the init block:
            initBlock.Nodes.Add(untilNode); // parent already assigned by initBlock.CreateNode() above.

            // The init block is now actually the entire loop, having been exploded and unrolled into its
            // new form, make that be our only node:
            node.Nodes.Clear();
            node.Nodes.Add(initBlock);  // initBlock's parent already points at node to begin with.

            // The FROM loop node is still in the parent's list, but it contains this new rearranged sub-tree
            // instead of its original.
        }