pub fn statement(tokens: ParserIter) -> Result<Option<Stmt>, ParseError> {
	let consumed_token = match_then_consume!(
		tokens,
		TokenType::If
			| TokenType::For
			| TokenType::Print
			| TokenType::Break
			| TokenType::Class
			| TokenType::Return
			| TokenType::Continue
			| TokenType::LeftBrace
			| TokenType::Semicolon
	);

	let token_type = consumed_token.as_ref().map(|ct| &ct.token_type);

	match token_type {
		Some(TokenType::If) => if_statement(tokens),
		Some(TokenType::For) => for_statement(tokens),
		Some(TokenType::Print) => print_statement(tokens),
		Some(TokenType::Class) => class_statement(tokens),
		Some(TokenType::LeftBrace) => block_statement(tokens),
		Some(TokenType::Break) => unsafe {
			break_statement(tokens, consumed_token.unwrap_unchecked())
		},
		Some(TokenType::Return) => unsafe {
			return_statement(tokens, consumed_token.unwrap_unchecked())
		},
		Some(TokenType::Continue) => unsafe {
			continue_statement(tokens, consumed_token.unwrap_unchecked())
		},

		// We allow trails of semicolons and treat them as empty statements
		Some(TokenType::Semicolon) => Ok(None),

		_ => expression_statement(tokens),
	}
}
/// Statement can not fail and produce None for a statement, because it wouldn't
/// be significant (e.g. lone `;`)
Statement can not fail and produce None for a statement, because it wouldn't
be significant
Statement can not fail and produce None for a statement because it wouldn ' t be significant
pub fn statement(tokens: ParserIter) -> Result<Option<Stmt>, ParseError> {
	let consumed_token = match_then_consume!(
		tokens,
		TokenType::If
			| TokenType::For
			| TokenType::Print
			| TokenType::Break
			| TokenType::Class
			| TokenType::Return
			| TokenType::Continue
			| TokenType::LeftBrace
			| TokenType::Semicolon
	);
	let token_type = consumed_token.as_ref().map(|ct| &ct.token_type);
	match token_type {
		Some(TokenType::If) => if_statement(tokens),
		Some(TokenType::For) => for_statement(tokens),
		Some(TokenType::Print) => print_statement(tokens),
		Some(TokenType::Class) => class_statement(tokens),
		Some(TokenType::LeftBrace) => block_statement(tokens),
		Some(TokenType::Break) => unsafe {
			break_statement(tokens, consumed_token.unwrap_unchecked())
		},
		Some(TokenType::Return) => unsafe {
			return_statement(tokens, consumed_token.unwrap_unchecked())
		},
		Some(TokenType::Continue) => unsafe {
			continue_statement(tokens, consumed_token.unwrap_unchecked())
		},
		// We allow trails of semicolons and treat them as empty statements
		Some(TokenType::Semicolon) => Ok(None),
		_ => expression_statement(tokens),
	}
}
pub fn statement ( tokens : ParserIter ) -> Result < Option < Stmt > , ParseError > { let consumed_token = match_then_consume ! ( tokens TokenType If TokenType For TokenType Print TokenType Break TokenType Class TokenType Return TokenType Continue TokenType LeftBrace TokenType Semicolon ) ; let token_type = consumed_token . as_ref ( ) . map ( | ct | & ct . token_type ) ; match token_type { Some ( TokenType :: If ) => if_statement ( tokens ) , Some ( TokenType :: For ) => for_statement ( tokens ) , Some ( TokenType :: Print ) => print_statement ( tokens ) , Some ( TokenType :: Class ) => class_statement ( tokens ) , Some ( TokenType :: LeftBrace ) => block_statement ( tokens ) , Some ( TokenType :: Break ) => unsafe { break_statement ( tokens , consumed_token . unwrap_unchecked ( ) ) } , Some ( TokenType :: Return ) => unsafe { return_statement ( tokens , consumed_token . unwrap_unchecked ( ) ) } , Some ( TokenType :: Continue ) => unsafe { continue_statement ( tokens , consumed_token . unwrap_unchecked ( ) ) } , // We allow trails of semicolons and treat them as empty statements Some ( TokenType :: Semicolon ) => Ok ( None ) , _ => expression_statement ( tokens ) , } }
Statement can not fail and produce None for a statement, because it wouldn't
be significant (e.g.
Statement can not fail and produce None for a statement because it wouldn ' t be significant ( e . g .
tokens
ParserIter
tokens
ParserIter