public virtual object VisitLabelStatement(LabeledStatement labelStatement, object data) { stackMap.Push(labelStatement); labelStatement.Statement.AcceptVisitor(this, data); stackMap.Pop(); return(null); }
// 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; }
// statements private void ParseStatement(NodeCollection<StatementNode> node) { // 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 switch (curtok.ID) { case TokenID.LCurly: // block BlockStatement newBlock = new BlockStatement(isUnsafe > 0, curtok); newBlock.IsUnsafe = isUnsafe > 0; node.Add(newBlock); ParseBlock(newBlock); break; case TokenID.Semi: // empty statement node.Add(new StatementNode(curtok)); Advance(); break; case TokenID.If: // If statement node.Add(ParseIf()); break; case TokenID.Switch: // Switch statement node.Add(ParseSwitch()); break; case TokenID.While: // While statement node.Add(ParseWhile()); break; case TokenID.Do: // Do statement node.Add(ParseDo()); break; case TokenID.For: // For statement node.Add(ParseFor()); break; case TokenID.Foreach: // Foreach statement node.Add(ParseForEach()); break; case TokenID.Break: // Break statement node.Add(ParseBreak()); break; case TokenID.Continue: // Continue statement node.Add(ParseContinue()); break; case TokenID.Goto: // Goto statement node.Add(ParseGoto()); break; case TokenID.Return: // Return statement node.Add(ParseReturn()); break; case TokenID.Throw: // Throw statement node.Add(ParseThrow()); break; case TokenID.Try: // Try statement node.Add(ParseTry()); break; case TokenID.Checked: // Checked statement node.Add(ParseChecked()); break; case TokenID.Unchecked: // Unchecked statement node.Add(ParseUnchecked()); break; case TokenID.Lock: // Lock statement node.Add(ParseLock()); break; case TokenID.Using: // Using statement node.Add(ParseUsing()); break; case TokenID.Const: isLocalConst = true; Advance(); break; case TokenID.Yield: node.Add(ParseYieldStatement()); break; case TokenID.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: case TokenID.StringLiteral: case TokenID.HexLiteral: case TokenID.IntLiteral: case TokenID.UIntLiteral: case TokenID.LongLiteral: case TokenID.ULongLiteral: case TokenID.TrueLiteral: case TokenID.FalseLiteral: case TokenID.NullLiteral: 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 ExpressionNode rexpr = ParseExpression(); if (rexpr is LocalDeclarationStatement ) { PopLocalDeclaration(rexpr); } else { ExpressionStatement enode = new ExpressionStatement(rexpr ); node.Add(enode); } if (curtok.ID == TokenID.Semi) { Advance(); } break; case TokenID.Ident: if (curTokNode != null && curTokNode.Next != null && curTokNode.Value.ID == TokenID.Colon) { LabeledStatement lsnode = new LabeledStatement(curtok); lsnode.Name = (IdentifierExpression)ParseIdentifierOrKeyword(false, true, false, false); AssertAndAdvance(TokenID.Colon); ParseStatement(lsnode.Statements); node.Add(lsnode); } else { rexpr = ParseExpression(); if (rexpr is LocalDeclarationStatement) { PopLocalDeclaration(rexpr); } else { ExpressionStatement enode = new ExpressionStatement(rexpr ); node.Add(enode); } } if (curtok.ID == TokenID.Semi) { Advance(); } break; case TokenID.Unsafe: // preprocessor directives node.Add(ParseUnsafeCode()); break; case TokenID.Fixed: // preprocessor directives node.Add(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.Add(new ExpressionStatement(ParseExpression())); break; default: if (Lexer.IsKeyWord(curtok.ID)) { // in this case a key word is used like a variable name. goto case TokenID.Ident; } else { Console.WriteLine("Unhandled case in statement parsing: \"" + curtok.ID + "\" in line: " + lineCount); // this is almost always an expression ExpressionStatement dnode = new ExpressionStatement(ParseExpression()); node.Add(dnode); if (curtok.ID == TokenID.Semi) { Advance(); } } break; } }
public virtual object VisitLabelStatement(LabeledStatement labelStatement, object data) { stackMap.Push(labelStatement); labelStatement.Statements.AcceptVisitor(this, data); stackMap.Pop(); return null; }