Ejemplo n.º 1
0
		private IType ParseType()										
		{
            //backup modifiers because ParseQualifiedIdentifier will consume ParseTypeParameter
            // and ParseTypeParameter consume modifiers ... 
            Modifier backupModifiers = curmods;
            curmods = Modifier.Empty;
            IType result = new TypeNode(curtok);

            QualifiedIdentifierExpression ident = ParseQualifiedIdentifier(true, false, false);

            // if the ParseQualifiedIdentifier is can resolve the identifier to a type, 
            // the parser does not need to wrappe the type in another typenode ... 
            if ( ident.Expressions.Last is PredefinedTypeNode )
            {
                result = (IType)ident.Expressions.Last;
            }
            else
            {
                ((TypeNode)result).Identifier = ident;

                // move the rank specifier
                if (((TypeNode)result).Identifier.IsType)
                {
                    ((IType)result).RankSpecifiers = ((IType)((TypeNode)result).Identifier.Expressions.Last).RankSpecifiers;
                    ((IType)((TypeNode)result).Identifier.Expressions.Last).RankSpecifiers = new List<int>();
                }
            }

            if (curtok.ID == TokenID.Star)
            {
                result = new TypePointerNode( (ExpressionNode)result ); 
                Advance();
            }

            if (curtok.ID == TokenID.Question)
            {
                ((INullableType)result).IsNullableType = true;
                Advance();
            }

            curmods = backupModifiers;

            return result;
		}
Ejemplo n.º 2
0
        private ExpressionNode ParseExpressionOrType(bool inStatementContext)
        {
            // Can the interior be a type? (A.2.2)
            switch (curtok.ID)
            {
                // type-name
                case TokenID.Ident:

                // simple-type
                case TokenID.SByte:
                case TokenID.Byte:
                case TokenID.Short:
                case TokenID.UShort:
                case TokenID.Int:
                case TokenID.UInt:
                case TokenID.Long:
                case TokenID.ULong:
                case TokenID.Char:

                case TokenID.Float:
                case TokenID.Double:

                case TokenID.Decimal:

                case TokenID.Bool:

                // class-type
                case TokenID.Object:
                case TokenID.String:
                    // yes, it can
                    break;

                default:
                    // no, it can not
                    return ParseExpression();
            }

            ExpressionNode expr = ParseIdentifierOrKeyword(false, false, false, false, false);
            if (curtok.ID == TokenID.ColonColon)
            {
                // id :: id type-parameter-list_opt

                QualifiedIdentifierExpression qualID = new QualifiedIdentifierExpression(curtok);	// TODO: Replace by QualifiedAliasMember instance
                qualID.IsNamespaceAliasQualifier = true;
                qualID.Expressions.Add(expr);

                Advance(); // over ColonColon
                qualID.Expressions.Add(ParseMember(inStatementContext));

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

            while (curtok.ID == TokenID.Dot)
            {
                Advance(); // over Dot
                if (curtok.ID != TokenID.Ident)
                {
                    RecoverFromError(TokenID.Ident);
                    return expr;
                }
                expr = new MemberAccessExpression(expr, ParseMember(inStatementContext), TokenID.Dot);
            }

            bool hasQuestionMark = false;
            int starCount = 0;
            bool hasBracket = false;

            if (curtok.ID == TokenID.Question)
            {
                Advance();
                hasQuestionMark = true;
            }

            while (curtok.ID == TokenID.Star)
            {
                Advance();
                starCount++;
            }

            // return (a * b);
            // return (a ? b : c);
            // a* b = c;
            // a? b = c;
            // a b = c;

            //if(curtok.ID == TokenID.Ident || (hasQuestionMark || starCount > 0) && curtok.ID == TokenID.RParen) goto foundType;

            if (curtok.ID == TokenID.Ident)
            {
                if (inStatementContext) goto foundType;
                else if (!hasQuestionMark && starCount == 0) goto foundType;	// it is a parse error
            }
            else if (curtok.ID == TokenID.RParen)
            {
                if (hasQuestionMark || starCount > 0) goto foundType;
            }
            else if (curtok.ID == TokenID.LBracket)
            {
                Advance();
                hasBracket = true;
                if (hasQuestionMark || starCount > 0 || curtok.ID == TokenID.Comma || curtok.ID == TokenID.RBracket) goto foundType;
            }

            //
            // treat as expression
            //
            if (hasQuestionMark)
            {
                // hasBracket is false
                ExpressionNode trueExpr = ParseSubexpression(starCount > 0 ? (int)PRECEDENCE_UNARY : 1);
                while (starCount-- > 0)
                    trueExpr = new DereferenceExpression(trueExpr);
                AssertAndAdvance(TokenID.Colon);
                return new ConditionalExpression(expr, trueExpr, ParseExpression());
            }
            else if (starCount > 0)
            {
                // hasBracket is false
                starCount--;
                ExpressionNode right = ParseSubexpression(starCount > 0 ? PRECEDENCE_UNARY : PRECEDENCE_MULTIPLICATIVE + ASSOC_LEFT);
                while (starCount-- > 0)
                    right = new DereferenceExpression(right);
                expr = new BinaryExpression(TokenID.Star, expr, right);
            }
            else if (hasBracket)
            {
                expr = new ElementAccessExpression(expr, ParseExpressionList());
                AssertAndAdvance(TokenID.RBracket);
            }
            return ParseSubexpression(1, expr);


            //
        // treat as type
        //
        foundType:
            TypeNode typeNode = new TypeNode(expr);
            if (hasQuestionMark)
                typeNode.IsNullableType = true;
            while (starCount-- > 0)
                typeNode = new TypePointerNode(typeNode);
            if (hasBracket)
            {
                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();
                }
            }
            return typeNode;
        }
