Пример #1
0
 /// <summary>
 /// Create a new block argument.
 /// </summary>
 /// <param name="parent">Block closure that defines the argument node.</param>
 /// <param name="colon">Colon that preceeds the argument name.</param>
 /// <param name="token">Identifier token containing the name of the argument.</param>
 protected internal BlockArgumentNode(BlockNode parent, SpecialCharacterToken colon, IdentifierToken token)
     : base(token)
 {
     #if DEBUG
     if (parent == null)
         throw new ArgumentNullException("parent");
     if (colon == null)
         throw new ArgumentNullException("colon");
     #endif
     this.Colon = colon;
     this.Parent = parent;
 }
Пример #2
0
        /// <summary>
        /// Create a new block argument.
        /// </summary>
        /// <param name="parent">Block closure that defines the argument node.</param>
        /// <param name="colon">Colon that precedes the argument name.</param>
        /// <param name="token">Identifier token containing the name of the argument.</param>
        protected internal BlockArgumentNode(BlockNode parent, SpecialCharacterToken colon, IdentifierToken token)
            : base(token)
        {
#if DEBUG
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (colon == null)
            {
                throw new ArgumentNullException("colon");
            }
#endif
            this.Colon  = colon;
            this.Parent = parent;
        }
Пример #3
0
 protected virtual BlockArgumentNode ParseBlockArgument(BlockNode parent, SpecialCharacterToken colon)
 {
     // PARSE: <block argument> ::= ':' identifier
     Token token = this.GetNextTokenxx(Preference.Default);
     if (!(token is IdentifierToken))
     {
         this.ReportParserError(parent, SemanticErrors.MissingBlockArgument, token);
         this.ResidueToken = token;
         // NB: BlockArgumentNode must be able to handle null for arg. name token.
         return new BlockArgumentNode(parent, colon, null);
     }
     return new BlockArgumentNode(parent, colon, (IdentifierToken)token);
 }
Пример #4
0
        protected virtual BlockNode ParseBlock(IPrimaryParentNode parent, SpecialCharacterToken leftBracket)
        {
            // PARSE: <block constructor> ::= '[' <block body> ']'
            //      <block body> ::= [<block argument>* '|'] [<temporaries>] [<statements>]
            //      <block argument> ::= ':' identifier
            BlockNode result = new BlockNode(parent, leftBracket);

            // PARSE: [<block argument>* '|']
            // ISSUE: It this a bug in X3J20. Shouldn't it be: [<block argument>+ '|']
            // The current definition allows blocks like: [ | ] ... or ... [ | self doStuff ]  ... or ... [ | | temp | temp := self something ]
            // We assume X3J20 bug and expect: [<block argument>+ '|']
            VerticalBarToken argumentsBar = null;
            List<BlockArgumentNode> arguments = new List<BlockArgumentNode>();

            Token token = this.GetNextTokenxx(Preference.VerticalBar | Preference.NegativeSign);
            // Check if the block has arguments
            if (Parser.IsBlockArgumentPrefix(token))
            {
                // ... yes arguments ... parse them ...
                while (true)
                {

                    if (Parser.IsBlockArgumentPrefix(token))
                    {
                        // <block argument>
                        arguments.Add(this.ParseBlockArgument(result, (SpecialCharacterToken)token));
                    }
                    else if (token is VerticalBarToken)
                    {
                        // The '|' after the arguments.
                        argumentsBar = (VerticalBarToken)token;
                        token = this.GetNextTokenxx(Preference.NegativeSign | Preference.VerticalBar);
                        break; // Done with block arguments
                    }
                    else
                    {
                        this.ReportParserError(result, SemanticErrors.MissingBlockClosingArgsBar, token);
                        break;
                    }
                    // Get the next token
                    token = this.GetNextTokenxx(Preference.VerticalBar | Preference.NegativeSign);
                }
            }

            // PARSE: [<temporaries>]
            ParseTemporariesResult ptr = this.ParseTemporaries(result, token);

            // PARSE: <statements>
            token = this.GetNextTokenxx(Preference.NegativeSign);
            StatementNode statements = this.ParseStatement(result, token);

            // Ensure the block is properly closed.
            SpecialCharacterToken rightBracket = null;
            token = this.GetNextTokenxx(Preference.Default) ;
            if (!Parser.IsBlockEndDelimiter(token))
            {
                this.ReportParserError(result, SemanticErrors.MissingBlockClosingBracket, token);
                this.ResidueToken = token;
            }
            else
            {
                rightBracket = (SpecialCharacterToken)token;
            }

            result.SetContents(arguments, argumentsBar, ptr.LeftBar, ptr.Temporaries, ptr.RightBar, statements, rightBracket);
            return result;
        }