devalang_core/core/parser/handler/identifier/
group.rs

1use devalang_types::Value;
2
3use crate::core::{
4    lexer::token::{Token, TokenKind},
5    parser::{
6        driver::parser::Parser,
7        statement::{Statement, StatementKind},
8    },
9    store::global::GlobalStore,
10};
11use std::collections::HashMap;
12
13pub fn parse_group_token(
14    parser: &mut Parser,
15    current_token: Token,
16    global_store: &mut GlobalStore,
17) -> Statement {
18    parser.advance(); // consume "group"
19
20    let Some(identifier_token) = parser.peek_clone() else {
21        return crate::core::parser::statement::error_from_token(
22            current_token,
23            "Expected identifier after 'group'".to_string(),
24        );
25    };
26
27    if identifier_token.kind != TokenKind::Identifier && identifier_token.kind != TokenKind::String
28    {
29        return crate::core::parser::statement::error_from_token(
30            identifier_token,
31            "Expected valid identifier".to_string(),
32        );
33    }
34
35    parser.advance(); // consume identifier
36
37    let Some(colon_token) = parser.peek_clone() else {
38        return crate::core::parser::statement::error_from_token(
39            identifier_token,
40            "Expected ':' after group identifier".to_string(),
41        );
42    };
43
44    if colon_token.kind != TokenKind::Colon {
45        return crate::core::parser::statement::error_from_token(
46            colon_token.clone(),
47            "Expected ':' after group identifier".to_string(),
48        );
49    }
50
51    parser.advance(); // consume ':'
52
53    let base_indent = current_token.indent;
54
55    // Clone without consuming tokens
56    let mut index = parser.token_index;
57    let mut tokens_inside_group = Vec::new();
58
59    while index < parser.tokens.len() {
60        let token = parser.tokens[index].clone();
61
62        if token.indent <= base_indent && token.kind != TokenKind::Newline {
63            break;
64        }
65
66        tokens_inside_group.push(token);
67        index += 1;
68    }
69
70    // Advance index once to skip the processed tokens
71    parser.token_index = index;
72
73    let body = parser.parse_block(tokens_inside_group, global_store);
74
75    let mut value_map = HashMap::new();
76    value_map.insert(
77        "identifier".to_string(),
78        Value::String(identifier_token.lexeme.clone()),
79    );
80    value_map.insert("body".to_string(), Value::Block(body));
81
82    Statement {
83        kind: StatementKind::Group,
84        value: Value::Map(value_map),
85        indent: current_token.indent,
86        line: current_token.line,
87        column: current_token.column,
88    }
89}