Ejemplo n.º 3
0
        /*		private TypeNode ParseTypeDeclarator(TypeNode type)
                {
                    if(curtok.ID == TokenID.Question && curtok.NullableDeclaration)
                    {
                        Advance();
                        type.IsNullableType = true;
                    }
                    while(curtok.ID == TokenID.Star)
                    {
                        Advance();
                        type = new TypePointerNode(type);
                    }
                    // TODO: Parse rank specifiers
                    return type;
                }*/

        // note: this does NOT check for rank specifiers: MyType[,,]
        // to also do this use CheckRankSpecifier(TypeNode);
        private TypeNode ParseType(bool considerTrinary)
        {
            //backup modifiers because ParseQualifiedIdentifier will consume ParseTypeParameter
            // and ParseTypeParameter consume modifiers ... 
            Modifier backupModifiers = curmods;
            curmods = Modifier.Empty;
            TypeNode result = null;

            QualifiedIdentifierExpression ident = ParseQualifiedIdentifier(true, false, false);
           
            // if the ParseQualifiedIdentifier can resolve the identifier to a type, 
            // the parser does not need to wrap the type in another type node ... 
            if (ident.Expressions.Last is PredefinedTypeNode)
            {
                result = (TypeNode)ident.Expressions.Last;
            }
            else
            {
                result = new TypeNode(curtok);
                result.Identifier = ident;

                // Edit Robin: I don't think ParseQualifiedIdentifier will ever have rank specifiers..
                //// move the rank specifier
                //if (result.Identifier.IsType)
                //{
                //    result.RankSpecifiers = ((IType)result.Identifier.Expressions.Last).RankSpecifiers;
                //    ((IType)result.Identifier.Expressions.Last).RankSpecifiers = new List<int>();
                //}
            }

            if (curtok.ID == TokenID.Question && (!considerTrinary || curtok.NullableDeclaration))
            {
                Advance();
                result.IsNullableType = true;
            }
            while (curtok.ID == TokenID.Star)
            {
                Advance();
                result = new TypePointerNode(result);
            }

            curmods = backupModifiers;

            return result;
        }
Ejemplo n.º 4
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;
        }
Ejemplo n.º 5
0
        public virtual object VisitTypePointerReference(TypePointerNode  typePointerReference, object data)
        {
            stackMap.Push(typePointerReference);
             typePointerReference.Expression.AcceptVisitor(this, data); ;

             stackMap.Pop();
             return null;

        }