Example #1
0
        // statements		
        private StatementNode ParseStatement()
        {
            // label		ident	: colon
            // localDecl	type	: ident
            // block		LCurly
            // empty		Semi
            // expression	
            //	-invoke		pexpr	: LParen
            //	-objCre		new		: type
            //	-assign		uexpr	: assignOp
            //	-postInc	pexpr	: ++
            //	-postDec	pexpr	: --
            //	-preInc		++		: uexpr
            //	-preDec		--		: uexpr
            //
            // selection	if		: LParen
            //				switch	: LParen
            //
            // iteration	while	: LParen
            //				do		: LParen
            //				for		: LParen
            //				foreach	: LParen
            //
            // jump			break	: Semi
            //				continue: Semi
            //				goto	: ident | case | default
            //				return	: expr
            //				throw	: expr
            //
            // try			try		: block
            // checked		checked	: block
            // unchecked	unchecked : block
            // lock			lock	: LParen
            // using		using	: LParen

            StatementNode node;
            mayBeLocalDecl = false;
            switch (curtok.ID)
            {
                case TokenID.LCurly:	// block
                    BlockStatement newBlock = new BlockStatement(isUnsafe > 0, curtok);
                    newBlock.IsUnsafe = isUnsafe > 0;
                    node = newBlock;
                    ParseBlock(newBlock);
                    break;
                case TokenID.Semi:		// empty statement
                    node = new StatementNode(curtok);
                    Advance(); // over semi
                    break;
                case TokenID.If:		// If statement
                    node = ParseIf();
                    break;
                case TokenID.Switch:	// Switch statement
                    node = ParseSwitch();
                    break;
                case TokenID.While:		// While statement
                    node = ParseWhile();
                    break;
                case TokenID.Do:		// Do statement
                    node = ParseDo();
                    break;
                case TokenID.For:		// For statement
                    node = ParseFor();
                    break;
                case TokenID.Foreach:	// Foreach statement
                    node = ParseForEach();
                    break;
                case TokenID.Break:		// Break statement
                    node = ParseBreak();
                    break;
                case TokenID.Continue:	// Continue statement
                    node = ParseContinue();
                    break;
                case TokenID.Goto:		// Goto statement
                    node = ParseGoto();
                    break;
                case TokenID.Return:	// Return statement
                    node = ParseReturn();
                    break;
                case TokenID.Throw:		// Throw statement
                    node = ParseThrow();
                    break;
                case TokenID.Try:		// Try statement
                    node = ParseTry();
                    break;
                case TokenID.Checked:	// Checked statement
                    node = ParseChecked();
                    break;
                case TokenID.Unchecked:	// Unchecked statement
                    node = ParseUnchecked();
                    break;
                case TokenID.Lock:		// Lock statement
                    node = ParseLock();
                    break;
                case TokenID.Using:		// Using statement
                    node = ParseUsing();
                    break;

                case TokenID.Const:
                    node = null;
                    isLocalConst = true;
                    Advance(); // over const
                    break;

                case TokenID.StringLiteral:
                case TokenID.HexLiteral:
                case TokenID.IntLiteral:
                case TokenID.UIntLiteral:
                case TokenID.LongLiteral:
                case TokenID.ULongLiteral:
                case TokenID.True:
                case TokenID.False:
                case TokenID.Null:
                case TokenID.LParen:
                case TokenID.DecimalLiteral:
                case TokenID.RealLiteral:
                case TokenID.CharLiteral:
                case TokenID.PlusPlus:	// PreInc statement
                case TokenID.MinusMinus:// PreDec statement
                case TokenID.This:
                case TokenID.Base:
                case TokenID.New:		// creation statement
                    node = new ExpressionStatement(ParseExpression());
                    AssertAndAdvance(TokenID.Semi);
                    break;

                case TokenID.Void:			// TODO: Special case void
                case TokenID.Bool:
                case TokenID.Byte:
                case TokenID.Char:
                case TokenID.Decimal:
                case TokenID.Double:
                case TokenID.Float:
                case TokenID.Int:
                case TokenID.Long:
                case TokenID.Object:
                case TokenID.SByte:
                case TokenID.Short:
                case TokenID.String:
                case TokenID.UInt:
                case TokenID.ULong:
                case TokenID.UShort:
                    {
                        TypeNode type = new PredefinedTypeNode(curtok.ID, curtok);
                        Advance();
                        bool mustBeDecl = false;
                        if (curtok.ID == TokenID.Question)
                        {
                            Advance();
                            type.IsNullableType = true;
                            mustBeDecl = true;
                        }
                        else if (curtok.ID == TokenID.Star)
                        {
                            do
                            {
                                Advance();
                                type = new TypePointerNode(type);
                            }
                            while (curtok.ID == TokenID.Star);
                            mustBeDecl = true;
                        }
                        if (curtok.ID == TokenID.LBracket)
                        {
                            do
                            {
                                Advance();   // over lbracket
                                int commaCount = 0;
                                while (curtok.ID == TokenID.Comma)
                                {
                                    Advance();
                                    commaCount++;
                                }
                                type.RankSpecifiers.Add(commaCount);
                                AssertAndAdvance(TokenID.RBracket);
                            }
                            while (curtok.ID == TokenID.LBracket);
                            mustBeDecl = true;
                        }

                        if (curtok.ID == TokenID.Ident)
                        {
                            node = ParseLocalDeclarationStatement(type);
                        }
                        else if (mustBeDecl)
                        {
                            RecoverFromError(TokenID.Ident);
                            node = new StatementNode(curtok);
                        }
                        else
                        {
                            ExpressionNode expr = ParseSubexpression(1, type);
                            if (!(expr is InvocationExpression))
                            {
                                ReportError("Statement must be an invocation", expr.RelatedToken);
                            }
                            node = new ExpressionStatement(expr);
                        }
                        AssertAndAdvance(TokenID.Semi);
                        break;
                    }

                case TokenID.Ident:
                    {
                        if (strings[curtok.Data] == "yield")
                        {
                            node = ParseYieldStatement();
                            break;
                        }

                        ExpressionNode expr = ParseExpressionOrType(true);
                        if (expr is IdentifierExpression && curtok.ID == TokenID.Colon)
                        {
                            Advance(); // advance over colon
                            LabeledStatement lsnode = new LabeledStatement(curtok);
                            lsnode.Name = (IdentifierExpression)expr;
                            lsnode.Statement = ParseStatement();
                            node = lsnode;
                        }
                        else
                        {
                            if (expr is TypeNode)
                                node = ParseLocalDeclarationStatement((IType)expr);
                            else
                                node = new ExpressionStatement(expr);
                            AssertAndAdvance(TokenID.Semi);
                        }

                        /*					ExpressionNode expr = ParseIdentifierOrKeyword(false, true, false, false);
                                            IdentifierExpression idExpr = expr as IdentifierExpression;
                                            if(idExpr != null && curtok.ID == TokenID.Colon)
                                            {
                                                Advance(); // advance over colon
                                                LabeledStatement lsnode = new LabeledStatement(curtok);
                                                lsnode.Name = idExpr;
                                                lsnode.Statement = ParseStatement();
                                                node = lsnode;
                                            }
                                            else
                                            {
                                                mayBeLocalDecl = true;

                                                if(curtok.ID == TokenID.ColonColon)
                                                {
                                                    Advance();
                                                    if(curtok.ID != TokenID.Ident)
                                                    {
                                                        RecoverFromError(TokenID.Ident);
                                                        node = null;
                                                        break;
                                                    }
                                                    expr = new MemberAccessExpression(expr, new IdentifierExpression(strings[curtok.Data], curtok), TokenID.ColonColon);
                                                    Advance(); // over ident
                                                }

                                                while(curtok.ID == TokenID.Dot)
                                                {
                                                    Advance();
                                                    if(curtok.ID != TokenID.Ident)
                                                    {
                                                        RecoverFromError(TokenID.Ident);
                                                        node = null;
                                                        break;
                                                    }
                                                    expr = new MemberAccessExpression(expr, new IdentifierExpression(strings[curtok.Data], curtok), TokenID.Dot);
                                                    Advance(); // over ident
                                                }

                                                if(ParsePossibleTypeParameterNode(false, false, false))
                                                {
                                                    expr = new TypeNode(expr);
                                                    ApplyTypeParameters((TypeNode) expr);
                                                }

                                                if(curtok.ID == TokenID.LBracket)
                                                {
                                                    Advance();
                                                    if(curtok.ID == TokenID.Comma || curtok.ID == TokenID.RBracket)
                                                    {
                                                        TypeNode typeNode = expr as TypeNode;
                                                        if(typeNode == null)
                                                            expr = typeNode = new TypeNode(expr);
                                                        while(true)
                                                        {
                                                            int numCommas = 0;
                                                            while(curtok.ID == TokenID.Comma)
                                                            {
                                                                Advance();
                                                                numCommas++;
                                                            }
                                                            AssertAndAdvance(TokenID.RBracket);
                                                            typeNode.RankSpecifiers.Add(numCommas);

                                                            if(curtok.ID != TokenID.LBracket) break;
                                                            Advance();
                                                        }
                                                    }
                                                    else
                                                    {
                                                        ExpressionList exprList = ParseExpressionList();
                                                        expr = new ElementAccessExpression(expr, exprList);
                                                        AssertAndAdvance(TokenID.RBracket);
                                                    }
                                                }

                                                if(curtok.ID == TokenID.Question)
                                                {
                                                    Advance();
                                                    TypeNode typeNode = expr as TypeNode;
                                                    if(typeNode == null)
                                                        expr = typeNode = new TypeNode(expr);
                                                    typeNode.IsNullableType = true;
                                                }
                                                else
                                                {
                                                    while(curtok.ID == TokenID.Star)
                                                    {
                                                        Advance();
                                                        expr = new TypePointerNode(expr);
                                                    }
                                                }*/


                        //						expr = ParseSubexpression(PRECEDENCE_PRIMARY, expr);
                        /*						exprStack.Push(expr);
                                                ParseContinuingPrimary();
                                                expr = exprStack.Pop();*/
                        /*						if((expr is IdentifierExpression || expr is MemberAccessExpression || expr is TypeNode)
                                                        && (curtok.ID == TokenID.Ident || curtok.ID == TokenID.Star || curtok.ID == TokenID.Question))
                                                {
                                                    node = ParseLocalDeclarationStatement((IType) expr);
                                                }
                                                else
                                                    node = new ExpressionStatement(ParseSubexpression(1, expr));
                                                AssertAndAdvance(TokenID.Semi);
                                            }*/
                        break;
                    }

                case TokenID.Unsafe:
                    // preprocessor directives
                    node = ParseUnsafeCode();
                    break;

                case TokenID.Fixed:
                    // preprocessor directives
                    node = ParseFixedStatement();
                    break;


                case TokenID.Star:
                    // dereference variable 
                    // introduced because of the mono file test-406.cs
                    //private static uint DoOp2 (uint *u) {
                    //    *(u) += 100;
                    //    return *u;
                    //}
                    node = new ExpressionStatement(ParseExpression());
                    AssertAndAdvance(TokenID.Semi);
                    break;

                case TokenID.SingleComment:
                case TokenID.MultiComment:
                case TokenID.DocComment:
                    node = new CommentStatement(curtok, strings[curtok.Data], curtok.ID != TokenID.SingleComment);
                    Advance(); // over comment token
                    break;
                default:
                    {
                        Console.WriteLine("Unhandled case in statement parsing: \"" + curtok.ID + "\" in line: " + lineCount);
                        // this is almost always an expression
                        ExpressionStatement dnode = new ExpressionStatement(ParseExpression());
                        node = dnode;
                        if (curtok.ID == TokenID.Semi)
                        {
                            Advance();
                        }
                        break;
                    }
            }
            return node;
        }
 public virtual object VisitStatementNode(StatementNode statementNode, object data)
 {
     return null;
 }