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

1use devalang_types::Value;
2
3use crate::core::{
4    lexer::token::{Token, TokenKind},
5    parser::{
6        driver::parser::Parser,
7        statement::{Statement, StatementKind},
8    },
9    store::global::GlobalStore,
10};
11
12pub fn parse_sleep_token(
13    parser: &mut Parser,
14    current_token: Token,
15    _global_store: &mut GlobalStore,
16) -> Statement {
17    parser.advance(); // consume "sleep"
18
19    // Accept number, decimal, fraction like 1/4 (-> Duration::Beat), string, or identifier
20    let duration_value = if let Some(token) = parser.peek_clone() {
21        match token.kind {
22            TokenKind::Number => {
23                let mut num = token.lexeme.clone();
24                parser.advance();
25                // decimal part
26                if let Some(dot) = parser.peek_clone() {
27                    if dot.kind == TokenKind::Dot {
28                        if let Some(next) = parser.peek_nth(1).cloned() {
29                            if next.kind == TokenKind::Number {
30                                parser.advance(); // consume dot
31                                parser.advance(); // consume next number
32                                num.push('.');
33                                num.push_str(&next.lexeme);
34                            }
35                        }
36                    }
37                }
38
39                // fraction form 1/4 -> Duration::Beat("1/4")
40                if let Some(slash) = parser.peek_clone() {
41                    if slash.kind == TokenKind::Slash {
42                        parser.advance();
43                        if let Some(den) = parser.peek_clone() {
44                            if den.kind == TokenKind::Number || den.kind == TokenKind::Identifier {
45                                let frac = format!("{}/{}", num, den.lexeme);
46                                parser.advance();
47                                Value::Duration(devalang_types::Duration::Beat(frac))
48                            } else {
49                                return crate::core::parser::statement::error_from_token(
50                                    slash,
51                                    "Expected denominator after '/' in sleep".to_string(),
52                                );
53                            }
54                        } else {
55                            return crate::core::parser::statement::error_from_token(
56                                slash,
57                                "Expected denominator after '/' in sleep".to_string(),
58                            );
59                        }
60                    } else {
61                        Value::Number(num.parse().unwrap_or(0.0))
62                    }
63                } else {
64                    Value::Number(num.parse().unwrap_or(0.0))
65                }
66            }
67            TokenKind::String => {
68                parser.advance();
69                Value::String(token.lexeme.clone())
70            }
71            TokenKind::Identifier => {
72                parser.advance();
73                Value::Identifier(token.lexeme.clone())
74            }
75            _ => {
76                return crate::core::parser::statement::error_from_token(
77                    token,
78                    "Expected duration after 'sleep'".to_string(),
79                );
80            }
81        }
82    } else {
83        return crate::core::parser::statement::error_from_token(
84            current_token,
85            "Expected duration after 'sleep'".to_string(),
86        );
87    };
88
89    Statement {
90        kind: StatementKind::Sleep,
91        value: duration_value,
92        indent: current_token.indent,
93        line: current_token.line,
94        column: current_token.column,
95    }
96}