/// <summary>
 /// Create a new cascade message sequence.
 /// </summary>
 /// <param name="parent">Parent node that defines this cascade message node.</param>
 /// <param name="token">Token representing the semicolon used to delimit cascase message sequences.</param>
 protected internal CascadeMessageSequenceNode(ICascadeMessageSequenceParentNode parent, SpecialCharacterToken token)
 {
     #if DEBUG
     if (parent == null)
         throw new ArgumentNullException("parent");
     if (token == null)
         throw new ArgumentNullException("token");
     #endif
     this.Parent = parent;
     this.Semicolon = token;
 }
Example #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 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;
 }
 /// <summary>
 /// Create and initialize a new literal array node.
 /// </summary>
 /// <param name="parent">Parent node that defines this literal node.</param>
 /// <param name="arrayToken">Hash token that defines the start of array literals.</param>
 /// <param name="leftParenthesis">Opening left parenthesis of the literal array.</param>
 protected internal ArrayLiteralNode(ILiteralNodeParent parent, SpecialCharacterToken arrayToken,
     SpecialCharacterToken leftParenthesis)
     : base(parent)
 {
     #if DEBUG
     if (!Parser.IsLiteralArrayPrefix(arrayToken))
         throw new ArgumentException("arrayToken");
     if (!Parser.IsOpeningParenthesis(leftParenthesis))
         throw new ArgumentException("leftParenthesis");
     #endif
     this.ArrayToken = arrayToken;
     this.LeftParenthesis = leftParenthesis;
     this.Elements = new List<LiteralNode>();
 }
 /// <summary>
 /// Create and initialize a new literal array node.
 /// </summary>
 /// <param name="parent">Parent node that defines this literal node.</param>
 /// <param name="arrayToken">Hash token that defines the start of array literals.</param>
 /// <param name="leftParenthesis">Opening left parenthesis of the literal array.</param>
 protected internal ByteArrayLiteralNode(ILiteralNodeParent parent, SpecialCharacterToken arrayToken,
     SpecialCharacterToken leftBracket)
     : base(parent)
 {
     #if DEBUG
     if (!Parser.IsLiteralArrayPrefix(arrayToken))
         throw new ArgumentException("arrayToken");
     if (!VseCompatibleParser.IsOpeningByteArrayBracket(leftBracket))
         throw new ArgumentException("leftBracket");
     #endif
     this.ArrayToken = arrayToken;
     this.LeftBracket = leftBracket;
     this.Elements = new List<SmallIntegerLiteralNode>();
 }
 /// <summary>
 /// Create a new parenthesized expression node.
 /// </summary>
 /// <param name="parent">Parent node that defines this expression.</param>
 /// <param name="token">Left opening parenthesis of the parenthesized expression.</param>
 protected internal ParenthesizedExpressionNode(IPrimaryParentNode parent, SpecialCharacterToken token)
 {
     #if DEBUG
     if (parent == null)
         throw new ArgumentNullException("parent");
     if (!Parser.IsOpeningParenthesis(token))
         // We do expect the caller to this method to have ensured that we are actually parsing a parethesis.
         throw new InvalidParserOperationException("Expected opening parenthesis token ... '('");
     #endif
     this.Parent = parent;
     this.LeftParenthesis = (SpecialCharacterToken)token;
 }
 /// <summary>
 /// Initializes the node after being parsed by the parser.
 /// </summary>
 /// <param name="elements">Collection with literal nodes that compose the elements of the literal array.</param>
 /// <param name="rightParenthesis">Closing right parenthesis of the literal array.</param>
 protected internal void SetContents(IEnumerable<LiteralNode> elements, SpecialCharacterToken rightParenthesis)
 {
     if (elements == null)
         throw new ArgumentNullException("elements");
     if ((rightParenthesis != null) &&  !Parser.IsClosingParenthesis(rightParenthesis)) // NB: We allow null value.
         throw new ArgumentException("rightParenthesis");
     this.RightParenthesis = rightParenthesis;
     foreach (LiteralNode elem in elements)
         this.Elements.Add(elem);
 }
Example #7
0
        /// <summary>
        /// Initializes the node after being parsed by the parser.
        /// </summary>
        /// <param name="arguments">Collection of block arguments for this block.</param>
        /// <param name="argumentsBar">The vertical bar after the block arguments.</param>
        /// <param name="leftBar">Left vertical bar "|" token, if temporary variable definition is present.</param>
        /// <param name="temporaries">A collection of temporary variable nodes.</param>
        /// <param name="rightBar">Right vertical bar "|" token, if temporary variable definition is present.</param>
        /// <param name="statements">Executable statements defining the function.</param>
        /// <param name="rightBracket">Token for the right / closing square bracket of the block.</param>
        protected internal void SetContents(IEnumerable<BlockArgumentNode> arguments, VerticalBarToken argumentsBar,
            VerticalBarToken leftBar, IEnumerable<TemporaryVariableNode> temporaries, VerticalBarToken rightBar,
            StatementNode statements, SpecialCharacterToken rightBracket)
        {
            if (arguments == null)
                throw new ArgumentNullException("arguments");

            this.SetContents(leftBar, temporaries, rightBar, statements);

            this.Arguments.Clear();
            this.Arguments.AddRange(arguments);
            this.ArgumentsBar = argumentsBar; // OK with null if no args. or illegal source
            this.RightBracket = rightBracket; // OK with null if illegal source
        }
