use crate::parser::ast::*;
use crate::parser::error::{Expected, ParseResult};
use crate::parser::state::Parser;
use crate::parser::token::Keyword;
pub fn parse_if(parser: &mut Parser) -> ParseResult<Statement> {
let condition = crate::parser::parse::expressions::parse_expr(parser)?;
let then_stmt = crate::parser::parse::parse_statement(parser)?;
let else_stmt = if let Some(Token::Keyword(Keyword::Else)) = parser.peek() {
let _ = parser.next();
Some(crate::parser::parse::parse_statement(parser)?)
} else {
None
};
Ok(Statement::Procedural(ProceduralStatement::If {
condition,
then_stmt: Box::new(then_stmt),
else_stmt: else_stmt.map(Box::new),
}))
}
pub fn parse_begin_end(parser: &mut Parser) -> ParseResult<Statement> {
let mut statements = Vec::new();
loop {
while matches!(parser.peek(), Some(Token::Semicolon)) {
let _ = parser.next();
}
if let Some(Token::Keyword(Keyword::End)) = parser.peek() {
let _ = parser.next();
break;
}
if parser.is_empty() {
return parser.backtrack(Expected::Description("statement"));
}
statements.push(crate::parser::parse::parse_statement(parser)?);
}
Ok(Statement::Procedural(ProceduralStatement::BeginEnd(
statements,
)))
}
pub fn parse_try_catch(parser: &mut Parser) -> ParseResult<Statement> {
let mut try_body = Vec::new();
loop {
while matches!(parser.peek(), Some(Token::Semicolon)) {
let _ = parser.next();
}
if matches!(parser.peek(), Some(Token::Keyword(Keyword::End)))
&& matches!(parser.peek_at(1), Some(Token::Keyword(Keyword::Try)))
{
let _ = parser.next();
let _ = parser.next();
break;
}
try_body.push(crate::parser::parse::parse_statement(parser)?);
}
parser.expect_keyword(Keyword::Begin)?;
parser.expect_keyword(Keyword::Catch)?;
let mut catch_body = Vec::new();
loop {
while matches!(parser.peek(), Some(Token::Semicolon)) {
let _ = parser.next();
}
if matches!(parser.peek(), Some(Token::Keyword(Keyword::End)))
&& matches!(parser.peek_at(1), Some(Token::Keyword(Keyword::Catch)))
{
let _ = parser.next();
let _ = parser.next();
break;
}
catch_body.push(crate::parser::parse::parse_statement(parser)?);
}
Ok(Statement::Procedural(ProceduralStatement::TryCatch {
try_body,
catch_body,
}))
}