devalang_core/core/parser/driver/
block.rs

1use crate::core::lexer::token::Token;
2use crate::core::lexer::token::TokenKind;
3use crate::core::store::global::GlobalStore;
4
5pub fn collect_block_tokens(
6    parser: &mut crate::core::parser::driver::parser::Parser,
7    base_indent: usize,
8) -> Vec<Token> {
9    let mut tokens = Vec::new();
10
11    while let Some(tok) = parser.peek() {
12        if tok.indent <= base_indent && tok.kind != TokenKind::Newline {
13            break;
14        }
15        if let Some(t) = parser.advance() {
16            tokens.push(t.clone());
17        } else {
18            // Unexpected EOF while collecting block tokens: stop collecting
19            break;
20        }
21    }
22
23    tokens
24}
25
26pub fn collect_until<F>(
27    parser: &mut crate::core::parser::driver::parser::Parser,
28    condition: F,
29) -> Vec<Token>
30where
31    F: Fn(&Token) -> bool,
32{
33    let mut collected = Vec::new();
34    while let Some(token) = parser.peek() {
35        if condition(token) {
36            break;
37        }
38        if token.kind == TokenKind::EOF {
39            break;
40        }
41        if let Some(t) = parser.advance() {
42            collected.push(t.clone());
43        } else {
44            break;
45        }
46    }
47
48    collected
49}
50
51pub fn parse_block(
52    parser: &crate::core::parser::driver::parser::Parser,
53    tokens: Vec<Token>,
54    global_store: &mut GlobalStore,
55) -> Vec<crate::core::parser::statement::Statement> {
56    let mut inner_parser = crate::core::parser::driver::parser::Parser {
57        resolve_modules: parser.resolve_modules,
58        tokens,
59        token_index: 0,
60        current_module: parser.current_module.clone(),
61        previous: None,
62    };
63
64    inner_parser.parse_tokens(inner_parser.tokens.clone(), global_store)
65}
66
67pub fn parse_block_until_next_else(
68    parser: &mut crate::core::parser::driver::parser::Parser,
69    base_indent: usize,
70    global_store: &mut GlobalStore,
71) -> Vec<crate::core::parser::statement::Statement> {
72    let mut block_tokens = Vec::new();
73
74    while let Some(tok) = parser.peek() {
75        // Stop if we encounter an 'else' at same indent level
76        if tok.lexeme == "else" && tok.indent == base_indent {
77            break;
78        }
79        if let Some(t) = parser.advance() {
80            block_tokens.push(t.clone());
81        } else {
82            break;
83        }
84    }
85
86    parse_block(parser, block_tokens, global_store)
87}
88
89pub fn parse_block_until_else_or_dedent(
90    parser: &mut crate::core::parser::driver::parser::Parser,
91    base_indent: usize,
92    global_store: &mut GlobalStore,
93) -> Vec<crate::core::parser::statement::Statement> {
94    let mut tokens = Vec::new();
95
96    while let Some(tok) = parser.peek() {
97        if tok.lexeme == "else" && tok.indent == base_indent {
98            break;
99        }
100        if tok.indent < base_indent && tok.kind != TokenKind::Newline {
101            break;
102        }
103        if let Some(t) = parser.advance() {
104            tokens.push(t.clone());
105        } else {
106            break;
107        }
108    }
109
110    parse_block(parser, tokens, global_store)
111}