Example #8
0
 /// <summary>
 /// Create and intialize a block node.
 /// </summary>
 /// <param name="parent">The parent node to the block node.</param>
 /// <param name="token">Token for the left / opening square bracket of the block.</param>
 protected internal BlockNode(IPrimaryParentNode parent, SpecialCharacterToken token)
 {
     #if DEBUG
     if (parent == null)
         throw new ArgumentNullException("parent");
     if (token == null)
         throw new ArgumentNullException("token");
     #endif
     this.Arguments = new List<BlockArgumentNode>();
     this.Parent = parent;
     this.LeftBracket = token;
 }
Example #9
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;
        }
        protected ByteArrayLiteralNode ParseByteArrayLiteral(ILiteralNodeParent parent, SpecialCharacterToken arrayToken, SpecialCharacterToken leftBracket)
        {
            // PARSE: <array literal> ::= '#[' <number literal>* ']'

            List<SmallIntegerLiteralNode> elements = new List<SmallIntegerLiteralNode>();
            ByteArrayLiteralNode result = new ByteArrayLiteralNode(parent, arrayToken, leftBracket);

            // Process tokens inside the array ...
            while (true)
            {
                // ... get next token in the array ...
                Token token = this.GetNextTokenxx(Preference.NegativeSign);

                // Is this closing parenthesis?
                if (VseCompatibleParser.IsClosingByteArrayBracket(token))
                {
                    // Closing parenthesis ... done with the array, return litral array node.
                    result.SetContents(elements, (SpecialCharacterToken)token);
                    this.ResidueToken = null;
                    return result;
                }

                if (token is EofToken)
                {
                    // Unfinished source code ... return
                    result.SetContents(elements, null);
                    this.ReportParserError(parent, "Missing literal byte array closing bracket.", token);
                    this.ResidueToken = token;
                    return result;
                }

                // PARSE: <numeric liteal>
                if (token is SmallIntegerToken)
                {
                    elements.Add(new SmallIntegerLiteralNode(result, (SmallIntegerToken)token, null));
                }
                else if (token is NegativeSignToken)
                {
                    NegativeSignToken negativeSign = (NegativeSignToken)token;
                    token = this.GetNextTokenxx(Preference.NegativeSign);
                    if (token is SmallIntegerToken)
                    {
                        elements.Add(new SmallIntegerLiteralNode(result, (SmallIntegerToken)token, negativeSign));
                    }
                    else
                    {
                        this.ReportParserError(parent, "Unrecognized literal.", token);
                        this.ResidueToken = token;
                        result.SetContents(elements, null);
                        return result;
                    }
                }
                else
                {
                    this.ReportParserError(parent, "Unrecognized literal.", token);
                    this.ResidueToken = token;
                    result.SetContents(elements, null);
                    return result;
                }
            }
        }
        protected override LiteralNode ParseLiteral(ILiteralNodeParent parent, Token token)
        {
            if ((parent is ArrayLiteralNode) && Parser.IsOpeningParenthesis(token))
            {
                // Stupid VSE allows declarations of arrays like: #( 1 2 ( 3 4 ) 5 6),
                // which is identical to: #( 1 2 #( 3 4 ) 5 6).
                // Only the inner (child) arrays may omit the hash prefix.
                // Here we emulate this and create a 'fake' hash token.
                // The fake hash token gets the same source positions and the parenthesis token.
                SpecialCharacterToken hash = new SpecialCharacterToken(SemanticConstants.LiteralArrayPrefix);
                hash.SetTokenValues(token.StartPosition, token.StopPosition, null);
                this.ResidueToken = token;
                return this.ParseArrayLiteral(parent, hash);
            }

            if (!Parser.IsLiteralArrayPrefix(token))
                return base.ParseLiteral(parent, token);

            Token token2 = this.GetNextTokenxx(Preference.Default);
            if (VseCompatibleParser.IsOpeningByteArrayBracket(token2))
                return this.ParseByteArrayLiteral(parent, (SpecialCharacterToken) token, (SpecialCharacterToken)token2);

            this.ResidueToken = token2;
            return base.ParseLiteral(parent, token);
        }
 /// <summary>
 /// Initializes the node after being parsed by the parser.
 /// </summary>
 /// <param name="elements">Collection with literal nodes that compose the elements of the literal array.</param>
 /// <param name="rightParenthesis">Closing right parenthesis of the literal array.</param>
 protected internal void SetContents(IEnumerable<SmallIntegerLiteralNode> elements, SpecialCharacterToken rightBracket)
 {
     if (elements == null)
         throw new ArgumentNullException("elements");
     if ((rightBracket != null) && !VseCompatibleParser.IsClosingByteArrayBracket(rightBracket)) // NB: We allow null value.
         throw new ArgumentException("rightBracket");
     this.RightBracket = rightBracket;
     foreach (SmallIntegerLiteralNode elem in elements)
         this.Elements.Add(elem);
 }
