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

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