use crate::{
state::ScopeContext,
syntax::utilities::{CLOSE_BRACE, OPEN_BRACE},
};
use super::*;
impl<'input, D: Diagnostics, C: ConcreteSyntaxTreeBuilder> ParserState<'input, D, C> {
pub(super) fn parse_while_loop(&mut self) {
self.parse_in_context(ScopeContext::Loop, |state| {
state.start_node(SyntaxKind::WhileLoop);
state.parse_token(SyntaxKind::Keyword);
state.skip_trivia();
state.parse_condition_and_body();
state.finish_node();
})
}
}
impl<'input, D: Diagnostics, C: ConcreteSyntaxTreeBuilder> ParserState<'input, D, C> {
pub(super) fn parse_for_loop_with_missing_open(&mut self) {
self.parse_for_loop();
}
pub(super) fn parse_for_loop(&mut self) {
self.parse_in_context(ScopeContext::Loop, |state| {
state.start_node(SyntaxKind::ForLoop);
state.parse_delimited_for_loop();
state.skip_trivia();
state.parse_expression_followed_by_braces();
state.finish_node();
});
}
fn parse_delimited_for_loop(&mut self) {
const OPEN_FOR: TokenKind = TokenKind::ControlFlow(ControlFlowKind::ForLoopOpen);
const CLOSE_FOR: TokenKind = TokenKind::ControlFlow(ControlFlowKind::ForLoopClose);
self.parse_delimited_aggressive(
SyntaxKind::DelimitedRange,
(OPEN_FOR, SyntaxKind::ForIterOpen),
(CLOSE_FOR, SyntaxKind::ForIterClose),
|state| {
state.parse_repeated_expression(|k| {
k.is(&CLOSE_FOR) || k.is(&OPEN_BRACE) || k.is(&CLOSE_BRACE)
});
},
);
}
}
mod test {
#[test]
fn test_while() {
crate::test::create_parsing_test("loop_while/*.skull", |state| {
state.parse_while_loop();
});
}
#[test]
fn test_for_loop() {
crate::test::create_parsing_test("loop_for/*.skull", |state| {
state.parse_for_loop();
});
}
}