devalang_core/core/parser/handler/
bank.rs

1use crate::core::{
2    lexer::token::TokenKind,
3    parser::{
4        driver::Parser,
5        statement::{Statement, StatementKind},
6    },
7    shared::value::Value,
8    store::global::GlobalStore,
9};
10
11pub fn parse_bank_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
12    // consume 'bank'
13    parser.advance();
14
15    let Some(bank_tok) = parser.previous_clone() else {
16        return Statement::unknown();
17    };
18
19    // Parse bank name
20    let bank_value: Value = match parser.peek_clone() {
21        Some(tok) => match tok.kind {
22            TokenKind::Identifier | TokenKind::Number => {
23                // base name
24                parser.advance();
25                let mut base = tok.lexeme.clone();
26                // optional .suffix (identifier or number)
27                if let Some(dot) = parser.peek_clone() {
28                    if dot.kind == TokenKind::Dot {
29                        // consume '.' and the following ident/number
30                        parser.advance();
31                        if let Some(suffix) = parser.peek_clone() {
32                            match suffix.kind {
33                                TokenKind::Identifier | TokenKind::Number => {
34                                    parser.advance();
35                                    base.push('.');
36                                    base.push_str(&suffix.lexeme);
37                                    Value::String(base)
38                                }
39                                _ => Value::Identifier(base),
40                            }
41                        } else {
42                            Value::Identifier(base)
43                        }
44                    } else {
45                        match tok.kind {
46                            TokenKind::Identifier => Value::String(base),
47                            TokenKind::Number => Value::Number(base.parse::<f32>().unwrap_or(0.0)),
48                            _ => Value::Unknown,
49                        }
50                    }
51                } else {
52                    match tok.kind {
53                        TokenKind::Identifier => Value::String(base),
54                        TokenKind::Number => Value::Number(base.parse::<f32>().unwrap_or(0.0)),
55                        _ => Value::Unknown,
56                    }
57                }
58            }
59            TokenKind::String => {
60                parser.advance();
61                Value::String(tok.lexeme.clone())
62            }
63            _ => Value::Unknown,
64        },
65        None => Value::Unknown,
66    };
67
68    if matches!(bank_value, Value::Unknown | Value::Null) {
69        return Statement::error(bank_tok, "Expected a bank name".to_string());
70    }
71
72    // Optional alias: as <identifier>
73    let mut alias: Option<String> = None;
74    if parser.peek_is("as") {
75        // consume 'as'
76        parser.advance();
77        let Some(next) = parser.peek_clone() else {
78            return Statement::error(bank_tok, "Expected identifier after 'as'".to_string());
79        };
80        if next.kind != TokenKind::Identifier {
81            return Statement::error(next, "Expected identifier after 'as'".to_string());
82        }
83        parser.advance();
84        alias = Some(next.lexeme.clone());
85    }
86
87    Statement {
88        kind: StatementKind::Bank { alias },
89        value: bank_value,
90        indent: bank_tok.indent,
91        line: bank_tok.line,
92        column: bank_tok.column,
93    }
94}