} // Throw // Return a with statement. public StmtFrag With(WithInfo withInfo, ExprFrag value, StmtFrag body) { CSharpWithInfo csWithInfo = (CSharpWithInfo)withInfo; CSharpStmtFrag frag = new CSharpStmtFrag(csWithInfo.loc); frag.Append( "object withTemp_{0} = ({1});", csWithInfo.index+1, ((CSharpExprFrag)value).GenerateRHS() ); frag.Append(body); return frag; } // With
} // Switch // Return a try...catch, try...finally, or try...catch...finally // statement. If there was no "catch" clause, then catchVar, catchWithInfo, // and catchBody will be null. If there was no "finally" clause, then // finallyBody will be null. These parameters can't all be null (i.e. // at least one of the "catch" and "finally" clauses must have been // present). public StmtFrag TryCatchFinally( SrcLoc loc, StmtFrag tryBody, string catchVar, WithInfo catchWithInfo, StmtFrag catchBody, StmtFrag finallyBody ) { CSharpStmtFrag frag = new CSharpStmtFrag(loc); frag.Append("try"); frag.AppendIndentedBody(tryBody); if (catchBody != null) { CSharpWithInfo csWithInfo = (CSharpWithInfo)catchWithInfo; frag.Append("catch (Exception catchTemp_{0})", csWithInfo.index+1); frag.Indent(); frag.Append("{"); frag.Append( "JObject withTemp_{0} = Support.CreateCatchScope(catchTemp_{0}, \"{1}\");", csWithInfo.index+1, catchVar ); frag.Append(catchBody); frag.Append("}"); frag.Outdent(); } if (finallyBody != null) { frag.Append("finally"); frag.AppendIndentedBody(finallyBody); } return frag; } // TryCatchFinally
} // ParseForStatement // Parse a Statement. private StmtFrag ParseStatement(FunctionInfo info) { StringCollection labels = MatchLabelSet(); if (tok.TryMatchKeyword("do")) { LoopInfo loopInfo = gen.NewLoopInfo( curCGFuncInfo, tok.Prev().loc, labels ); loops.Push(loopInfo); StmtFrag body = ParseStatement(info); tok.MatchKeyword("while"); tok.MatchOp("("); ExprFrag condition = ParseExpression(info, true); tok.MatchOp(")"); tok.MatchOp(";"); LoopInfo temp = (LoopInfo) loops.Pop(); Trace.Assert(temp == loopInfo); return gen.DoWhile(loopInfo, body, condition); } else if (tok.TryMatchKeyword("while")) { LoopInfo loopInfo = gen.NewLoopInfo( curCGFuncInfo, tok.Prev().loc, labels ); loops.Push(loopInfo); tok.MatchOp("("); ExprFrag condition = ParseExpression(info, true); tok.MatchOp(")"); StmtFrag body = ParseStatement(info); LoopInfo temp = (LoopInfo) loops.Pop(); Trace.Assert(temp == loopInfo); return gen.WhileDo(loopInfo, condition, body); } else if (tok.TryMatchKeyword("for")) return ParseForStatement(info, labels); else { bool isSwitch = tok.PeekKeyword("switch"); LoopInfo labelInfo = null; if (labels != null || isSwitch) { labelInfo = gen.NewLabeledStmtInfo( curCGFuncInfo, tok.Prev().loc, labels, isSwitch ); loops.Push(labelInfo); } StmtFrag stmt; if (tok.PeekOp("{")) stmt = ParseBlock(info); else if (tok.TryMatchKeyword("var")) { stmt = gen.NewStmtFrag(tok.Prev().loc); do { string varName; SrcLoc varLoc; stmt.Append(ParseVariableDeclaration( info, true, out varName, out varLoc )); } while (tok.TryMatchOp(",")); tok.MatchOp(";"); } else if (tok.TryMatchOp(";")) { // EmptyStatement stmt = gen.NewStmtFrag(tok.Prev().loc); } else if (tok.TryMatchKeyword("if")) { SrcLoc ifLoc = tok.Prev().loc; tok.MatchOp("("); ExprFrag condition = ParseExpression(info, true); tok.MatchOp(")"); StmtFrag ifClause = ParseStatement(info); StmtFrag elseClause = null; if (tok.TryMatchKeyword("else")) elseClause = ParseStatement(info); stmt = gen.IfThenElse(ifLoc, condition, ifClause, elseClause); } else if (tok.TryMatchKeyword("continue")) { SrcLoc continueLoc = tok.Prev().loc; // HACK snewman 8/7/01: the grammar (ContinueStatement) specifies // "no LineTerminator here". string id; tok.TryMatchID(out id); tok.MatchOp(";"); stmt = gen.Continue(continueLoc, id, CloneStack(loops)); } else if (tok.TryMatchKeyword("break")) { SrcLoc breakLoc = tok.Prev().loc; // HACK snewman 8/7/01: the grammar (BreakStatement) specifies // "no LineTerminator here". string id; tok.TryMatchID(out id); tok.MatchOp(";"); stmt = gen.Break(breakLoc, id, CloneStack(loops)); } else if (tok.TryMatchKeyword("return")) { SrcLoc returnLoc = tok.Prev().loc; // HACK snewman 8/7/01: the grammar (ReturnStatement) specifies // "no LineTerminator here". if (tok.TryMatchOp(";")) stmt = gen.Return(returnLoc, null); else { ExprFrag value = ParseExpression(info, true); tok.MatchOp(";"); stmt = gen.Return(returnLoc, value); } } else if (tok.TryMatchKeyword("with")) { SrcLoc withLoc = tok.Prev().loc; tok.MatchOp("("); ExprFrag value = ParseExpression(info, true); tok.MatchOp(")"); WithInfo withInfo = gen.NewWithInfo(curCGFuncInfo, withLoc); withs.Push(withInfo); StmtFrag body = ParseStatement(info); WithInfo temp = (WithInfo) withs.Pop(); Trace.Assert(temp == withInfo); stmt = gen.With(withInfo, value, body); } else if (tok.TryMatchKeyword("switch")) { SrcLoc switchLoc = tok.Prev().loc; SwitchInfo switchInfo = gen.NewSwitchInfo(); tok.MatchOp("("); ExprFrag switchValue = ParseExpression(info, true); tok.MatchOp(")"); tok.MatchOp("{"); while (!tok.TryMatchOp("}")) { ExprFrag caseValue; if (tok.TryMatchKeyword("default")) caseValue = null; else { tok.MatchKeyword("case"); caseValue = ParseExpression(info, true); } StmtFrag clauseStmt = null; tok.MatchOp(":"); while ( !tok.PeekOp("}") && !tok.PeekKeyword("case") && !tok.PeekKeyword("default") ) { StmtFrag tempStmt = ParseStatement(info); if (clauseStmt == null) clauseStmt = tempStmt; else clauseStmt.Append(tempStmt); } switchInfo.AddCase(caseValue, clauseStmt); } stmt = gen.Switch(switchLoc, switchValue, switchInfo); } else if (tok.TryMatchKeyword("throw")) { SrcLoc throwLoc = tok.Prev().loc; // HACK snewman 8/7/01: the grammar (ThrowStatement) specifies // "no LineTerminator here". ExprFrag value = ParseExpression(info, true); tok.MatchOp(";"); stmt = gen.Throw(throwLoc, value); } else if (tok.TryMatchKeyword("try")) { SrcLoc tryLoc = tok.Prev().loc; StmtFrag tryBody = ParseBlock(info); String catchVar = null; WithInfo catchWithInfo = null; StmtFrag catchBody = null; StmtFrag finallyBody = null; if (tok.TryMatchKeyword("catch")) { SrcLoc catchLoc = tok.Prev().loc; tok.MatchOp("("); catchVar = tok.MatchID(); tok.MatchOp(")"); catchWithInfo = gen.NewWithInfo(curCGFuncInfo, catchLoc); withs.Push(catchWithInfo); catchBody = ParseBlock(info); WithInfo temp = (WithInfo) withs.Pop(); Trace.Assert(temp == catchWithInfo); } if (tok.TryMatchKeyword("finally")) finallyBody = ParseBlock(info); stmt = gen.TryCatchFinally( tryLoc, tryBody, catchVar, catchWithInfo, catchBody, finallyBody ); } else { ExprFrag expr = ParseExpression(info, true); tok.MatchOp(";"); stmt = gen.ExpressionStmt(expr); } if (labelInfo != null) { LoopInfo temp2 = (LoopInfo) loops.Pop(); Trace.Assert(temp2 == labelInfo); stmt = gen.LabeledStmt(labelInfo, stmt); } return stmt; } } // ParseStatement