Esempio n. 1
0
		} // ParseFunction
	
	
	// Parse a Block.  The stream should be positioned at the "{" token.
	private StmtFrag ParseBlock(FunctionInfo info)
		{
		StmtFrag frag = gen.NewStmtFrag(tok.Prev().loc);
		
		tok.MatchOp("{");
		while (!tok.TryMatchOp("}"))
			frag.Append(ParseStatement(info));
		
		return frag;
		} // ParseBlock
Esempio n. 2
0
		} // 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
Esempio n. 3
0
		} // 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
Esempio n. 4
0
		} // MatchLabelSet
	
	
	// Parse a for statement.  The caller should already have matched
	// the "for" keyword.
	private StmtFrag ParseForStatement(FunctionInfo info, StringCollection labels)
		{
		LoopInfo loopInfo = gen.NewLoopInfo(curCGFuncInfo, tok.Prev().loc, labels);
		loops.Push(loopInfo);
		
		// HACK snewman 8/13/01: need to review this section against the
		// specific semantics for "for" statements, and especially for/in
		// statements, in section 12.6 of the ECMA spec.
		
		tok.MatchOp("(");
		
		bool isIn;			  // True for for/in, false otherwise
		StmtFrag init=null;   // Initializer; used for both types of loop
		ExprFrag cond=null;   // Condition; only used for non-in loops
		ExprFrag update=null; // Update step; only used for non-in loops
		ExprFrag inLHS=null;  // LHS expression where in loops put prop names
		ExprFrag inRHS=null;  // RHS object that in loops iterate over
		if (tok.TryMatchKeyword("var"))
			{
			string varName;
			SrcLoc varLoc;
			init = ParseVariableDeclaration(info, false, out varName, out varLoc);
			
			isIn = tok.TryMatchKeyword("in");
			if (isIn)
				inLHS = gen.IdentifierExpr( varLoc, varName, info,
											CloneStack(withs) );
			else
				{
				while (tok.TryMatchOp(","))
					init.Append(ParseVariableDeclaration( info, false, out varName,
														  out varLoc ));
				}
			
			}
		else
			{
			if (!tok.PeekOp(";"))
				{
				ExprFrag initExpr = ParseExpression(info, false, 99);
				isIn = tok.TryMatchKeyword("in");
				
				if (isIn)
					inLHS = initExpr;
				else
					init = gen.ExpressionStmt(initExpr);
				
				}
			else
				isIn = false;
			
			}
		
		if (isIn)
			inRHS = ParseExpression(info, true);
		else
			{
			tok.MatchOp(";");
			if (!tok.PeekOp(";"))
				cond = ParseExpression(info, true);
			
			tok.MatchOp(";");
			if (!tok.PeekOp(")"))
				update = ParseExpression(info, true);
			}
		
		tok.MatchOp(")");
		
		StmtFrag body = ParseStatement(info);
		
		LoopInfo temp = (LoopInfo) loops.Pop();
		Trace.Assert(temp == loopInfo);
		
		if (isIn)
			return gen.ForIn(loopInfo, init, inLHS, inRHS, body);
		else
			return gen.For(loopInfo, init, cond, update, body);
		
		} // ParseForStatement