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

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