devalang_core/core/parser/handler/
dot.rs1use crate::core::{
2 lexer::token::TokenKind,
3 parser::{driver::Parser, statement::{Statement, StatementKind}},
4 shared::{duration::Duration, value::Value},
5};
6
7pub fn parse_dot_token(
8 parser: &mut Parser,
9 _global_store: &mut crate::core::store::global::GlobalStore
10) -> Statement {
11 parser.advance(); let Some(dot_token) = parser.previous_clone() else {
14 return Statement::unknown();
15 };
16
17 let mut parts = Vec::new();
19 let current_line = dot_token.line;
20
21 while let Some(token) = parser.peek_clone() {
22 if token.line != current_line {
24 break;
25 }
26 match token.kind {
27 TokenKind::Identifier | TokenKind::Number => {
28 parts.push(token.lexeme.clone());
29 parser.advance();
30 if let Some(next) = parser.peek_clone() {
32 if next.line != current_line || next.kind != TokenKind::Dot {
33 break;
34 }
35 } else {
36 break;
37 }
38 }
39 TokenKind::Dot => {
40 parser.advance();
41 }
42 TokenKind::Newline | TokenKind::EOF | TokenKind::Indent | TokenKind::Dedent => {
43 break; }
45 _ => {
46 break;
47 }
48 }
49 }
50
51 let entity = if !parts.is_empty() {
53 parts.join(".") } else {
55 eprintln!("⚠️ Empty entity after '.' at line {}", dot_token.line);
56 String::new()
57 };
58
59 let mut duration = Duration::Auto;
61 let mut value = Value::Null;
62
63 if let Some(token) = parser.peek_clone() {
64 if token.line == current_line {
66 match token.kind {
67 TokenKind::Number => {
68 let numerator = token.lexeme.clone();
69 parser.advance();
70 if let Some(peek) = parser.peek_clone() {
71 if peek.line == current_line {
72 if let Some(TokenKind::Slash) = parser.peek_kind() {
73 parser.advance();
74 if let Some(denominator_token) = parser.peek_clone() {
75 if denominator_token.line == current_line && denominator_token.kind == TokenKind::Number {
76 let denominator = denominator_token.lexeme.clone();
77 parser.advance();
78 duration = Duration::Beat(format!("{}/{}", numerator, denominator));
79 }
80 }
81 } else {
82 duration = parse_duration(numerator);
83 }
84 } else {
85 duration = parse_duration(numerator);
86 }
87 } else {
88 duration = parse_duration(numerator);
89 }
90 if let Some(next) = parser.peek_clone() {
91 if next.line == current_line && next.kind == TokenKind::LBrace {
92 value = parser.parse_map_value().unwrap_or(Value::Null);
93 }
94 }
95 }
96 TokenKind::Identifier => {
97 let id = token.lexeme.clone();
98 parser.advance();
99 duration = parse_duration(id);
100 if let Some(next) = parser.peek_clone() {
101 if next.line == current_line && next.kind == TokenKind::LBrace {
102 value = parser.parse_map_value().unwrap_or(Value::Null);
103 }
104 }
105 }
106 TokenKind::LBrace => {
107 value = parser.parse_map_value().unwrap_or(Value::Null);
108 }
109 _ => {}
110 }
111 }
112 }
113
114 Statement {
115 kind: StatementKind::Trigger {
116 entity,
117 duration,
118 effects: Some(value.clone()),
119 },
120 value: Value::Null,
121 indent: dot_token.indent,
122 line: dot_token.line,
123 column: dot_token.column,
124 }
125}
126
127fn parse_duration(s: String) -> Duration {
128 if s == "auto" {
129 Duration::Auto
130 } else if let Ok(num) = s.parse::<f32>() {
131 Duration::Number(num)
132 } else {
133 Duration::Identifier(s)
134 }
135}