} // Phase2Parser constructor // Parse a program from the input stream, given the FunctionInfo // object for the program's root scope. public void ParseProgram(FunctionInfo info) { gen.EmitProgramPrefix(); CGFuncInfo cgFuncInfo = gen.NewFuncInfo(info); curCGFuncInfo = cgFuncInfo; gen.EmitMainFunction(ParseSourceElements(info, cgFuncInfo)); Trace.Assert(curCGFuncInfo == cgFuncInfo); Trace.Assert(loops.Count == 0); Trace.Assert(withs.Count == 0); curCGFuncInfo = null; gen.EmitProgramSuffix(); } // ParseProgram
} // ParseProgram // Parse a SourceElements (i.e. the main program, or a function body) // and return the generated code. private StmtFrag ParseSourceElements( FunctionInfo info, CGFuncInfo cgFuncInfo ) { SrcLoc loc; loc.lineNum = 1; loc.colNum = 1; loc.absPosition = 0; loc.len = 1; StmtFrag frag = gen.NewStmtFrag(loc); while (!tok.atEnd && !tok.PeekOp("}")) if (tok.TryMatchKeyword("function")) ParseFunction(info.GetNextChild(), false); else frag.Append(ParseStatement(info)); return frag; } // ParseSourceElements
} // ParseSourceElements // Parse a FunctionDeclaration or FunctionExpression. The "function" // keyword should already have been matched. private void ParseFunction(FunctionInfo info, bool isExpression) { // Save the current loop and with stacks. OPTIMIZATION: don't need to // do this if the stack was empty. Stack savedLoops = loops; loops = new Stack(); Stack savedWiths = withs; withs = new Stack(); CGFuncInfo savedCGFuncInfo = curCGFuncInfo; CGFuncInfo cgFuncInfo = gen.NewFuncInfo(info); curCGFuncInfo = cgFuncInfo; string functionName = null; if (isExpression) tok.TryMatchID(out functionName); else functionName = tok.MatchID(); // Scan to the end of the parameter list. We don't bother parsing // it in detail, as this was done during the first phase. while (!tok.TryMatchOp(")")) tok.Match(); tok.MatchOp("{"); StmtFrag body = ParseSourceElements(info, cgFuncInfo); tok.MatchOp("}"); gen.EmitFunction(info, body); Trace.Assert(loops.Count == 0); Trace.Assert(withs.Count == 0); Trace.Assert(curCGFuncInfo == cgFuncInfo); loops = savedLoops; withs = savedWiths; curCGFuncInfo = savedCGFuncInfo; } // ParseFunction
} // NewLabeledStmtInfo // Return a new WithInfo object. public WithInfo NewWithInfo(CGFuncInfo cgFuncInfo, SrcLoc loc) { return new CSharpWithInfo((CSharpGenFuncInfo)cgFuncInfo, loc); } // NewWithInfo
} // NewLoopInfo // Return a new LoopInfo object for a labeled non-iteration statement // with the given label set. isSwitch should be true if the statement // was a switch statement; in this case, if the statement had no labels, // the labels parameter can be null. public LoopInfo NewLabeledStmtInfo( CGFuncInfo cgFuncInfo, SrcLoc loc, StringCollection labels, bool isSwitch ) { Trace.Assert(labels != null || isSwitch); return new CSharpLoopInfo( (CSharpGenFuncInfo)cgFuncInfo, loc, labels, false, isSwitch ); } // NewLabeledStmtInfo
} // NewStmtFrag // Return a new LoopInfo object for an iteratiion statement with the // given label set. The labels parameter can be null if there were no // labels. public LoopInfo NewLoopInfo( CGFuncInfo cgFuncInfo, SrcLoc loc, StringCollection labels ) { return new CSharpLoopInfo( (CSharpGenFuncInfo)cgFuncInfo, loc, labels, true, false ); } // NewLoopInfo