1use crate::{macros::{MacroGroup, MacroTokenIterator}, string_clip::StringClip};
2use crate::lexer::Token;
3use guarded::guarded_unwrap;
4use indexmap::IndexSet;
5use num_traits::Num;
6use palette::Srgb;
7use tree_node_group::{AnyTreeNode, AnyTreeNodeMut, TreeNodeType};
8use std::{fmt::Debug, ops::Deref, str::FromStr, sync::LazyLock};
9use phf_macros::phf_map;
10use rbx_types::{Color3uint8, Content, EnumItem, UDim, Variant};
11use regex::Regex;
12
13mod tree_node_group;
14pub use tree_node_group::{TreeNodeGroup, TreeNode};
15
16mod tuple;
17use tuple::Tuple;
18
19mod selector;
20use selector::Selector;
21
22mod datatype_group;
23use datatype_group::DatatypeGroup;
24pub use datatype_group::Datatype;
25
26mod variants;
27pub use variants::EnumItemFromNameAndValueName;
28
29mod operator;
30use operator::Operator;
31
32mod colors {
33 include!(concat!(env!("OUT_DIR"), "/colors.rs"));
34}
35use colors::{TAILWIND_COLORS, BRICK_COLORS, CSS_COLORS, SKIN_COLORS};
36
37const MULTI_LINE_STRING_STRIP_LEFT_REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^[ \t\f]*\n+").unwrap());
38
39type TokenWithResult<'a, R> = (Option<Token>, R);
40
41fn parse_number_string<D>(num_str: &str) -> Result<D, <D as FromStr>::Err>
42where
43 D: Num + FromStr,
44 <D as FromStr>::Err: Debug
45{
46 let mut num_str = num_str.to_string();
47 num_str.retain(|c| !r#"_"#.contains(c));
48 num_str.parse::<D>()
49}
50
51struct Parser<'a> {
52 lexer: &'a mut logos::Lexer<'a, Token>,
53
54 current_macros: IndexSet<(String, usize)>,
57
58 macros: &'a MacroGroup,
59 injected_macro_tokens: Vec<MacroTokenIterator<'a>>,
60
61 tree_nodes: TreeNodeGroup,
62 current_tree_node_idx: TreeNodeType,
63
64 tuples: Vec<Tuple>,
65
66 did_advance: bool,
67}
68
69impl<'a> Parser<'a> {
70 fn new(lexer: &'a mut logos::Lexer<'a, Token>, macros: &'a MacroGroup) -> Self {
71 Self {
72 lexer,
73
74 current_macros: IndexSet::new(),
75 macros,
76
77 injected_macro_tokens: vec![],
78
79 tree_nodes: TreeNodeGroup::new(),
80 current_tree_node_idx: TreeNodeType::Root,
81
82 tuples: vec![],
83
84 did_advance: false,
85 }
86 }
87
88 fn inject_tokens(&mut self, injected_macro_tokens: MacroTokenIterator<'a>) {
89 self.injected_macro_tokens.push(injected_macro_tokens);
90 }
91
92 fn core_next(&mut self) -> Option<Result<Token, ()>> {
93 if let Some(last_injected_macro_tokens) = self.injected_macro_tokens.last_mut() {
94 let next_injected = last_injected_macro_tokens.next();
95
96 if next_injected.is_some() {
97 next_injected
98
99 } else {
100 self.injected_macro_tokens.pop();
101 self.current_macros.pop();
102 self.core_next()
103 }
104
105 } else {
106 self.lexer.next()
107 }
108 }
109
110 fn slice(&self) -> &'a str {
111 if let Some(injected_macro_tokens) = self.injected_macro_tokens.last() {
112 injected_macro_tokens.slice()
113 } else {
114 self.lexer.slice()
115 }
116 }
117
118 fn core_advance(&mut self) -> Option<Token> {
122 self.did_advance = true;
123
124 loop {
125 match self.core_next() {
126 Some(Ok(token)) => break Some(token),
127 None => return None,
128 _ => ()
129 }
130 }
131 }
132
133 fn advance(self: &mut Parser<'a>) -> Option<Token> {
134 let token = guarded_unwrap!(self.core_advance(), return None);
135
136 let token = parse_comment_multi(self, token).unwrap_or(token);
137
138 let token = parse_comment_single(self, token).unwrap_or(token);
139
140 parse_macro_call(self, token)
141 }
142
143 fn push_tuple(self: &mut Parser<'a>, tuple: Tuple) -> usize {
146 let tuples = &mut self.tuples;
147
148 let new_tuple_idx = tuples.len();
149 tuples.push(tuple);
150
151 new_tuple_idx
152 }
153
154 fn get_tuple(self: &mut Parser<'a>, tuple_idx: usize) -> Option<&Tuple> {
155 self.tuples.get(tuple_idx)
156 }
157
158 fn get_tuple_mut<'b>(self: &'b mut Parser<'a>, tuple_idx: usize) -> Option<&'b mut Tuple> {
159 self.tuples.get_mut(tuple_idx)
160 }
161}
162
163fn parse_macro_call<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
164 if !matches!(token, Token::MacroCall) { return Some(token) }
165
166 let macro_name_with_suffix = parser.slice();
167 let macro_name: String = macro_name_with_suffix.chars().take(macro_name_with_suffix.chars().count() - 1).collect();
168
169 let next_token = parser.advance();
170 if !matches!(next_token, Some(Token::ParensOpen)) { return next_token }
171
172 let mut scope_nestedness = 0usize;
173 let mut parens_nestedness = 0usize;
174 let mut parens_nestedness_is_zero = true;
175
176 let mut args_tokens: Vec<Vec<(Token, &'a str)>> = vec![];
177 let mut current_args_tokens: Vec<(Token, &'a str)> = vec![];
178
179 let mut next_token = parser.advance()?;
180 loop {
181 match next_token {
182 Token::ScopeOpen => scope_nestedness += 1,
183 Token::ScopeClose => scope_nestedness -= 1,
184
185 Token::ParensOpen => {
186 parens_nestedness += 1;
187 parens_nestedness_is_zero = false;
188 },
189 Token::ParensClose => {
190 if parens_nestedness_is_zero {
191 if current_args_tokens.len() != 0 {
192 args_tokens.push(current_args_tokens);
193 }
194 break
195
196 } else {
197 parens_nestedness -= 1;
198 parens_nestedness_is_zero = parens_nestedness == 0;
199 }
200 }
201
202 Token::Comma => {
203 if scope_nestedness == 0 && parens_nestedness_is_zero && current_args_tokens.len() != 0 {
204 args_tokens.push(current_args_tokens);
205 current_args_tokens = vec![];
206
207 next_token = parser.advance()?;
208 continue;
209 }
210 }
211
212 _ => ()
213 }
214
215 current_args_tokens.push((next_token, parser.slice()));
216 next_token = parser.advance()?;
217 }
218
219 let args_len = args_tokens.len();
220
221 let macro_data = guarded_unwrap!(parser.macros.get(¯o_name, args_len), return parser.advance());
222
223 let current_macro = (macro_name, args_len);
224
225 if parser.current_macros.contains(¤t_macro) {
227 return parser.advance()
228 }
229
230 parser.inject_tokens(macro_data.iter(Some(args_tokens)));
231
232 parser.current_macros.insert(current_macro);
233
234 parser.advance()
235}
236
237fn parse_comment_multi_end<'a>(
238 parser: &mut Parser<'a>, start_equals_amount: usize
239) -> Option<Token> {
240 loop {
243 let token = parser.core_advance()?;
244
245 if let Token::StringMultiEnd = token {
246 let end_token_value = parser.slice();
247 let end_equals_amount = end_token_value.clip(1, 1).len();
248
249 if start_equals_amount == end_equals_amount {
250 return parser.core_advance()
251 }
252 }
253 }
254}
255
256fn parse_comment_multi<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
257 if let Token::CommentMultiStart = token {
258 let token_value = parser.slice();
259 let start_equals_amount = token_value.clip(3, 1).len();
260
261 return parse_comment_multi_end(parser, start_equals_amount);
262 };
263
264 None
265}
266
267fn parse_comment_single<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
268 if !matches!(token, Token::CommentSingle) { return None }
269
270 parser.core_advance()
271}
272
273fn parse_scope_open<'a>(parser: &mut Parser<'a>, token: Token, selector: Option<String>) -> Option<Token> {
274 if !matches!(token, Token::ScopeOpen) { return Some(token) }
275
276 let new_tree_node_idx = parser.tree_nodes.nodes_len();
277 let new_tree_node_idx_as_parent = TreeNodeType::Node(new_tree_node_idx);
278
279 let previous_tree_node = parser.tree_nodes.get_node_mut(parser.current_tree_node_idx);
280 match previous_tree_node {
281 AnyTreeNodeMut::Root(node) => node.unwrap().child_rules.push(new_tree_node_idx),
282 AnyTreeNodeMut::Node(node) => node.unwrap().child_rules.push(new_tree_node_idx)
283 }
284
285 let current_tree_node = TreeNode::new(parser.current_tree_node_idx, selector);
286 parser.tree_nodes.add_node(current_tree_node);
287
288 parser.current_tree_node_idx = new_tree_node_idx_as_parent;
289
290 parser.advance()
291}
292
293fn parse_scope_delimiter<'a>(
294 parser: &mut Parser<'a>,
295 token: Token,
296 delim_token: Option<Token>
297) -> TokenWithResult<'a, Option<Token>> {
298 if matches!(token, Token::Comma) {
299 let next_token = guarded_unwrap!(parser.advance(), return (None, delim_token));
300 return parse_scope_delimiter(parser, next_token, Some(token))
301
302 } else {
303 return (Some(token), delim_token)
304 }
305}
306
307fn parse_scope_selector_start<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
308 if !matches!(token,
310 Token::NameIdentifier | Token::PsuedoIdentifier | Token::StateOrEnumIdentifier |
311 Token::TagOrEnumIdentifier | Token::ScopeToDescendants | Token::ScopeToChildren
312 ) { return Some(token) }
313
314 let selector = Selector::new(parser.slice(), token);
315
316 let token = parser.advance()?;
317 return parse_scope_selector(parser, token, selector);
318}
319
320fn parse_scope_selector<'a>(
321 parser: &mut Parser<'a>, mut token: Token, mut selector: Selector
322) -> Option<Token> {
323 loop {
324 let parsed_delimiter = parse_scope_delimiter(parser, token, None);
326 token = guarded_unwrap!(parsed_delimiter.0, return None);
327
328 if matches!(token,
329 Token::NameIdentifier | Token::PsuedoIdentifier | Token::StateOrEnumIdentifier |
330 Token::TagOrEnumIdentifier | Token::ScopeToDescendants | Token::ScopeToChildren |
331 Token::Text
332 ) {
333 if let Some(delim_token) = parsed_delimiter.1 {
335 selector.append(",", delim_token);
336 }
337
338 selector.append(parser.slice(), token);
339
340 token = parser.advance()?;
341
342 } else { break }
343 };
344
345 return parse_scope_open(parser, token, Some(selector.content))
346}
347
348
349fn parse_scope_close<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
350 if !matches!(token, Token::ScopeClose) { return Some(token) }
351
352 let current_tree_node = parser.tree_nodes.get(parser.current_tree_node_idx);
353 match current_tree_node {
354 AnyTreeNode::Node(node) => parser.current_tree_node_idx = node.unwrap().parent,
355 _ => ()
356 }
357
358 return parser.advance()
359}
360
361fn parse_string_multi_end<'a>(
362 parser: &mut Parser<'a>, start_equals_amount: usize
363) -> TokenWithResult<'a, String> {
364 let mut string_data = String::new();
365
366 loop {
369 match parser.lexer.next() {
370 Some(Ok(token)) => {
371 if let Token::StringMultiEnd = token {
372 let end_token_value = parser.slice();
373 let end_equals_amount = end_token_value.clip(1, 1).len();
374
375 if start_equals_amount == end_equals_amount {
376 return (parser.core_advance(), string_data)
377 }
378 }
379
380 string_data += parser.slice();
381 },
382
383 Some(Err(_)) => {
384 string_data += parser.slice();
385 },
386
387 None => return (None, string_data)
388 };
389 }
390}
391
392fn parse_string_multi_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
393 if let Token::StringMultiStart = token {
394 let token_value = parser.slice();
395 let start_equals_amount = token_value.clip(1, 1).len();
396
397 let (token, string_data) = parse_string_multi_end(parser, start_equals_amount);
398
399 let string_data = MULTI_LINE_STRING_STRIP_LEFT_REGEX.replace(&string_data, "").to_string();
402 return (token, Some(Datatype::Variant(Variant::String(string_data))))
403 };
404
405 (Some(token), None)
406}
407
408fn parse_content_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
409 if let Token::RobloxContent = token {
410 let content = parser.slice();
411 return (parser.advance(), Some(Datatype::Variant(Variant::Content(Content::from(content)))))
412 }
413
414 (Some(token), None)
415}
416
417fn parse_string_single_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
418 match token {
419 Token::StringSingle => {
420 let str = parser.slice();
421 let datatype = Some(Datatype::Variant(Variant::String(str.clip(1, 1).to_string())));
422 return (parser.advance(), datatype)
423 },
424
425 Token::RobloxAsset => {
426 let str = parser.slice();
427 let datatype = Some(Datatype::Variant(Variant::String(str.to_string())));
428 return (parser.advance(), datatype)
429 },
430
431 _ => (Some(token), None)
432 }
433}
434
435fn parse_string_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
436 let parsed = parse_string_single_datatype(parser, token);
437 if parsed.1.is_some() { return parsed }
438
439 let parsed = parse_string_multi_datatype(parser, token);
440 if parsed.1.is_some() { return parsed }
441
442 (Some(token), None)
443}
444
445fn parse_number_offset<'a>(parser: &mut Parser<'a>, token: Token, num_str: &str) -> TokenWithResult<'a, Option<Datatype>> {
446 if !matches!(token, Token::Offset) { return (Some(token), None) }
447
448 let datatype = Some(Datatype::Variant(Variant::UDim(UDim::new(
449 0.0,
450 match parse_number_string::<i32>(num_str) {
451 Ok(int32) => int32,
452 Err(_) => parse_number_string::<f32>(num_str).unwrap() as i32
453 }
454 ))));
455
456 return (parser.advance(), datatype)
457}
458
459fn parse_number_scale<'a>(parser: &mut Parser<'a>, token: Token, num_str: &str) -> TokenWithResult<'a, Option<Datatype>> {
460 if !matches!(token, Token::ScaleOrOpMod) { return (Some(token), None) }
461
462 let datatype = Some(Datatype::Variant(Variant::UDim(UDim::new(parse_number_string::<f32>(num_str).unwrap() / 100.0, 0))));
463
464 return (parser.advance(), datatype)
465}
466
467fn parse_number_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
468 if let Token::Number = token {
469 let token_value = parser.slice();
470 let token = parser.advance();
471
472 if let Some(token) = token {
473 let parsed = parse_number_offset(parser, token, token_value);
474 if parsed.1.is_some() { return parsed }
475
476 let parsed = parse_number_scale(parser, token, token_value);
477 if parsed.1.is_some() { return parsed }
478 }
479
480 let datatype = Some(Datatype::Variant(Variant::Float32(parse_number_string::<f32>(token_value).unwrap())));
481
482 return (token, datatype)
483 }
484
485 (Some(token), None)
486}
487
488fn parse_operator_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
489 match Operator::from_token(token) {
490 Some(operator) => (parser.advance(), Some(Datatype::Operator(operator.clone()))),
491 None => (Some(token), None)
492 }
493}
494
495fn parse_enum_tokens<'a>(parser: &mut Parser<'a>, token_history: &mut Vec<Token>) -> Option<Datatype> {
496 let token_history_len = token_history.len();
497 let mut first_stop_idx = 0;
498
499 let mut enum_name = None;
500 for idx in 0..=token_history_len {
501 let token = &token_history[idx];
502
503 if let Token::Text = token {
504 let text = parser.slice();
505 enum_name = Some(text);
506
507 first_stop_idx = idx;
508 break
509 }
510 };
511 let enum_name = guarded_unwrap!(enum_name, return None);
512
513 let mut enum_value_name = None;
514 for idx in (first_stop_idx + 1)..=token_history_len {
515 let token = &token_history[idx];
516
517 if let Token::Text = token {
518 let text = parser.slice();
519 enum_value_name = Some(text);
520 break
521 }
522 };
523 let enum_value_name = guarded_unwrap!(enum_value_name, return None);
524
525 let enum_item = guarded_unwrap!(EnumItem::from_name_and_value_name(enum_name, enum_value_name), return Some(Datatype::None));
526 return Some(Datatype::Variant(Variant::EnumItem(enum_item)))
527}
528
529fn parse_full_enum<'a>(
530 parser: &mut Parser<'a>, token: Token, token_history: &mut Vec<Token>
531) -> TokenWithResult<'a, Option<Datatype>> {
532 if matches!(token,
533 Token::TagOrEnumIdentifier | Token::StateOrEnumIdentifier | Token::Text
534 ) {
535 let token = parser.advance();
536
537 if let Some(token) = token {
538 token_history.push(token);
539
540 let parsed = parse_full_enum(parser, token, token_history);
541 if parsed.1.is_some() { return parsed }
542 }
543 }
544
545 if token_history.len() == 0 { return (Some(token), None) }
546
547 return (Some(token), parse_enum_tokens(parser, token_history))
548}
549
550
551fn parse_enum_keyword<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
552 if !matches!(token, Token::EnumKeyword) { return (Some(token), None) }
553
554 let token = guarded_unwrap!(parser.advance(), return (None, None) );
555
556 let mut token_history = vec![];
557 parse_full_enum(parser, token, &mut token_history)
558}
559
560const SHORTHAND_REBINDS: phf::Map<&'static str, &'static str> = phf_map! {
561 "FlexMode" => "UIFlexMode",
562 "HorizontalFlex" => "UIFlexAlignment",
563 "VerticalFlex" => "UIFlexAlignment"
564};
565
566fn parse_enum_shorthand<'a>(parser: &mut Parser<'a>, token: Token, key: Option<&str>) -> TokenWithResult<'a, Option<Datatype>> {
567 if !matches!(token, Token::StateOrEnumIdentifier) { return (Some(token), None) }
568
569 let token = guarded_unwrap!(parser.advance(), return (None, None));
570
571 let enum_value_name = if let Token::Text = token { parser.slice() } else { return (Some(token), None) };
572
573 if let Some(key) = key {
574 let enum_name = SHORTHAND_REBINDS.get(key).unwrap_or(&key);
575
576 let enum_item = guarded_unwrap!(
577 EnumItem::from_name_and_value_name(enum_name, enum_value_name), return (parser.advance(), Some(Datatype::None))
578 );
579 return (parser.advance(), Some(Datatype::Variant(Variant::EnumItem(enum_item))))
580
581 } else {
582 let datatype = Datatype::IncompleteEnumShorthand(enum_value_name.into());
583 return (parser.advance(), Some(datatype))
584 }
585
586
587}
588
589fn parse_enum_datatype<'a>(parser: &mut Parser<'a>, token: Token, key: Option<&str>) -> TokenWithResult<'a, Option<Datatype>> {
590 let parsed = parse_enum_keyword(parser, token);
591 if parsed.1.is_some() { return parsed }
592
593 let parsed = parse_enum_shorthand(parser, token, key);
594 if parsed.1.is_some() { return parsed }
595
596 (Some(token), None)
597}
598
599fn parse_nil_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
600 if !matches!(token, Token::Nil) { return (Some(token), None) }
601
602 (parser.advance(), Some(Datatype::None))
603}
604
605fn parse_boolean_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
606 match token {
607 Token::BoolTrue => {
608 (parser.advance(), Some(Datatype::Variant(Variant::Bool(true))))
609 },
610 Token::BoolFalse => {
611 (parser.advance(), Some(Datatype::Variant(Variant::Bool(false))))
612 },
613 _ => (Some(token), None)
614 }
615}
616
617#[allow(warnings)]
618fn parse_preset_tailwind_color<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
619 if let Token::ColorTailwind = token {
620 let color_name = parser.slice();
621 let datatype = TAILWIND_COLORS.get(&color_name.to_lowercase())
622 .and_then(|color| Some(Datatype::Oklab(**color.deref())));
623
624 return (parser.advance(), datatype)
625 }
626
627 (Some(token), None)
628}
629
630#[allow(warnings)]
631fn parse_preset_skin_color<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
632 if let Token::ColorSkin = token {
633 let color_name = parser.slice();
634 let datatype = SKIN_COLORS.get(&color_name.to_lowercase())
635 .and_then(|color| Some(Datatype::Oklab(**color.deref())));
636
637 return (parser.advance(), datatype)
638 }
639
640 (Some(token), None)
641}
642
643#[allow(warnings)]
644fn parse_preset_css_color<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
645 if let Token::ColorCss = token {
646 let color_name = parser.slice();
647 let datatype = CSS_COLORS.get(&color_name.to_lowercase())
648 .and_then(|color| Some(Datatype::Oklab(**color.deref())));
649
650 return (parser.advance(), datatype)
651 }
652
653 (Some(token), None)
654}
655
656#[allow(warnings)]
657fn parse_preset_brick_color<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
658 if let Token::ColorBrick = token {
659 let color_name = parser.slice();
660 let datatype = BRICK_COLORS.get(&color_name.to_lowercase())
661 .and_then(|color| Some(Datatype::Oklab(**color.deref())));
662
663 return (parser.advance(), datatype)
664 }
665
666 (Some(token), None)
667}
668
669fn parse_preset_color_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
670 let parsed = parse_preset_tailwind_color(parser, token);
671 if parsed.1.is_some() { return parsed }
672
673 let parsed = parse_preset_skin_color(parser, token);
674 if parsed.1.is_some() { return parsed }
675
676 let parsed = parse_preset_css_color(parser, token);
677 if parsed.1.is_some() { return parsed }
678
679 let parsed = parse_preset_brick_color(parser, token);
680 if parsed.1.is_some() { return parsed }
681
682 return (Some(token), None)
683}
684
685fn normalize_hex(hex: &str) -> String {
686 let hex = hex.trim_start_matches('#');
687
688 match hex.len() {
689 3 | 6 => hex.into(),
690 1..=5 => format!("{:0<6}", hex),
691 _ => hex.into(),
692 }
693}
694
695fn parse_hex_color_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
696 if let Token::ColorHex = token {
697 let hex = parser.slice();
698
699 let color: Srgb<u8> = normalize_hex(hex).parse().unwrap();
700 let datatype = Datatype::Variant(Variant::Color3(
701 Color3uint8::new(color.red, color.green, color.blue).into(),
702 ));
703
704 return (parser.advance(), Some(datatype))
705 }
706
707 return (None, None)
708}
709
710fn parse_color_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
711 let parsed = parse_preset_color_datatype(parser, token);
712 if parsed.1.is_some() { return parsed }
713
714 let parsed = parse_hex_color_datatype(parser, token);
715 if parsed.1.is_some() { return parsed }
716
717 return (Some(token), None)
718}
719
720fn parse_attribute_reference_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
721 if !matches!(token, Token::AttributeIdentifier) { return (Some(token), None) }
722
723 let token = guarded_unwrap!(parser.advance(), return (None, None));
724
725 if let Token::Text = token {
726 let attribute_name = parser.slice();
727 return (parser.advance(), Some(Datatype::Variant(Variant::String(format!("${}", attribute_name)))))
728 }
729
730 (Some(token), None)
731}
732
733fn resolve_static_attribute_reference<'a>(parser: &mut Parser<'a>, static_name: &str, tree_node_idx: TreeNodeType) -> Datatype {
734 let tree_node = parser.tree_nodes.get(tree_node_idx);
735
736 match tree_node {
737 AnyTreeNode::Root(node) => {
738 let resolved = node.unwrap().static_attributes.get(static_name);
739
740 match resolved {
741 Some(datatype) => datatype.clone(),
742
743 None => Datatype::None
744 }
745 },
746
747 AnyTreeNode::Node(node) => {
748 let node = node.unwrap();
749 let resolved = node.static_attributes.get(static_name);
750
751 match resolved {
752 Some(datatype) => datatype.clone(),
753
754 None => resolve_static_attribute_reference(parser, static_name, node.parent)
755 }
756 }
757 }
758}
759
760fn parse_static_attribute_reference_datatype<'a>(parser: &mut Parser<'a>, token: Token) -> TokenWithResult<'a, Option<Datatype>> {
761 if !matches!(token, Token::StaticAttributeIdentifier) { return (Some(token), None) }
762
763 let token = guarded_unwrap!(parser.advance(), return (None, None));
764
765 if let Token::Text = token {
766 let static_name = parser.slice();
767
768 let resolved_datatype = resolve_static_attribute_reference(parser, static_name, parser.current_tree_node_idx);
769
770 return (parser.advance(), Some(resolved_datatype))
771 }
772
773 (Some(token), None)
774}
775
776fn parse_datatype<'a>(
777 parser: &mut Parser<'a>, mut token: Token, key: Option<&str>
778) -> TokenWithResult<'a, Option<Datatype>> {
779 if let (Some(tuple_token), current_tuple_idx) = parse_tuple_name(parser, token, None, None) {
780 token = tuple_token;
783
784 if let Some(current_tuple_idx) = current_tuple_idx {
785 let current_tuple = parser.get_tuple(current_tuple_idx).unwrap();
786
787 return (Some(token), Some(current_tuple.coerce_to_datatype()))
788 }
789 };
790
791 let parsed = parse_string_datatype(parser, token);
792 if parsed.1.is_some() { return parsed }
793
794 let parsed = parse_content_datatype(parser, token);
795 if parsed.1.is_some() { return parsed }
796
797 let parsed = parse_number_datatype(parser, token);
798 if parsed.1.is_some() { return parsed }
799
800 let parsed = parse_operator_datatype(parser, token);
801 if parsed.1.is_some() { return parsed }
802
803 let parsed = parse_enum_datatype(parser, token, key);
804 if parsed.1.is_some() { return parsed }
805
806 let parsed = parse_color_datatype(parser, token);
807 if parsed.1.is_some() { return parsed }
808
809 let parsed = parse_attribute_reference_datatype(parser, token);
810 if parsed.1.is_some() { return parsed }
811
812 let parsed = parse_static_attribute_reference_datatype(parser, token);
813 if parsed.1.is_some() { return parsed }
814
815 let parsed = parse_boolean_datatype(parser, token);
816 if parsed.1.is_some() { return parsed }
817
818 let parsed = parse_nil_datatype(parser, token);
819 if parsed.1.is_some() { return parsed }
820
821 (Some(token), None)
822}
823
824fn parse_datatype_group<'a>(
825 parser: &mut Parser<'a>, token: Token, key: Option<&str>,
826 mut datatype_group: Option<DatatypeGroup>, mut pending_operator: Option<Operator>
827) -> TokenWithResult<'a, Option<Datatype>> {
828 let (token, datatype) = parse_datatype(parser, token, key);
829
830 if let Some(datatype) = datatype {
831 if !matches!(datatype, Datatype::Operator(_)) {
835 if let Some(some_pending_operator) = pending_operator {
836 let mut datatypes_exists = DatatypeGroup::ensure_then_insert(
839 datatype_group,
840 Datatype::Operator(some_pending_operator)
841 );
842 pending_operator = None;
843 datatypes_exists.push(datatype.clone());
844 datatype_group = Some(datatypes_exists);
845
846 } else {
847 datatype_group = Some(DatatypeGroup::ensure_then_insert(datatype_group, datatype.clone()))
848 }
849 }
850
851 if let Some(some_token) = token {
852 if matches!(some_token, Token::ParensClose | Token::ScopeClose | Token::Comma | Token::SemiColon) {
853 return (token, datatype_group.and_then(|mut x| Some(x.coerce_to_datatype())));
854
855 } else {
856 if let Datatype::Operator(operator) = datatype {
857 if let Some(some_pending_operator) = pending_operator {
861 if some_pending_operator.can_merge_with(&operator) {
862 pending_operator = Some(some_pending_operator.merge_with(&operator))
863 } else {
864 datatype_group = Some(DatatypeGroup::ensure_then_insert(datatype_group, Datatype::Operator(some_pending_operator)));
865 pending_operator = Some(operator)
866 }
867 } else {
868 pending_operator = Some(operator)
869 }
870 }
871
872 return parse_datatype_group(parser, some_token, key, datatype_group, pending_operator);
873 }
874 } else {
875 return (token, datatype_group.and_then(|mut x| Some(x.coerce_to_datatype())));
876 }
877
878 } else {
879 return (token, datatype_group.and_then(|mut x| Some(x.coerce_to_datatype())))
880 }
881}
882
883fn parse_tuple_close<'a>(
884 parser: &mut Parser<'a>, token: Token,
885 current_tuple_idx: usize, root_tuple_idx: usize
886) -> Option<Token> {
887 if !matches!(token, Token::ParensClose) { return None }
888
889 let token = parser.advance();
890
891 let current_tuple = parser.get_tuple(current_tuple_idx).unwrap();
892 let parent_tuple_idx = current_tuple.parent;
893
894 if let Some(some_parent_tuple_idx) = parent_tuple_idx {
895 let datatype = current_tuple.coerce_to_datatype();
896 parser.get_tuple_mut(some_parent_tuple_idx).unwrap().push(datatype);
897
898 let token = guarded_unwrap!(token, return None);
899
900 let parsed = parse_tuple_delimiter(parser, token, some_parent_tuple_idx, root_tuple_idx);
901 if parsed.is_some() { return parsed }
902
903 let parsed = parse_tuple_close(parser, token, some_parent_tuple_idx, root_tuple_idx);
904 if parsed.is_some() { return parsed }
905
906 let parsed = parse_tuple_name(
907 parser, token, parent_tuple_idx, Some(root_tuple_idx)
908 );
909 if parsed.1.is_some() { return parsed.0 }
910 };
911
912 token
913}
914
915fn parse_tuple_datatype<'a>(
916 parser: &mut Parser<'a>, token: Token,
917 current_tuple_idx: usize, root_tuple_idx: usize
918) -> Option<Token> {
919 let (token, datatype) = parse_datatype_group(
920 parser, token, None, None, None
921 );
922
923 let datatype = guarded_unwrap!(datatype, return None);
924
925 let current_tuple = parser.get_tuple_mut(current_tuple_idx).unwrap();
926 current_tuple.push(datatype);
927
928 if let Some(token) = token {
929 let parsed = parse_tuple_delimiter(parser, token, current_tuple_idx, root_tuple_idx);
930 if parsed.is_some() { return parsed }
931
932 let parsed = parse_tuple_close(parser, token, current_tuple_idx, root_tuple_idx);
933 if parsed.is_some() { return parsed }
934
935 let parsed = parse_tuple_name(
936 parser, token, Some(current_tuple_idx), Some(root_tuple_idx)
937 );
938 if parsed.1.is_some() { return parsed.0 }
939 }
940
941 token
942}
943
944fn parse_tuple_delimiter<'a>(
945 parser: &mut Parser<'a>, token: Token,
946 current_tuple_idx: usize, root_tuple_idx: usize
947) -> Option<Token> {
948 if !matches!(token, Token::SemiColon | Token::Comma) { return None }
949
950 let token = parser.advance();
951
952 if let Some(token) = token {
953 let parsed = parse_tuple_delimiter(parser, token, current_tuple_idx, root_tuple_idx);
955 if parsed.is_some() { return parsed }
956
957 let parsed = parse_tuple_close(parser, token, current_tuple_idx, root_tuple_idx);
958 if parsed.is_some() { return parsed }
959
960 let parsed = parse_tuple_name(
961 parser, token, Some(current_tuple_idx), Some(root_tuple_idx)
962 );
963 if parsed.1.is_some() { return parsed.0 }
964
965 let parsed = parse_tuple_datatype(parser, token, current_tuple_idx, root_tuple_idx);
966 if parsed.is_some() { return parsed }
967 }
968
969 token
970}
971
972fn parse_tuple_open<'a>(
973 parser: &mut Parser<'a>, token: Token, tuple_name: Option<String>,
974 parent_tuple_idx: Option<usize>, root_tuple_idx: Option<usize>
975) -> TokenWithResult<'a, Option<usize>> {
976 if !matches!(token, Token::ParensOpen) { return (None, None) };
977
978 let current_tuple_idx = parser.push_tuple(
979 Tuple::new(tuple_name, parent_tuple_idx)
980 );
981
982 let token = guarded_unwrap!(parser.advance(), return (None, Some(current_tuple_idx)));
983
984 let root_tuple_idx = root_tuple_idx.unwrap_or(current_tuple_idx);
985
986 let parsed = parse_tuple_delimiter(parser, token, current_tuple_idx, root_tuple_idx);
987 if parsed.is_some() { return (parsed, Some(current_tuple_idx)) }
988
989 let parsed = parse_tuple_close(parser, token, current_tuple_idx, root_tuple_idx);
990 if parsed.is_some() { return (parsed, Some(current_tuple_idx)) }
991
992 let parsed = parse_tuple_name(
993 parser, token, Some(current_tuple_idx), Some(root_tuple_idx)
994 );
995 if parsed.0.is_some() { return (parsed.0, Some(current_tuple_idx)) }
996
997 let parsed = parse_tuple_datatype(parser, token, current_tuple_idx, root_tuple_idx);
998 if parsed.is_some() { return (parsed, Some(current_tuple_idx)) }
999
1000 (Some(token), Some(current_tuple_idx))
1001}
1002
1003fn parse_tuple_name<'a>(
1004 parser: &mut Parser<'a>, token: Token,
1005 parent_tuple_idx: Option<usize>, root_tuple_idx: Option<usize>
1006) -> TokenWithResult<'a, Option<usize>> {
1007 if let Token::Text = token {
1008 let tuple_name = parser.slice();
1009 let token = guarded_unwrap!(parser.advance(), return (None, None));
1010
1011 return parse_tuple_open(parser, token, Some(tuple_name.to_string()), parent_tuple_idx, root_tuple_idx)
1012
1013 } else {
1014 return parse_tuple_open(parser, token, None, parent_tuple_idx, root_tuple_idx)
1015 }
1016}
1017
1018fn parse_delimiters<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1019 if matches!(token, Token::SemiColon | Token::Comma) {
1020 let token = parser.advance()?;
1021 return parse_delimiters(parser, token);
1022 }
1023
1024 return Some(token)
1025}
1026
1027fn parse_property<'a>(parser: &mut Parser<'a>, mut token: Token) -> Option<Token> {
1028 if let Token::Text = token {
1029 let property_name = parser.slice();
1030 let selector_token = token;
1031
1032 token = parser.advance()?;
1033
1034 if !matches!(token, Token::Equals) {
1035 return parse_scope_selector(parser, token, Selector::new(property_name, selector_token))
1036 };
1037
1038 if let TreeNodeType::Node(node_idx) = parser.current_tree_node_idx {
1040 token = parser.advance()?;
1041
1042 let (token, datatype) = parse_datatype_group(
1043 parser, token, Some(property_name), None, None
1044 );
1045 let variant = datatype.and_then(|d| d.coerce_to_variant(Some(property_name)));
1046
1047 if let Some(variant) = variant {
1048 let current_tree_node = parser.tree_nodes[node_idx].as_mut().unwrap();
1049 current_tree_node.properties.insert(property_name.to_string(), variant);
1050 }
1051
1052 let token = guarded_unwrap!(token, return None);
1053 return parse_delimiters(parser, token);
1054
1055 } else {
1056 return Some(token)
1057 }
1058 }
1059
1060 Some(token)
1061}
1062
1063fn parse_static_attribute<'a>(parser: &mut Parser<'a>, mut token: Token) -> Option<Token> {
1064 if !matches!(token, Token::StaticAttributeIdentifier) { return Some(token) };
1065
1066 token = parser.advance()?;
1067
1068 if let Token::Text = token {
1069 let static_name = parser.slice();
1070 let next_token = parser.advance()?;
1071
1072 if !matches!(next_token, Token::Equals) { return Some(next_token) }
1073
1074 token = parser.advance()?;
1075
1076 let (token, datatype) = parse_datatype_group(
1077 parser, token, Some(static_name), None, None
1078 );
1079 let datatype = datatype.and_then(|d| d.coerce_to_static(Some(static_name)));
1080
1081 if let Some(datatype) = datatype {
1082 let current_tree_node = parser.tree_nodes.get_node_mut(parser.current_tree_node_idx);
1083 match current_tree_node {
1084 AnyTreeNodeMut::Root(node) => {
1085 node.unwrap().static_attributes.insert(static_name.to_string(), datatype)
1086 },
1087 AnyTreeNodeMut::Node(node) => {
1088 node.unwrap().static_attributes.insert(static_name.to_string(), datatype)
1089 }
1090 };
1091 }
1092
1093 let token = guarded_unwrap!(token, return None);
1094 return parse_delimiters(parser, token)
1095 }
1096
1097 Some(token)
1098}
1099
1100fn parse_attribute<'a>(parser: &mut Parser<'a>, mut token: Token) -> Option<Token> {
1101 if !matches!(token, Token::AttributeIdentifier) { return Some(token) };
1102
1103 token = parser.advance()?;
1104
1105 if let Token::Text = token {
1106 let attribute_name = parser.slice();
1107 let next_token = parser.advance()?;
1108
1109 if !matches!(next_token, Token::Equals) { return Some(next_token) }
1110
1111 token = parser.advance()?;
1112
1113 let (token, datatype) = parse_datatype_group(
1114 parser, token, Some(attribute_name), None, None
1115 );
1116 let variant = datatype.and_then(|d| d.coerce_to_variant(Some(attribute_name)));
1117
1118 if let Some(variant) = variant {
1119 let current_tree_node = parser.tree_nodes.get_node_mut(parser.current_tree_node_idx);
1120 match current_tree_node {
1121 AnyTreeNodeMut::Root(node) => {
1122 node.unwrap().attributes.insert(attribute_name.to_string(), variant)
1123 },
1124 AnyTreeNodeMut::Node(node) => {
1125 node.unwrap().attributes.insert(attribute_name.to_string(), variant)
1126 }
1127 };
1128 }
1129
1130 let token = guarded_unwrap!(token, return None);
1131 return parse_delimiters(parser, token)
1132 }
1133
1134 Some(token)
1135}
1136
1137fn parse_priority_declaration<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1138 if !matches!(token, Token::PriorityDeclaration) { return Some(token) }
1139
1140 let token = parser.advance()?;
1141
1142 if let TreeNodeType::Node(node_idx) = parser.current_tree_node_idx {
1144 let (token, datatype) = parse_datatype_group(parser, token, None, None, None);
1145
1146 if let Some(Datatype::Variant(Variant::Float32(float32))) = datatype {
1147 let current_tree_node = parser.tree_nodes[node_idx].as_mut().unwrap();
1148 current_tree_node.priority = Some(float32 as i32);
1149 }
1150
1151 let token = guarded_unwrap!(token, return None);
1152 parse_delimiters(parser, token)
1153
1154 } else {
1155 Some(token)
1156 }
1157}
1158
1159fn parse_name_declaration<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1160 if !matches!(token, Token::NameDeclaration) { return Some(token) }
1161
1162 let token = parser.advance()?;
1163
1164 if let TreeNodeType::Node(node_idx) = parser.current_tree_node_idx {
1166 let (token, datatype) = parse_datatype_group(
1167 parser, token, None, None, None
1168 );
1169
1170 if let Some(Datatype::Variant(Variant::String(name))) = datatype {
1171 let current_tree_node = parser.tree_nodes[node_idx].as_mut().unwrap();
1172 current_tree_node.name = Some(name);
1173 }
1174
1175 let token = guarded_unwrap!(token, return None);
1176 parse_delimiters(parser, token)
1177
1178 } else {
1179 Some(token)
1180 }
1181}
1182
1183fn parse_tween_declaration<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1184 if !matches!(token, Token::TweenDeclaration) { return Some(token) }
1185
1186 let token = parser.advance()?;
1187
1188 if !matches!(token, Token::Text) { return Some(token) }
1190 let tween_name = parser.slice();
1191
1192 let token = parser.advance()?;
1193
1194 if let TreeNodeType::Node(node_idx) = parser.current_tree_node_idx {
1196 let (token, datatype) = parse_datatype_group(parser, token, None, None, None);
1197
1198 if let Some(datatype) = datatype {
1199 let current_tree_node = parser.tree_nodes[node_idx].as_mut().unwrap();
1200 current_tree_node.tweens.insert(tween_name.to_string(), datatype);
1201 }
1202
1203 let token = guarded_unwrap!(token, return None);
1204 parse_delimiters(parser, token)
1205 } else {
1206 Some(token)
1207 }
1208}
1209
1210fn parse_ignore_derive_declaration<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1211 if !matches!(token, Token::DeriveDeclaration) { return Some(token) }
1212
1213 let token = parser.core_advance()?;
1214 if !matches!(token, Token::Text) { return Some(token) }
1215
1216 let token = parser.core_advance()?;
1217
1218 parse_ignore_tuple_open(parser, token)
1219}
1220
1221fn parse_ignore_scope_open<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1223 if !matches!(token, Token::ScopeOpen) { return Some(token) }
1224
1225 let mut nestedness = 0usize;
1226
1227 loop {
1228 match parser.core_advance()? {
1229 Token::ScopeOpen => nestedness += 1,
1230 Token::ScopeClose => match nestedness {
1231 0 => return parser.advance(),
1233 _ => nestedness -= 1
1234 },
1235 _ => ()
1236 }
1237 }
1238}
1239
1240fn parse_util_declaration<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1242 if !matches!(token, Token::UtilDeclaration) { return Some(token) }
1243
1244 let token = parser.core_advance()?;
1245 if !matches!(token, Token::Text) { return Some(token) }
1246
1247 let token = parser.core_advance()?;
1248 parse_ignore_scope_open(parser, token)
1249}
1250
1251fn parse_ignore_tuple_open<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1253 if !matches!(token, Token::ParensOpen) { return Some(token) }
1254
1255 let mut nestedness = 0usize;
1256
1257 loop {
1258 match parser.core_advance()? {
1259 Token::ParensOpen => nestedness += 1,
1260 Token::ParensClose => match nestedness {
1261 0 => return parser.advance(),
1263 _ => nestedness -= 1
1264 },
1265 _ => ()
1266 }
1267 }
1268}
1269
1270fn parse_macro_declaration<'a>(parser: &mut Parser<'a>, token: Token) -> Option<Token> {
1272 if !matches!(token, Token::MacroDeclaration) { return Some(token) }
1273
1274 let token = parser.core_advance()?;
1275 if !matches!(token, Token::Text) { return Some(token) }
1276
1277 let token = parser.core_advance()?;
1278
1279 let token = parse_ignore_tuple_open(parser, token)?;
1280
1281 parse_ignore_scope_open(parser, token)
1282}
1283
1284fn main_loop<'a>(parser: &mut Parser<'a>) -> Option<()> {
1285 let mut token = parser.advance()?;
1286
1287 loop {
1288 parser.did_advance = false;
1289
1290 token = parse_attribute(parser, token)?;
1291 token = parse_static_attribute(parser, token)?;
1292 token = parse_property(parser, token)?;
1293 token = parse_scope_selector_start(parser, token)?;
1294 token = parse_scope_open(parser, token, None)?;
1295 token = parse_scope_close(parser, token)?;
1296 token = parse_priority_declaration(parser, token)?;
1297 token = parse_name_declaration(parser, token)?;
1298 token = parse_tween_declaration(parser, token)?;
1299 token = parse_ignore_derive_declaration(parser, token)?;
1300 token = parse_util_declaration(parser, token)?;
1301 token = parse_macro_declaration(parser, token)?;
1302
1303 if !parser.did_advance {
1306 token = guarded_unwrap!(parser.advance(), break)
1307 }
1308 }
1309
1310 None
1311}
1312
1313pub fn parse_rsml<'a>(lexer: &'a mut logos::Lexer<'a, Token>, macros: &'a MacroGroup) -> TreeNodeGroup {
1314 let mut parser = Parser::<'a>::new(lexer, macros);
1315
1316 main_loop(&mut parser);
1317
1318 return parser.tree_nodes;
1319}