devalang_core/core/parser/driver/
driver_impl.rs

1use crate::core::lexer::token::TokenKind;
2use crate::core::parser::statement::StatementKind;
3use crate::core::store::global::GlobalStore;
4use devalang_types::Value;
5
6pub fn parse_tokens_impl(
7    parser: &mut crate::core::parser::driver::parser::Parser,
8    tokens: Vec<crate::core::lexer::token::Token>,
9    global_store: &mut GlobalStore,
10) -> Vec<crate::core::parser::statement::Statement> {
11    // Filter out Whitespace tokens but keep Newline tokens because some constructs (e.g., print ...)
12    // rely on end-of-line semantics.
13    parser.tokens = tokens
14        .into_iter()
15        .filter(|t| t.kind != TokenKind::Whitespace)
16        .collect();
17    parser.token_index = 0;
18
19    let mut statements = Vec::new();
20
21    while !crate::core::parser::driver::cursor::is_eof_impl(parser) {
22        let token = match crate::core::parser::driver::cursor::peek_impl(parser) {
23            Some(t) => t.clone(),
24            None => {
25                break;
26            }
27        };
28
29        if token.kind == TokenKind::Newline {
30            crate::core::parser::driver::cursor::advance_impl(parser);
31            continue;
32        }
33
34        // If the line starts with an Arrow ("->"), treat it as a continuation of the
35        // previous arrow call: reuse the target from the last parsed ArrowCall statement
36        // so chained effects on subsequent lines are supported.
37        let statement = if token.kind == TokenKind::Arrow {
38            // find previous ArrowCall target if any
39            let prev_target = statements.last().and_then(
40                |s: &crate::core::parser::statement::Statement| match &s.kind {
41                    StatementKind::ArrowCall { target, .. } => Some(target.clone()),
42                    _ => None,
43                },
44            );
45
46            crate::core::parser::handler::arrow_call::parse_arrow_continuation(
47                parser,
48                global_store,
49                prev_target,
50            )
51        } else {
52            match &token.kind {
53            TokenKind::At => crate::core::parser::handler::at::parse_at_token(parser, global_store),
54            TokenKind::Identifier => {
55                if
56                    let Some(next) = crate::core::parser::driver::cursor
57                        ::peek_nth_impl(parser, 1)
58                        .cloned()
59                {
60                    if next.kind == TokenKind::Arrow {
61                        crate::core::parser::handler::arrow_call::parse_arrow_call(
62                            parser,
63                            global_store
64                        )
65                    } else {
66                        crate::core::parser::handler::identifier::parse_identifier_token(
67                            parser,
68                            global_store
69                        )
70                    }
71                } else {
72                    crate::core::parser::handler::identifier::parse_identifier_token(
73                        parser,
74                        global_store
75                    )
76                }
77            }
78            TokenKind::Dot =>
79                crate::core::parser::handler::dot::parse_dot_token(parser, global_store),
80            TokenKind::Tempo =>
81                crate::core::parser::handler::tempo::parse_tempo_token(parser, global_store),
82            TokenKind::Bank =>
83                crate::core::parser::handler::bank::parse_bank_token(parser, global_store),
84            TokenKind::Pattern =>
85                crate::core::parser::handler::pattern::parse_pattern_token(parser, global_store),
86            TokenKind::Loop =>
87                crate::core::parser::handler::loop_::parse_loop_token(parser, global_store),
88            TokenKind::If =>
89                crate::core::parser::handler::condition::parse_condition_token(
90                    parser,
91                    global_store
92                ),
93            TokenKind::Function =>
94                crate::core::parser::handler::identifier::function::parse_function_token(
95                    parser,
96                    global_store
97                ),
98            TokenKind::On =>
99                crate::core::parser::handler::identifier::on::parse_on_token(parser, global_store),
100            TokenKind::Emit =>
101                crate::core::parser::handler::identifier::emit::parse_emit_token(
102                    parser,
103                    token.clone(),
104                    global_store
105                ),
106
107            | TokenKind::Else // Ignore else, already handled in `parse_condition_token`
108            | TokenKind::Comment
109            | TokenKind::Equals
110            | TokenKind::Colon
111            | TokenKind::Number
112            | TokenKind::String
113            | TokenKind::LBrace
114            | TokenKind::RBrace
115            | TokenKind::Comma
116            | TokenKind::Dedent
117            | TokenKind::Indent => {
118                crate::core::parser::driver::cursor::advance_impl(parser);
119                continue;
120            }
121
122            TokenKind::EOF => {
123                break;
124            }
125
126            _ => {
127                crate::core::parser::driver::cursor::advance_impl(parser);
128                crate::core::parser::statement::Statement::unknown_with_pos(
129                    token.indent,
130                    token.line,
131                    token.column
132                )
133            }
134            }
135        };
136
137        statements.push(statement);
138    }
139
140    statements
141}
142
143pub fn parse_condition_until_colon_impl(
144    parser: &mut crate::core::parser::driver::parser::Parser,
145) -> Option<Value> {
146    let tokens =
147        crate::core::parser::driver::block::collect_until(parser, |t| t.kind == TokenKind::Colon);
148    if tokens.is_empty() {
149        return None;
150    }
151
152    let condition = tokens
153        .iter()
154        .map(|t| t.lexeme.clone())
155        .collect::<Vec<_>>()
156        .join(" ");
157
158    Some(Value::String(condition))
159}