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 mut args = Vec::new();
184 let mut paren_depth = 0;
185 let mut map_depth = 0;
186
187 while let Some(token) = parser.peek_clone() {
188 if token.kind == TokenKind::Newline || token.kind == TokenKind::EOF {
189 break;
190 }
191 if token.kind == TokenKind::LParen {
192 paren_depth += 1;
193 }
194 if token.kind == TokenKind::RParen {
195 if paren_depth > 0 {
196 paren_depth -= 1;
197 parser.advance();
198 if paren_depth == 0 {
199 break;
200 }
201 continue;
202 } else {
203 break;
204 }
205 }
206 if token.kind == TokenKind::LBrace {
207 map_depth += 1;
208 }
209 if token.kind == TokenKind::RBrace {
210 if map_depth > 0 {
211 map_depth -= 1;
212 parser.advance();
213 if map_depth == 0 {
214 continue;
215 }
216 continue;
217 } else {
218 break;
219 }
220 }
221
222 parser.advance();
223
224 let value = match token.kind {
225 TokenKind::Identifier => Value::Identifier(token.lexeme.clone()),
226 TokenKind::String => Value::String(token.lexeme.clone()),
227 TokenKind::Number => {
228 if let Some(TokenKind::Slash) = parser.peek_kind() {
231 parser.advance(); if let Some(den) = parser.peek_clone() {
233 if den.kind == TokenKind::Number || den.kind == TokenKind::Identifier {
234 parser.advance();
235 let beat = format!("{}/{}", token.lexeme, den.lexeme);
236 Value::Duration(devalang_types::Duration::Beat(beat))
237 } else {
238 Value::Number(token.lexeme.parse::<f32>().unwrap_or(0.0))
239 }
240 } else {
241 Value::Number(token.lexeme.parse::<f32>().unwrap_or(0.0))
242 }
243 } else {
244 Value::Number(token.lexeme.parse::<f32>().unwrap_or(0.0))
245 }
246 }
247 TokenKind::LBrace => {
248 parse_map_literal(parser)
253 }
254 _ => Value::Unknown,
255 };
256
257 args.push(value);
258
259 if paren_depth == 0 && (token.kind == TokenKind::RParen || token.kind == TokenKind::RBrace)
261 {
262 break;
263 }
264 }
265
266 Statement {
267 kind: StatementKind::ArrowCall {
268 target: target_token.lexeme.clone(),
269 method: method_token.lexeme.clone(),
270 args,
271 },
272 value: Value::Null,
273 indent: target_token.indent,
274 line: target_token.line,
275 column: target_token.column,
276 }
277}