// Parse the loop block and ignore its result
int Compiler::ParseOptimizeBlock(int arguments)
{
	if (!ThisTokenIsBinary('['))
	{
		CompileError(CErrExpectLiteralBlock);
		return 0;
	}

	int nTextStart = ThisTokenRange().m_start;

	_ASSERTE(IsInOptimizedBlock());

	// Parse the arguments - note we parse them anyway, regardless of whether they are wanted, 
	// and subsequently complain if there are too many
	NextToken();
	int argument = 0;
	while (m_ok && ThisTokenIsSpecial(':') )
	{
		if (NextToken()==NameConst)
		{
			if (argument < arguments)
				RenameTemporary(argument, ThisTokenText(), ThisTokenRange());
			else
				AddTemporary(ThisTokenText(), ThisTokenRange(), true);
			argument++;
			NextToken();
		}
		else
			CompileError(CErrExpectVariable);
	}

	int argBar = -1;
	if (m_ok && argument > 0)
	{
		if (ThisTokenIsBinary(TEMPSDELIMITER))
		{
			argBar = ThisTokenRange().m_stop;
			NextToken();
		}
		else
			m_ok = false;
	}

	int nBlockTemps = 0;
	if (m_ok)
	{
		// Temporarily commented out for interim release
		ParseTemporaries();
		
		ParseBlockStatements();
		if (m_ok && ThisToken() != CloseSquare)
			CompileError(TEXTRANGE(nTextStart, LastTokenRange().m_stop), CErrBlockNotClosed);
	}
	
	if (m_ok && argument != arguments)
		CompileError(TEXTRANGE(nTextStart, argBar < 0 ? ThisTokenRange().m_stop : argBar), CErrIncorrectBlockArgCount);

	return nBlockTemps;
}
int Compiler::ParseIfNotNilBlock()
{
	if (!ThisTokenIsBinary('['))
	{
		CompileError(CErrExpectLiteralBlock);
		return 0;
	}

	PushOptimizedScope();

	// We now allow either zero or one arguments to the ifNotNil: block
	//ParseOptimizeBlock(1);

	int nTextStart = ThisTokenRange().m_start;

	_ASSERTE(IsInOptimizedBlock());

	// Generate the body code for an optimized block
	NextToken();
	int argc = 0;
	while (m_ok && ThisTokenIsSpecial(':'))
	{
		if (NextToken() == NameConst)
		{
			argc++;
			CheckTemporaryName(ThisTokenText(), ThisTokenRange(), true);
			if (m_ok)
			{
				TempVarRef* pValueTempRef = AddOptimizedTemp(ThisTokenText(), ThisTokenRange());
				GenPopAndStoreTemp(pValueTempRef);
			}
			NextToken();
		}
		else
			CompileError(CErrExpectVariable);
	}

	switch (argc)
	{
	case 0:
		// Zero arg block, we don't need the implicit arg so just discard it
		GenPopStack();
		break;

	case 1:
		m_ok = m_ok && ThisTokenIsBinary(TEMPSDELIMITER);
		NextToken();
		break;

	default:
		CompileError(TEXTRANGE(nTextStart, ThisTokenRange().m_stop), CErrTooManyIfNotNilBlockArgs);
		break;
	}
	
	int nBlockTemps = 0;
	if (m_ok)
	{
		// Temporarily commented out for interim release
		ParseTemporaries();
		
		ParseBlockStatements();
		if (m_ok && ThisToken() != CloseSquare)
			CompileError(TEXTRANGE(nTextStart, LastTokenRange().m_stop), CErrBlockNotClosed);
	}

	PopOptimizedScope(ThisTokenRange().m_stop);
	NextToken();

	return argc;
}