devalang_core/core/parser/handler/
arrow_call.rs1use crate::core::{
2 lexer::token::TokenKind,
3 parser::{
4 driver::parser::Parser,
5 statement::{Statement, StatementKind},
6 },
7 store::global::GlobalStore,
8};
9use devalang_types::Value;
10
11fn parse_map_literal(parser: &mut Parser) -> Value {
12 let mut map = std::collections::HashMap::new();
14 loop {
15 let Some(inner_token) = parser.peek_clone() else {
16 break;
17 };
18
19 match inner_token.kind {
20 TokenKind::RBrace => {
21 parser.advance(); break;
23 }
24 TokenKind::Newline | TokenKind::Comma => {
25 parser.advance();
26 continue;
27 }
28 _ => {}
29 }
30
31 parser.advance();
33 let key = inner_token.lexeme.clone();
34
35 if let Some(colon_token) = parser.peek_clone() {
37 if colon_token.kind == TokenKind::Colon {
38 parser.advance(); if let Some(value_token) = parser.peek_clone() {
42 match value_token.kind {
43 TokenKind::LBrace => {
44 parser.advance(); let nested = parse_map_literal(parser);
46 map.insert(key, nested);
47 }
48 TokenKind::Identifier => {
49 parser.advance();
50 let v = if value_token.lexeme == "true" {
51 Value::Boolean(true)
52 } else if value_token.lexeme == "false" {
53 Value::Boolean(false)
54 } else {
55 Value::Identifier(value_token.lexeme.clone())
56 };
57 map.insert(key, v);
58 }
59 TokenKind::String => {
60 parser.advance();
61 map.insert(key, Value::String(value_token.lexeme.clone()));
62 }
63 TokenKind::Number => {
64 parser.advance();
65 if let Some(TokenKind::Slash) = parser.peek_kind() {
67 parser.advance(); if let Some(den) = parser.peek_clone() {
69 if den.kind == TokenKind::Number
70 || den.kind == TokenKind::Identifier
71 {
72 parser.advance();
73 let beat = format!("{}/{}", value_token.lexeme, den.lexeme);
74 map.insert(
75 key,
76 Value::Duration(devalang_types::Duration::Beat(beat)),
77 );
78 continue;
79 }
80 }
81 }
82 if let Some(next) = parser.peek_clone() {
84 if next.kind == TokenKind::Dot {
85 parser.advance(); if let Some(after) = parser.peek_clone() {
87 if after.kind == TokenKind::Number {
88 parser.advance();
89 let combined =
90 format!("{}.{}", value_token.lexeme, after.lexeme);
91 map.insert(
92 key,
93 Value::Number(
94 combined.parse::<f32>().unwrap_or(0.0),
95 ),
96 );
97 continue;
98 }
99 }
100 }
101 }
102 map.insert(
103 key,
104 Value::Number(value_token.lexeme.parse::<f32>().unwrap_or(0.0)),
105 );
106 }
107 TokenKind::Boolean => {
108 parser.advance();
109 map.insert(
110 key,
111 Value::Boolean(value_token.lexeme.parse::<bool>().unwrap_or(false)),
112 );
113 }
114 _ => {
115 parser.advance();
117 map.insert(key, Value::Unknown);
118 }
119 }
120 }
121 }
122 }
123 }
124 Value::Map(map)
125}
126
127pub fn parse_arrow_call(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
128 let Some(target_token) = parser.peek_clone() else {
129 return Statement::unknown();
130 };
131
132 if target_token.kind != TokenKind::Identifier {
133 parser.advance(); return Statement::unknown_with_pos(
135 target_token.indent,
136 target_token.line,
137 target_token.column,
138 );
139 }
140
141 let Some(arrow_token) = parser.peek_nth(1).cloned() else {
142 parser.advance(); return Statement::unknown_with_pos(
144 target_token.indent,
145 target_token.line,
146 target_token.column,
147 );
148 };
149
150 if arrow_token.kind != TokenKind::Arrow {
151 parser.advance(); return Statement::unknown_with_pos(
153 target_token.indent,
154 target_token.line,
155 target_token.column,
156 );
157 }
158
159 let Some(method_token) = parser.peek_nth(2).cloned() else {
161 parser.advance();
162 return Statement::unknown_with_pos(
163 target_token.indent,
164 target_token.line,
165 target_token.column,
166 );
167 };
168
169 if method_token.kind != TokenKind::Identifier {
170 parser.advance();
171 return Statement::unknown_with_pos(
172 method_token.indent,
173 method_token.line,
174 method_token.column,
175 );
176 }
177
178 parser.advance(); parser.advance(); parser.advance(); let args = parse_arrow_args(parser);
184 Statement {
185 kind: StatementKind::ArrowCall {
186 target: target_token.lexeme.clone(),
187 method: method_token.lexeme.clone(),
188 args,
189 },
190 value: Value::Null,
191 indent: target_token.indent,
192 line: target_token.line,
193 column: target_token.column,
194 }
195}
196
197fn parse_arrow_args(parser: &mut Parser) -> Vec<Value> {
199 let mut args = Vec::new();
200 let mut paren_depth = 0;
201 let mut map_depth = 0;
202
203 while let Some(token) = parser.peek_clone() {
204 if token.kind == TokenKind::Newline || token.kind == TokenKind::EOF {
205 break;
206 }
207 if token.kind == TokenKind::LParen {
208 paren_depth += 1;
209 }
210 if token.kind == TokenKind::RParen {
211 if paren_depth > 0 {
212 paren_depth -= 1;
213 parser.advance();
214 if paren_depth == 0 {
215 break;
216 }
217 continue;
218 } else {
219 break;
220 }
221 }
222 if token.kind == TokenKind::LBrace {
223 map_depth += 1;
224 }
225 if token.kind == TokenKind::RBrace {
226 if map_depth > 0 {
227 map_depth -= 1;
228 parser.advance();
229 if map_depth == 0 {
230 continue;
231 }
232 continue;
233 } else {
234 break;
235 }
236 }
237
238 parser.advance();
239
240 let value = match token.kind {
241 TokenKind::Identifier => Value::Identifier(token.lexeme.clone()),
242 TokenKind::String => Value::String(token.lexeme.clone()),
243 TokenKind::Number => {
244 if let Some(TokenKind::Slash) = parser.peek_kind() {
245 parser.advance(); if let Some(den) = parser.peek_clone() {
247 if den.kind == TokenKind::Number || den.kind == TokenKind::Identifier {
248 parser.advance();
249 let beat = format!("{}/{}", token.lexeme, den.lexeme);
250 Value::Duration(devalang_types::Duration::Beat(beat))
251 } else {
252 Value::Number(token.lexeme.parse::<f32>().unwrap_or(0.0))
253 }
254 } else {
255 Value::Number(token.lexeme.parse::<f32>().unwrap_or(0.0))
256 }
257 } else {
258 Value::Number(token.lexeme.parse::<f32>().unwrap_or(0.0))
259 }
260 }
261 TokenKind::LBrace => parse_map_literal(parser),
262 _ => Value::Unknown,
263 };
264
265 args.push(value);
266
267 if paren_depth == 0 && (token.kind == TokenKind::RParen || token.kind == TokenKind::RBrace)
268 {
269 break;
270 }
271 }
272
273 args
274}
275
276pub fn parse_arrow_continuation(
279 parser: &mut Parser,
280 _global_store: &mut GlobalStore,
281 prev_target: Option<String>,
282) -> Statement {
283 let arrow_tok = parser.peek_clone();
285 if arrow_tok.is_none() {
286 return Statement::unknown();
287 }
288
289 let Some(target) = prev_target else {
291 parser.advance(); return Statement::unknown();
293 };
294
295 parser.advance();
297
298 let Some(method_token) = parser.peek_nth(0).cloned() else {
300 return Statement::unknown();
301 };
302
303 if method_token.kind != TokenKind::Identifier {
304 parser.advance();
305 return Statement::unknown_with_pos(
306 method_token.indent,
307 method_token.line,
308 method_token.column,
309 );
310 }
311
312 parser.advance();
314
315 let args = parse_arrow_args(parser);
316
317 Statement {
318 kind: StatementKind::ArrowCall {
319 target,
320 method: method_token.lexeme.clone(),
321 args,
322 },
323 value: Value::Null,
324 indent: method_token.indent,
325 line: method_token.line,
326 column: method_token.column,
327 }
328}