devalang_core/core/parser/handler/
pattern.rs

1use devalang_types::Value;
2
3use crate::core::{
4    lexer::token::TokenKind,
5    parser::{
6        driver::parser::Parser,
7        statement::{Statement, StatementKind},
8    },
9    store::global::GlobalStore,
10};
11
12pub fn parse_pattern_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
13    // consume 'pattern'
14    parser.advance();
15
16    let Some(tok) = parser.previous_clone() else {
17        return Statement::unknown();
18    };
19
20    // Parse pattern name
21    let mut name = String::new();
22    if let Some(next) = parser.peek_clone() {
23        if next.kind == TokenKind::Identifier {
24            parser.advance();
25            name = next.lexeme.clone();
26        }
27    }
28
29    // optional 'with <target>' sequence
30    let mut target: Option<String> = None;
31    if parser.peek_is("with") {
32        parser.advance(); // consume 'with'
33        if let Some(tok2) = parser.peek_clone() {
34            // target can be identifier or dotted identifier
35            if tok2.kind == TokenKind::Identifier {
36                parser.advance();
37                let mut base = tok2.lexeme.clone();
38                if let Some(dot) = parser.peek_clone() {
39                    if dot.kind == TokenKind::Dot {
40                        parser.advance();
41                        if let Some(suf) = parser.peek_clone() {
42                            if suf.kind == TokenKind::Identifier || suf.kind == TokenKind::Number {
43                                parser.advance();
44                                base.push('.');
45                                base.push_str(&suf.lexeme);
46                            }
47                        }
48                    }
49                }
50                target = Some(base);
51            }
52        }
53    }
54
55    // optional '=' and pattern string
56    let mut value: Value = Value::Null;
57    if parser.peek_is("=") {
58        parser.advance();
59        if let Some(tok3) = parser.peek_clone() {
60            if tok3.kind == TokenKind::String {
61                parser.advance();
62                value = Value::String(tok3.lexeme.clone());
63            }
64        }
65    }
66
67    Statement {
68        kind: StatementKind::Pattern { name, target },
69        value,
70        indent: tok.indent,
71        line: tok.line,
72        column: tok.column,
73    }
74}