Example #13
0
        protected virtual ParenthesizedExpressionNode ParseParenthesizedExpression(IPrimaryParentNode parent, SpecialCharacterToken leftParenthesis)
        {
            // PARSE: '(' <expression> ')'
            ParenthesizedExpressionNode result = new ParenthesizedExpressionNode(parent, leftParenthesis);

            Token token = this.GetNextTokenxx(Preference.NegativeSign);
            ExpressionNode expression = this.ParseExpression(result, token);

            if (expression == null)
            {
                this.ReportParserError(result, SemanticErrors.MissingExpression, token);
                return result;
            }

            // Ensure the parenthese are properly closed.
            token = this.GetNextTokenxx(Preference.Default);
            SpecialCharacterToken rightParenthesis = null;
            if (Parser.IsClosingParenthesis(token))
            {
                rightParenthesis = (SpecialCharacterToken)token;
            }
            else
            {
                this.ReportParserError(result, SemanticErrors.MissingExpressionClosingParenthesis, token);
                this.ResidueToken = token;
            }

            result.SetContents(expression, rightParenthesis);
            return result;
        }
Example #14
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);
 }
 /// <summary>
 /// Initializes the node after being parsed by the parser.
 /// </summary>
 /// <param name="expression">Expression that's being enclosed by the parentheses.</param>
 /// <param name="rightParenthesis">Right closingparenthesis of the parenthesized expression.</param>
 protected internal void SetContents(ExpressionNode expression, SpecialCharacterToken rightParenthesis)
 {
     if (expression == null)
         throw new ArgumentNullException("expression");
     if ((rightParenthesis != null) && !Parser.IsClosingParenthesis(rightParenthesis)) // Must allow for null
         throw new ArgumentException("rightParenthesis");
     this.Expression = expression;
     this.RightParenthesis = rightParenthesis;
 }
Example #16
0
 /// <summary>
 /// Initializes the node after being parsed by the parser.
 /// </summary>
 /// <param name="expression">Expression node defining the statement.</param>
 /// <param name="period">Optional period that terminates a statement.</param>
 /// <param name="nextStatement">Optional statement node that follows this statement.</param>
 protected internal void SetContents(ExpressionNode expression, SpecialCharacterToken period, StatementNode nextStatement)
 {
     if (expression == null)
         throw new ArgumentNullException("expression");
     this.Expression = expression;
     this.Period = period; // Null is OK here.
     this.NextStatement = nextStatement; // Null is OK here.
 }
Example #17
0
        protected virtual ArrayLiteralNode ParseArrayLiteral(ILiteralNodeParent parent, SpecialCharacterToken arrayToken)
        {
            // PARSE: <array literal> ::= '#(' <array element>* ')'
            // <array element> ::= <literal> | identifier

            Token token = this.GetNextTokenxx(Preference.Default);
            if (!Parser.IsOpeningParenthesis(token))
            {
                this.ReportParserError(parent, SemanticErrors.MissingLiteralArrayOpeningParenthesis, token);
                // The hash token is thrown away and lost :-/   ... only the current token is passed on.
                this.ResidueToken = token;
                return null;
            }
            List<LiteralNode> elements = new List<LiteralNode>();
            ArrayLiteralNode result = new ArrayLiteralNode(parent, arrayToken, (SpecialCharacterToken)token);

            // Process tokens inside the array ...
            while (true)
            {
                // ... get next token in the array ...
                token = this.GetNextTokenxx(Preference.NegativeSign | Preference.UnquotedSelector);

                // Is this closing parenthesis?
                if (Parser.IsClosingParenthesis(token))
                {
                    // Closing parenthesis ... done with the array, return litral array node.
                    result.SetContents(elements, (SpecialCharacterToken)token);
                    this.ResidueToken = null;
                    return result;
                }

                if (token is EofToken)
                {
                    // Unfinished source code ... return
                    result.SetContents(elements, null);
                    this.ReportParserError(parent, SemanticErrors.MissingLiteralArrayClosingParenthesis, token);
                    this.ResidueToken = token;
                    return result;
                }

                // PARSE: <array element> ::= <literal> | identifier
                if (token is ILiteralArrayIdentifierToken)
                {
                    // identifier ... special case only inside arrays.
                    elements.Add(new IdentifierLiteralNode(result, (ILiteralArrayIdentifierToken)token));
                }
                else
                {
                    // ... it's not identifier, so it must be an literal
                    LiteralNode element = this.ParseLiteral(result, token);
                    if (element == null)
                    {
                        // Report error in souce code ... here, it must be a literal
                        this.ReportParserError(result, SemanticErrors.UnrecognizedLiteral, token);
                        result.SetContents(elements, null);
                        return result;
                    }
                    else
                    {
                        // ... add the child element to the array elements.
                        elements.Add(element);
                    }
                }
            }
        }