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