public IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null) { switch (laKind) { case Semicolon: if (!EmptyAllowed) goto default; Step(); return null; case OpenCurlyBrace: if (!BlocksAllowed) goto default; return BlockStatement(Scope,Parent); // LabeledStatement (loc:... goto loc;) case Identifier: if (Lexer.CurrentPeekToken.Kind != Colon) goto default; Step(); var ls = new LabeledStatement() { Location = t.Location, Identifier = t.Value, Parent = Parent }; Step(); ls.EndLocation = t.EndLocation; return ls; // IfStatement case If: Step(); var iS = new IfStatement{ Location = t.Location, Parent = Parent }; Expect(OpenParenthesis); // IfCondition IfCondition(iS); // ThenStatement if(Expect(CloseParenthesis)) iS.ThenStatement = Statement(Scope: Scope, Parent: iS); // ElseStatement if (laKind == (Else)) { Step(); iS.ElseStatement = Statement(Scope: Scope, Parent: iS); } if(t != null) iS.EndLocation = t.EndLocation; return iS; // Conditions case Version: case Debug: return StmtCondition(Parent, Scope); case Static: if (Lexer.CurrentPeekToken.Kind == If) return StmtCondition(Parent, Scope); else if (Lexer.CurrentPeekToken.Kind == Assert) goto case Assert; else if (Lexer.CurrentPeekToken.Kind == Import) goto case Import; goto default; case For: return ForStatement(Scope, Parent); case Foreach: case Foreach_Reverse: return ForeachStatement(Scope, Parent); case While: Step(); var ws = new WhileStatement() { Location = t.Location, Parent = Parent }; Expect(OpenParenthesis); ws.Condition = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) { ws.ScopedStatement = Statement(Scope: Scope, Parent: ws); ws.EndLocation = t.EndLocation; } return ws; case Do: Step(); var dws = new WhileStatement() { Location = t.Location, Parent = Parent }; if(!IsEOF) dws.ScopedStatement = Statement(true, false, Scope, dws); if(Expect(While) && Expect(OpenParenthesis)) { dws.Condition = Expression(Scope); Expect(CloseParenthesis); Expect(Semicolon); dws.EndLocation = t.EndLocation; } return dws; // [Final] SwitchStatement case Final: if (Lexer.CurrentPeekToken.Kind != Switch) goto default; goto case Switch; case Switch: var ss = new SwitchStatement { Location = la.Location, Parent = Parent }; if (laKind == (Final)) { ss.IsFinal = true; Step(); } Step(); Expect(OpenParenthesis); ss.SwitchExpression = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) ss.ScopedStatement = Statement(Scope: Scope, Parent: ss); ss.EndLocation = t.EndLocation; return ss; case Case: Step(); var sscs = new SwitchStatement.CaseStatement() { Location = la.Location, Parent = Parent }; sscs.ArgumentList = Expression(Scope); Expect(Colon); // CaseRangeStatement if (laKind == DoubleDot) { Step(); Expect(Case); sscs.LastExpression = AssignExpression(); Expect(Colon); } var sscssl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: sscs); if (stmt != null) { stmt.Parent = sscs; sscssl.Add(stmt); } } sscs.ScopeStatementList = sscssl.ToArray(); sscs.EndLocation = t.EndLocation; return sscs; case Default: Step(); var ssds = new SwitchStatement.DefaultStatement() { Location = la.Location, Parent = Parent }; Expect(Colon); var ssdssl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: ssds); if (stmt != null) { stmt.Parent = ssds; ssdssl.Add(stmt); } } ssds.ScopeStatementList = ssdssl.ToArray(); ssds.EndLocation = t.EndLocation; return ssds; case Continue: Step(); var cs = new ContinueStatement() { Location = t.Location, Parent = Parent }; if (laKind == (Identifier)) { Step(); cs.Identifier = t.Value; } else if(IsEOF) cs.IdentifierHash = DTokens.IncompleteIdHash; Expect(Semicolon); cs.EndLocation = t.EndLocation; return cs; case Break: Step(); var bs = new BreakStatement() { Location = t.Location, Parent = Parent }; if (laKind == (Identifier)) { Step(); bs.Identifier = t.Value; } else if(IsEOF) bs.IdentifierHash = DTokens.IncompleteIdHash; Expect(Semicolon); bs.EndLocation = t.EndLocation; return bs; case Return: Step(); var rs = new ReturnStatement() { Location = t.Location, Parent = Parent }; if (laKind != (Semicolon)) rs.ReturnExpression = Expression(Scope); Expect(Semicolon); rs.EndLocation = t.EndLocation; return rs; case Goto: Step(); var gs = new GotoStatement() { Location = t.Location, Parent = Parent }; switch(laKind) { case Identifier: Step(); gs.StmtType = GotoStatement.GotoStmtType.Identifier; gs.LabelIdentifier = t.Value; break; case Default: Step(); gs.StmtType = GotoStatement.GotoStmtType.Default; break; case Case: Step(); gs.StmtType = GotoStatement.GotoStmtType.Case; if (laKind != (Semicolon)) gs.CaseExpression = Expression(Scope); break; default: if (IsEOF) gs.LabelIdentifierHash = DTokens.IncompleteIdHash; break; } Expect(Semicolon); gs.EndLocation = t.EndLocation; return gs; case With: Step(); var wS = new WithStatement() { Location = t.Location, Parent = Parent }; if(Expect(OpenParenthesis)) { // Symbol wS.WithExpression = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) wS.ScopedStatement = Statement(Scope: Scope, Parent: wS); } wS.EndLocation = t.EndLocation; return wS; case Synchronized: Step(); var syncS = new SynchronizedStatement() { Location = t.Location, Parent = Parent }; if (laKind == (OpenParenthesis)) { Step(); syncS.SyncExpression = Expression(Scope); Expect(CloseParenthesis); } if(!IsEOF) syncS.ScopedStatement = Statement(Scope: Scope, Parent: syncS); syncS.EndLocation = t.EndLocation; return syncS; case Try: Step(); var ts = new TryStatement() { Location = t.Location, Parent = Parent }; ts.ScopedStatement = Statement(Scope: Scope, Parent: ts); if (!(laKind == (Catch) || laKind == (Finally))) SemErr(Catch, "At least one catch or a finally block expected!"); var catches = new List<TryStatement.CatchStatement>(); // Catches while (laKind == (Catch)) { Step(); var c = new TryStatement.CatchStatement() { Location = t.Location, Parent = ts }; // CatchParameter if (laKind == (OpenParenthesis)) { Step(); if (laKind == CloseParenthesis || IsEOF) { SemErr(CloseParenthesis, "Catch parameter expected, not ')'"); Step(); } else { var catchVar = new DVariable { Parent = Scope, Location = t.Location }; Lexer.PushLookAheadBackup(); catchVar.Type = BasicType(); if (laKind == CloseParenthesis) { Lexer.RestoreLookAheadBackup(); catchVar.Type = new IdentifierDeclaration("Exception"); } else Lexer.PopLookAheadBackup(); if (Expect(Identifier)) { catchVar.Name = t.Value; catchVar.NameLocation = t.Location; Expect(CloseParenthesis); } else if(IsEOF) catchVar.NameHash = DTokens.IncompleteIdHash; catchVar.EndLocation = t.EndLocation; c.CatchParameter = catchVar; } } if(!IsEOF) c.ScopedStatement = Statement(Scope: Scope, Parent: c); c.EndLocation = t.EndLocation; catches.Add(c); } if (catches.Count > 0) ts.Catches = catches.ToArray(); if (laKind == (Finally)) { Step(); var f = new TryStatement.FinallyStatement() { Location = t.Location, Parent = Parent }; f.ScopedStatement = Statement(); f.EndLocation = t.EndLocation; ts.FinallyStmt = f; } ts.EndLocation = t.EndLocation; return ts; case Throw: Step(); var ths = new ThrowStatement() { Location = t.Location, Parent = Parent }; ths.ThrowExpression = Expression(Scope); Expect(Semicolon); ths.EndLocation = t.EndLocation; return ths; case DTokens.Scope: Step(); if (laKind == OpenParenthesis) { var s = new ScopeGuardStatement() { Location = t.Location, Parent = Parent }; Step(); if (Expect(Identifier) && t.Value != null) // exit, failure, success s.GuardedScope = t.Value.ToLower(); else if (IsEOF) s.GuardedScope = DTokens.IncompleteId; Expect(CloseParenthesis); s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } else PushAttribute(new Modifier(DTokens.Scope), false); goto default; case Asm: return ParseAsmStatement(Scope, Parent); case Pragma: var ps = new PragmaStatement { Location = la.Location }; ps.Pragma = _Pragma(); ps.Parent = Parent; ps.ScopedStatement = Statement(Scope: Scope, Parent: ps); ps.EndLocation = t.EndLocation; return ps; case Mixin: if (Peek(1).Kind == OpenParenthesis) { OverPeekBrackets(OpenParenthesis); if (Lexer.CurrentPeekToken.Kind != Semicolon) return ExpressionStatement(Scope, Parent); return MixinDeclaration(Scope, Parent); } else { var tmx = TemplateMixin(Scope, Parent); if (tmx.MixinId == null) return tmx; else return new DeclarationStatement { Declarations = new[] { new NamedTemplateMixinNode(tmx) }, Parent = Parent }; } case Assert: var isStatic = laKind == Static; AssertStatement asS; if (isStatic) { Step(); asS = new StaticAssertStatement { Location = la.Location, Parent = Parent }; } else asS = new AssertStatement() { Location = la.Location, Parent = Parent }; Step(); if (Expect(OpenParenthesis)) { asS.AssertedExpression = Expression(Scope); Expect(CloseParenthesis); Expect(Semicolon); } asS.EndLocation = t.EndLocation; return asS; case Volatile: Step(); var vs = new VolatileStatement() { Location = t.Location, Parent = Parent }; vs.ScopedStatement = Statement(Scope: Scope, Parent: vs); vs.EndLocation = t.EndLocation; return vs; case Import: if(laKind == Static) Step(); // Will be handled in ImportDeclaration return ImportDeclaration(Scope); case Enum: case Alias: case Typedef: var ds = new DeclarationStatement() { Location = la.Location, Parent = Parent, ParentNode = Scope }; ds.Declarations = Declaration(Scope); ds.EndLocation = t.EndLocation; return ds; default: if (IsClassLike(laKind) || (IsBasicType(laKind) && Lexer.CurrentPeekToken.Kind != Dot) || IsModifier(laKind)) goto case Typedef; if (IsAssignExpression()) return ExpressionStatement(Scope, Parent); goto case Typedef; } }
IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null) { if (EmptyAllowed && laKind == Semicolon) { LastParsedObject = null; Step(); return null; } if (BlocksAllowed && laKind == OpenCurlyBrace) return BlockStatement(Scope,Parent); #region LabeledStatement (loc:... goto loc;) if (laKind == Identifier && Lexer.CurrentPeekToken.Kind == Colon) { Step(); var ret = new LabeledStatement() { Location = t.Location, Identifier = t.Value, Parent = Parent }; LastParsedObject = ret; Step(); ret.EndLocation = t.EndLocation; return ret; } #endregion #region IfStatement else if (laKind == (If) || (laKind == Static && Lexer.CurrentPeekToken.Kind == If)) { bool isStatic = laKind == Static; if (isStatic) Step(); Step(); var dbs = new IfStatement() { Location = t.Location, IsStatic = isStatic, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); // IfCondition IfCondition(dbs); // ThenStatement if(Expect(CloseParenthesis)) dbs.ThenStatement = Statement(Scope: Scope, Parent: dbs); // ElseStatement if (laKind == (Else)) { Step(); dbs.ElseStatement = Statement(Scope: Scope, Parent: dbs); } dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region WhileStatement else if (laKind == While) { Step(); var dbs = new WhileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); dbs.Condition = Expression(Scope); Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region DoStatement else if (laKind == (Do)) { Step(); var dbs = new WhileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); Expect(While); Expect(OpenParenthesis); dbs.Condition = Expression(Scope); Expect(CloseParenthesis); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region ForStatement else if (laKind == (For)) { Step(); var dbs = new ForStatement { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); // Initialize if (laKind != Semicolon) dbs.Initialize = Statement(false, Scope: Scope, Parent: dbs); // Against the D language theory, blocks aren't allowed here! else Step(); // Enforce a trailing semi-colon only if there hasn't been an expression (the ; gets already skipped in there) // Expect(Semicolon); // Test if (laKind != (Semicolon)) dbs.Test = Expression(Scope); Expect(Semicolon); // Increment if (laKind != (CloseParenthesis)) dbs.Increment = Expression(Scope); Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region ForeachStatement else if (laKind == Foreach || laKind == Foreach_Reverse) return ForeachStatement(Scope, Parent); #endregion #region [Final] SwitchStatement else if ((laKind == (Final) && Lexer.CurrentPeekToken.Kind == (Switch)) || laKind == (Switch)) { var dbs = new SwitchStatement { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; if (laKind == (Final)) { dbs.IsFinal = true; Step(); } Step(); Expect(OpenParenthesis); dbs.SwitchExpression = Expression(Scope); Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region CaseStatement else if (laKind == (Case)) { Step(); var dbs = new SwitchStatement.CaseStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; dbs.ArgumentList = Expression(Scope); Expect(Colon); // CaseRangeStatement if (laKind == DoubleDot) { Step(); Expect(Case); dbs.LastExpression = AssignExpression(); Expect(Colon); } var sl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: dbs); if (stmt != null) { stmt.Parent = dbs; sl.Add(stmt); } } dbs.ScopeStatementList = sl.ToArray(); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Default else if (laKind == (Default)) { Step(); var dbs = new SwitchStatement.DefaultStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; Expect(Colon); var sl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: dbs); if (stmt != null) { stmt.Parent = dbs; sl.Add(stmt); } } dbs.ScopeStatementList = sl.ToArray(); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Continue | Break else if (laKind == (Continue)) { Step(); var s = new ContinueStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.Identifier = t.Value; } Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } else if (laKind == (Break)) { Step(); var s = new BreakStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.Identifier = t.Value; } Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region Return else if (laKind == (Return)) { Step(); var s = new ReturnStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind != (Semicolon)) s.ReturnExpression = Expression(Scope); Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region Goto else if (laKind == (Goto)) { Step(); var s = new GotoStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.StmtType = GotoStatement.GotoStmtType.Identifier; s.LabelIdentifier = t.Value; } else if (laKind == Default) { Step(); s.StmtType = GotoStatement.GotoStmtType.Default; } else if (laKind == (Case)) { Step(); s.StmtType = GotoStatement.GotoStmtType.Case; if (laKind != (Semicolon)) s.CaseExpression = Expression(Scope); } Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region WithStatement else if (laKind == (With)) { Step(); var dbs = new WithStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); // Symbol dbs.WithExpression = Expression(Scope); Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region SynchronizedStatement else if (laKind == (Synchronized)) { Step(); var dbs = new SynchronizedStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; if (laKind == (OpenParenthesis)) { Step(); dbs.SyncExpression = Expression(Scope); Expect(CloseParenthesis); } dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region TryStatement else if (laKind == (Try)) { Step(); var s = new TryStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ScopedStatement = Statement(Scope: Scope, Parent: s); if (!(laKind == (Catch) || laKind == (Finally))) SemErr(Catch, "At least one catch or a finally block expected!"); var catches = new List<TryStatement.CatchStatement>(); // Catches while (laKind == (Catch)) { Step(); var c = new TryStatement.CatchStatement() { Location = t.Location, Parent = s }; LastParsedObject = c; // CatchParameter if (laKind == (OpenParenthesis)) { Step(); if (laKind == CloseParenthesis) { SemErr(CloseParenthesis, "Catch parameter expected, not ')'"); Step(); } else { var catchVar = new DVariable(); LastParsedObject = catchVar; var tt = la; //TODO? catchVar.Type = BasicType(); if (laKind != Identifier) { la = tt; catchVar.Type = new IdentifierDeclaration("Exception"); } Expect(Identifier); catchVar.Name = t.Value; Expect(CloseParenthesis); c.CatchParameter = catchVar; } } c.ScopedStatement = Statement(Scope: Scope, Parent: c); c.EndLocation = t.EndLocation; catches.Add(c); } if (catches.Count > 0) s.Catches = catches.ToArray(); if (laKind == (Finally)) { Step(); var f = new TryStatement.FinallyStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = f; f.ScopedStatement = Statement(); f.EndLocation = t.EndLocation; s.FinallyStmt = f; } s.EndLocation = t.EndLocation; return s; } #endregion #region ThrowStatement else if (laKind == (Throw)) { Step(); var s = new ThrowStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ThrowExpression = Expression(Scope); Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region ScopeGuardStatement else if (laKind == DTokens.Scope) { Step(); if (laKind == OpenParenthesis) { var s = new ScopeGuardStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; Step(); if (Expect(Identifier) && t.Value != null) // exit, failure, success s.GuardedScope = t.Value.ToLower(); if (Expect(CloseParenthesis)) TrackerVariables.ExpectingIdentifier = false; if (!IsEOF) s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } else PushAttribute(new DAttribute(DTokens.Scope), false); } #endregion #region AsmStmt else if (laKind == Asm) return AsmStatement(Parent); #endregion #region PragmaStatement else if (laKind == (Pragma)) { var s = new PragmaStatement { Location = la.Location }; s.Pragma = _Pragma(); s.Parent = Parent; s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } #endregion #region MixinStatement //TODO: Handle this one in terms of adding it to the node structure else if (laKind == (Mixin)) { if (Peek(1).Kind == OpenParenthesis) return MixinDeclaration(); else return TemplateMixin(); } #endregion #region Conditions if (laKind == Debug) return DebugStatement(Scope, Parent); if (laKind == Version) return VersionStatement(Scope, Parent); #endregion #region (Static) AssertExpression else if (laKind == Assert || (laKind == Static && PK(Assert))) { var s = new AssertStatement() { Location = la.Location, IsStatic = laKind == Static, Parent = Parent }; LastParsedObject = s; if (s.IsStatic) Step(); Step(); if (Expect(OpenParenthesis)) { s.AssertedExpression = Expression(Scope); Expect(CloseParenthesis); Expect(Semicolon); } s.EndLocation = t.EndLocation; return s; } #endregion #region D1: VolatileStatement else if (laKind == Volatile) { Step(); var s = new VolatileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } #endregion // ImportDeclaration else if (laKind == Import) return ImportDeclaration(); else if (!(ClassLike[laKind] || BasicTypes[laKind] || laKind == Enum || Modifiers[laKind] || laKind == PropertyAttribute || laKind == Alias || laKind == Typedef) && IsAssignExpression()) { var s = new ExpressionStatement() { Location = la.Location, Parent = Parent }; if (!IsEOF) LastParsedObject = s; // a==b, a=9; is possible -> Expressions can be there, not only single AssignExpressions! s.Expression = Expression(Scope); if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } else { var s = new DeclarationStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = s; s.Declarations = Declaration(Scope); s.EndLocation = t.EndLocation; return s; } }
public IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null) { if (EmptyAllowed && laKind == Semicolon) { LastParsedObject = null; Step(); return null; } if (BlocksAllowed && laKind == OpenCurlyBrace) return BlockStatement(Scope,Parent); #region LabeledStatement (loc:... goto loc;) if (laKind == Identifier && Lexer.CurrentPeekToken.Kind == Colon) { Step(); var ret = new LabeledStatement() { Location = t.Location, Identifier = t.Value, Parent = Parent }; LastParsedObject = null; Step(); ret.EndLocation = t.EndLocation; return ret; } #endregion #region IfStatement else if (laKind == (If)) { Step(); var dbs = new IfStatement{ Location = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); // IfCondition IfCondition(dbs); // ThenStatement if(Expect(CloseParenthesis)) dbs.ThenStatement = Statement(Scope: Scope, Parent: dbs); // ElseStatement if (laKind == (Else)) { Step(); dbs.ElseStatement = Statement(Scope: Scope, Parent: dbs); } if(t != null) dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Conditions else if ((laKind == Static && Lexer.CurrentPeekToken.Kind == If) || laKind == Version || laKind == Debug) return StmtCondition(Parent, Scope); #endregion #region WhileStatement else if (laKind == While) { Step(); var dbs = new WhileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); dbs.Condition = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) { dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; } return dbs; } #endregion #region DoStatement else if (laKind == (Do)) { Step(); var dbs = new WhileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; if(!IsEOF) dbs.ScopedStatement = Statement(true, false, Scope, dbs); if(Expect(While) && Expect(OpenParenthesis)) { dbs.Condition = Expression(Scope); Expect(CloseParenthesis); if (Expect(Semicolon)) LastParsedObject = null; dbs.EndLocation = t.EndLocation; } return dbs; } #endregion #region ForStatement else if (laKind == (For)) return ForStatement(Scope, Parent); #endregion #region ForeachStatement else if (laKind == Foreach || laKind == Foreach_Reverse) return ForeachStatement(Scope, Parent); #endregion #region [Final] SwitchStatement else if ((laKind == (Final) && Lexer.CurrentPeekToken.Kind == (Switch)) || laKind == (Switch)) { var dbs = new SwitchStatement { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; if (laKind == (Final)) { dbs.IsFinal = true; Step(); } Step(); Expect(OpenParenthesis); dbs.SwitchExpression = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region CaseStatement else if (laKind == (Case)) { Step(); var dbs = new SwitchStatement.CaseStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; dbs.ArgumentList = Expression(Scope); if (Expect(Colon)) LastParsedObject = null; // CaseRangeStatement if (laKind == DoubleDot) { Step(); Expect(Case); dbs.LastExpression = AssignExpression(); if (Expect(Colon)) LastParsedObject = null; } var sl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: dbs); if (stmt != null) { stmt.Parent = dbs; sl.Add(stmt); } } dbs.ScopeStatementList = sl.ToArray(); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Default else if (laKind == (Default)) { Step(); var dbs = new SwitchStatement.DefaultStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; Expect(Colon); var sl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: dbs); if (stmt != null) { stmt.Parent = dbs; sl.Add(stmt); } } dbs.ScopeStatementList = sl.ToArray(); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Continue | Break else if (laKind == (Continue)) { Step(); var s = new ContinueStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.Identifier = t.Value; } if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } else if (laKind == (Break)) { Step(); var s = new BreakStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.Identifier = t.Value; } if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } #endregion #region Return else if (laKind == (Return)) { Step(); var s = new ReturnStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind != (Semicolon)) s.ReturnExpression = Expression(Scope); if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } #endregion #region Goto else if (laKind == (Goto)) { Step(); var s = new GotoStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.StmtType = GotoStatement.GotoStmtType.Identifier; s.LabelIdentifier = t.Value; } else if (laKind == Default) { Step(); s.StmtType = GotoStatement.GotoStmtType.Default; } else if (laKind == (Case)) { Step(); s.StmtType = GotoStatement.GotoStmtType.Case; if (laKind != (Semicolon)) s.CaseExpression = Expression(Scope); } if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } #endregion #region WithStatement else if (laKind == (With)) { Step(); var dbs = new WithStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; if(Expect(OpenParenthesis)) { // Symbol dbs.WithExpression = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); } dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region SynchronizedStatement else if (laKind == (Synchronized)) { Step(); var dbs = new SynchronizedStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; if (laKind == (OpenParenthesis)) { Step(); dbs.SyncExpression = Expression(Scope); Expect(CloseParenthesis); } if(!IsEOF) dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region TryStatement else if (laKind == (Try)) { Step(); var s = new TryStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ScopedStatement = Statement(Scope: Scope, Parent: s); if (!(laKind == (Catch) || laKind == (Finally))) SemErr(Catch, "At least one catch or a finally block expected!"); var catches = new List<TryStatement.CatchStatement>(); // Catches while (laKind == (Catch)) { Step(); var c = new TryStatement.CatchStatement() { Location = t.Location, Parent = s }; LastParsedObject = c; // CatchParameter if (laKind == (OpenParenthesis)) { Step(); if (laKind == CloseParenthesis || IsEOF) { SemErr(CloseParenthesis, "Catch parameter expected, not ')'"); Step(); } else { var catchVar = new DVariable { Parent = Scope, Location = t.Location }; LastParsedObject = catchVar; Lexer.PushLookAheadBackup(); catchVar.Type = BasicType(); if (laKind == CloseParenthesis) { Lexer.RestoreLookAheadBackup(); catchVar.Type = new IdentifierDeclaration("Exception"); } else Lexer.PopLookAheadBackup(); if (Expect(Identifier)) { catchVar.Name = t.Value; catchVar.NameLocation = t.Location; Expect(CloseParenthesis); } else if(IsEOF) ExpectingNodeName = true; catchVar.EndLocation = t.EndLocation; c.CatchParameter = catchVar; } } if(!IsEOF) c.ScopedStatement = Statement(Scope: Scope, Parent: c); c.EndLocation = t.EndLocation; catches.Add(c); } if (catches.Count > 0) s.Catches = catches.ToArray(); if (laKind == (Finally)) { Step(); var f = new TryStatement.FinallyStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = f; f.ScopedStatement = Statement(); f.EndLocation = t.EndLocation; s.FinallyStmt = f; } s.EndLocation = t.EndLocation; return s; } #endregion #region ThrowStatement else if (laKind == (Throw)) { Step(); var s = new ThrowStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ThrowExpression = Expression(Scope); Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region ScopeGuardStatement else if (laKind == DTokens.Scope) { Step(); if (laKind == OpenParenthesis) { var s = new ScopeGuardStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; Step(); if (Expect(Identifier) && t.Value != null) // exit, failure, success s.GuardedScope = t.Value.ToLower(); if (Expect(CloseParenthesis)) TrackerVariables.ExpectingIdentifier = false; if (!IsEOF) s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } else PushAttribute(new Modifier(DTokens.Scope), false); } #endregion #region AsmStmt else if (laKind == Asm) return AsmStatement(Parent); #endregion #region PragmaStatement else if (laKind == (Pragma)) { var s = new PragmaStatement { Location = la.Location }; s.Pragma = _Pragma(); s.Parent = Parent; s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } #endregion #region MixinStatement else if (laKind == (Mixin)) { if (Peek(1).Kind == OpenParenthesis) { OverPeekBrackets(OpenParenthesis); if (Lexer.CurrentPeekToken.Kind != Semicolon) return ExpressionStatement(Scope, Parent); return MixinDeclaration(Scope, Parent); } else { var tmx = TemplateMixin(Scope, Parent); if (tmx.MixinId == null) return tmx; else return new DeclarationStatement { Declarations = new[] { new NamedTemplateMixinNode(tmx) }, Parent = Parent }; } } #endregion #region (Static) AssertExpression else if (laKind == Assert || (laKind == Static && Lexer.CurrentPeekToken.Kind == Assert)) { var isStatic = laKind == Static; AssertStatement s; if (isStatic) { Step(); s = new StaticAssertStatement { Location = la.Location, Parent = Parent }; } else s = new AssertStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = s; Step(); if (Expect(OpenParenthesis)) { s.AssertedExpression = Expression(Scope); if(Expect(CloseParenthesis) && Expect(Semicolon)) LastParsedObject = null; } s.EndLocation = t.EndLocation; return s; } #endregion #region D1: VolatileStatement else if (laKind == Volatile) { Step(); var s = new VolatileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } #endregion // ImportDeclaration else if (laKind == Import || (laKind == Static && Lexer.CurrentPeekToken.Kind == Import)) { if(laKind == Static) Step(); // Will be handled in ImportDeclaration return ImportDeclaration(Scope); } else if (!(ClassLike[laKind] || BasicTypes[laKind] || laKind == Enum || Modifiers[laKind] || IsAtAttribute || laKind == Alias || laKind == Typedef) && IsAssignExpression()) return ExpressionStatement(Scope, Parent); var ds = new DeclarationStatement() { Location = la.Location, Parent = Parent, ParentNode = Scope }; LastParsedObject = ds; ds.Declarations = Declaration(Scope); ds.EndLocation = t.EndLocation; return ds; }
public void Visit(SwitchStatement.CaseStatement caseStatement) { }