devalang_core/core/parser/handler/
tempo.rs

1use crate::core::{
2    lexer::token::TokenKind,
3    parser::{
4        driver::Parser,
5        statement::{Statement, StatementKind},
6    },
7    store::global::GlobalStore,
8};
9use devalang_types::Value;
10
11pub fn parse_tempo_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
12    parser.advance(); // consume 'bpm'
13
14    let Some(tempo_token) = parser.previous_clone() else {
15        return Statement::unknown();
16    };
17
18    // Expect a number or identifier
19    let Some(value_token) = parser.peek_clone() else {
20        return Statement::error_with_pos(
21            tempo_token.indent,
22            tempo_token.line,
23            tempo_token.column,
24            "Expected a number or identifier after 'bpm'".to_string(),
25        );
26    };
27
28    let value = match value_token.kind {
29        TokenKind::Number => {
30            parser.advance();
31            Value::Number(value_token.lexeme.parse().unwrap_or(0.0))
32        }
33        TokenKind::Identifier => {
34            parser.advance();
35            Value::Identifier(value_token.lexeme.clone())
36        }
37        _ => {
38            return Statement::error_with_pos(
39                value_token.indent,
40                value_token.line,
41                value_token.column,
42                format!(
43                    "Expected a number or identifier after 'bpm', got {:?}",
44                    value_token.kind
45                ),
46            );
47        }
48    };
49
50    Statement {
51        kind: StatementKind::Tempo,
52        value,
53        indent: tempo_token.indent,
54        line: tempo_token.line,
55        column: tempo_token.column,
56    }
57}