1use crate::components::error_message::help_data::HelpData;
2use crate::components::error_message::help_message::ErrorMsg;
3use crate::components::error_message::syntax_error::SyntaxError;
4use crate::components::language::argument_value::ArgumentValue;
5use crate::components::language::operators::op;
6use crate::components::language::operators::Op;
7use crate::components::language::var::Var;
8use crate::components::language::Lang;
9use crate::components::r#type::argument_type::ArgumentType;
10use crate::components::r#type::Type;
11use crate::processes::parsing::base_parse;
12use crate::processes::parsing::lang_token::LangToken;
13use crate::processes::parsing::operation_priority::PriorityTokens;
14use crate::processes::parsing::types::if_type;
15use crate::processes::parsing::types::label;
16use crate::processes::parsing::types::ltype;
17use crate::processes::parsing::types::pascal_case_no_space;
18use crate::processes::parsing::types::primitive_types;
19
20use crate::processes::parsing::vector_priority::VectorPriority;
21use crate::utils::builder;
22use nom::branch::alt;
23use nom::bytes::complete::escaped;
24use nom::bytes::complete::is_not;
25use nom::bytes::complete::tag;
26use nom::bytes::complete::take_while1;
27use nom::character::complete::alpha1;
28use nom::character::complete::alphanumeric1;
29use nom::character::complete::char;
30use nom::character::complete::digit1;
31use nom::character::complete::multispace0;
32use nom::character::complete::multispace1;
33use nom::character::complete::one_of;
34use nom::combinator::not;
35use nom::combinator::opt;
36use nom::combinator::recognize;
37use nom::multi::many0;
38use nom::multi::many1;
39use nom::sequence::delimited;
40use nom::sequence::preceded;
41use nom::sequence::terminated;
42use nom::IResult;
43use nom::Parser;
44use nom_locate::LocatedSpan;
45use std::process::exit;
46
47type Span<'a> = LocatedSpan<&'a str, String>;
48
49pub fn is_pascal_case(name: &str) -> bool {
50 let res = recognize(pascal_case_no_space).parse(name.into());
51 match res {
52 Ok((_, _)) => true,
53 Err(_) => false,
54 }
55}
56
57fn number_helper(s: Span) -> IResult<Span, Lang> {
58 let res = (opt(tag("-")), digit1, tag("."), digit1).parse(s);
59 match res {
60 Ok((s, (sign, d1, _dot, d2))) => {
61 let sign2 = sign.unwrap_or(LocatedSpan::new_extra("", d1.clone().extra));
62 let n = format!("{}{}.{}", sign2, d1, d2).parse::<f32>().unwrap();
63 Ok((
64 s,
65 Lang::Number {
66 value: n,
67 help_data: sign2.into(),
68 },
69 ))
70 }
71 Err(r) => Err(r),
72 }
73}
74
75pub fn number(s: Span) -> IResult<Span, Lang> {
76 terminated(number_helper, multispace0).parse(s)
77}
78
79fn integer(s: Span) -> IResult<Span, Lang> {
80 let res = terminated((opt(tag("-")), digit1), multispace0).parse(s);
81 match res {
82 Ok((s, (minus, d))) => {
83 let symbol = match minus {
84 Some(_) => "-",
85 None => "",
86 }
87 .to_string()
88 + d.as_ref();
89 Ok((
90 s,
91 Lang::Integer {
92 value: symbol.parse::<i32>().unwrap(),
93 help_data: d.into(),
94 },
95 ))
96 }
97 Err(r) => Err(r),
98 }
99}
100
101fn get_value(l: LocatedSpan<&str, String>) -> Lang {
102 match l.clone().into_fragment() {
103 "true" | "TRUE" => Lang::Bool {
104 value: true,
105 help_data: l.into(),
106 },
107 "false" | "FALSE" => Lang::Bool {
108 value: false,
109 help_data: l.into(),
110 },
111 _ => panic!("No other boolean notation alolwed"),
112 }
113}
114
115fn null_value(s: Span) -> IResult<Span, Lang> {
116 let res = alt((
117 terminated(terminated(tag("NULL"), not(body_char)), multispace0),
118 terminated(terminated(tag("null"), not(body_char)), multispace0),
119 ))
120 .parse(s);
121 match res {
122 Ok((s, n)) => Ok((s, Lang::Null(n.into()))),
123 Err(r) => Err(r),
124 }
125}
126
127fn na_value(s: Span) -> IResult<Span, Lang> {
128 let res = alt((
129 terminated(terminated(tag("NA"), not(body_char)), multispace0),
130 terminated(terminated(tag("na"), not(body_char)), multispace0),
131 ))
132 .parse(s);
133 match res {
134 Ok((s, n)) => Ok((s, Lang::NA(n.into()))),
135 Err(r) => Err(r),
136 }
137}
138
139fn boolean(s: Span) -> IResult<Span, Lang> {
140 let res = alt((
141 terminated(terminated(tag("true"), not(body_char)), multispace0),
142 terminated(terminated(tag("TRUE"), not(body_char)), multispace0),
143 terminated(terminated(tag("false"), not(body_char)), multispace0),
144 terminated(terminated(tag("FALSE"), not(body_char)), multispace0),
145 ))
146 .parse(s);
147 match res {
148 Ok((s, ls)) => Ok((s, get_value(ls))),
149 Err(r) => Err(r),
150 }
151}
152
153pub fn chars(s: Span) -> IResult<Span, Lang> {
154 terminated(alt((double_quotes, single_quotes)), multispace0).parse(s)
155}
156
157pub fn double_quotes(input: Span) -> IResult<Span, Lang> {
158 let res = delimited(
159 char('"'),
160 opt(escaped(is_not("\\\""), '\\', alt((char('"'), char('\''))))),
161 char('"'),
162 )
163 .parse(input);
164 match res {
165 Ok((s, st)) => {
166 let content = st.clone().map(|span| span.to_string()).unwrap_or_default();
167 let location = st
168 .map(|span| span.into())
169 .unwrap_or_else(|| s.clone().into());
170 Ok((
171 s,
172 Lang::Char {
173 value: content,
174 help_data: location,
175 },
176 ))
177 }
178 Err(r) => Err(r),
179 }
180}
181
182pub fn single_quotes(input: Span) -> IResult<Span, Lang> {
183 let res = delimited(
184 char('\''),
185 opt(escaped(is_not("\\'"), '\\', alt((char('"'), char('\''))))),
186 char('\''),
187 )
188 .parse(input);
189 match res {
190 Ok((s, st)) => {
191 let content = st.clone().map(|span| span.to_string()).unwrap_or_default();
192 let location = st
193 .map(|span| span.into())
194 .unwrap_or_else(|| s.clone().into());
195 Ok((
196 s,
197 Lang::Char {
198 value: content,
199 help_data: location,
200 },
201 ))
202 }
203 Err(r) => Err(r),
204 }
205}
206
207fn starting_char(s: Span) -> IResult<Span, (char, HelpData)> {
208 let res = one_of("abcdefghijklmnopqrstuvwxyz_")(s);
209 match res {
210 Ok((s, val)) => Ok((s.clone(), (val, s.into()))),
211 Err(r) => Err(r),
212 }
213}
214
215fn body_char(s: Span) -> IResult<Span, (char, HelpData)> {
216 let res = one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789")(s);
217 match res {
218 Ok((s, val)) => Ok((s.clone(), (val, s.into()))),
219 Err(r) => Err(r),
220 }
221}
222
223pub fn variable_exp(s: Span) -> IResult<Span, (String, HelpData)> {
224 let res = (starting_char, many0(body_char)).parse(s);
225 match res {
226 Ok((s, ((s1, h), v))) => {
227 let res2 = v.iter().map(|(val, _h)| *val).collect::<String>();
228 Ok((s, (format!("{}{}", s1, res2), h.clone())))
229 }
230 Err(r) => Err(r),
231 }
232}
233
234fn type_annotation(s: Span) -> IResult<Span, Type> {
235 delimited(tag("<"), ltype, tag(">")).parse(s)
236}
237
238pub enum Case {
239 Maj,
240 Min,
241}
242
243fn variable_exp_2(s: Span) -> IResult<Span, (String, Case, HelpData)> {
244 let res = variable_exp.parse(s);
245 match res {
246 Ok((s, (name, h))) => Ok((s, (name, Case::Min, h))),
247 Err(r) => Err(r),
248 }
249}
250
251fn pascal_case_2(s: Span) -> IResult<Span, (String, Case, HelpData)> {
252 let res = pascal_case.parse(s);
253 match res {
254 Ok((s, (name, h))) => Ok((s, (name, Case::Maj, h))),
255 Err(r) => Err(r),
256 }
257}
258
259fn quoted_variable(s: Span) -> IResult<Span, (String, Case, HelpData)> {
260 let res = delimited(char('`'), is_not("`"), char('`')).parse(s);
261
262 match res {
263 Ok((s, st)) => Ok((s, (format!("`{}`", st.clone()), Case::Min, st.into()))),
264 Err(r) => Err(r),
265 }
266}
267
268pub fn variable_recognizer(s: Span) -> IResult<Span, (String, HelpData)> {
269 let res = alt((quoted_variable, pascal_case_2, variable_exp_2)).parse(s);
270 match res {
271 Ok((s, (s1, _case, h))) => Ok((s, (s1, h))),
272 Err(r) => Err(r),
273 }
274}
275
276fn variable_helper(s: Span) -> IResult<Span, (Lang, Case)> {
277 let res = (
278 alt((quoted_variable, pascal_case_2, variable_exp_2)),
279 opt(type_annotation),
280 )
281 .parse(s);
282 match res {
283 Ok((s, ((v, case, h), typ))) => {
284 let res = Var::from_name(&v)
285 .set_type(typ.unwrap_or(builder::empty_type()))
286 .set_help_data(h);
287 Ok((s, (res.into(), case)))
288 }
289 Err(r) => Err(r),
290 }
291}
292
293pub fn variable(s: Span) -> IResult<Span, (Lang, Case)> {
294 terminated(variable_helper, multispace0).parse(s)
295}
296
297pub fn argument(s: Span) -> IResult<Span, ArgumentType> {
298 let variadic = (
300 terminated(tag("..."), multispace0),
301 terminated(label, multispace0),
302 terminated(tag(":"), multispace0),
303 ltype,
304 opt(terminated(tag(","), multispace0)),
305 )
306 .parse(s.clone());
307 if let Ok((s2, (_, e1, _, e2, _))) = variadic {
308 return Ok((s2, ArgumentType(e1, e2, false, true)));
309 }
310
311 let res = (
313 terminated(label, multispace0),
314 terminated(tag(":"), multispace0),
315 ltype,
316 opt(terminated(tag(","), multispace0)),
317 )
318 .parse(s);
319 match res {
320 Ok((s, (e1, _, e2, _))) => Ok((s, ArgumentType(e1, e2, false, false))),
321 Err(r) => Err(r),
322 }
323}
324
325fn equality_params(s: Span) -> IResult<Span, Span> {
326 terminated(alt((tag("="), tag(":"))), multispace0).parse(s)
327}
328
329fn argument_val(s: Span) -> IResult<Span, ArgumentValue> {
330 let res = (
331 terminated(alphanumeric1, multispace0),
332 equality_params,
333 single_element,
334 opt(terminated(tag(","), multispace0)),
335 )
336 .parse(s);
337 match res {
338 Ok((s, (e1, _, e2, _))) => Ok((s, ArgumentValue(e1.to_string(), e2))),
339 Err(r) => Err(r),
340 }
341}
342
343pub fn parse_block(input: Span) -> IResult<Span, Span> {
344 recognize(parse_nested_braces).parse(input)
345}
346
347fn parse_nested_braces(input: Span) -> IResult<Span, Span> {
348 recognize(delimited(
349 tag("{"),
350 many0(alt((
351 parse_nested_braces,
352 recognize(take_while1(|c| c != '{' && c != '}')),
353 ))),
354 tag("}"),
355 ))
356 .parse(input)
357}
358
359pub fn r_function(s: Span) -> IResult<Span, Lang> {
360 let res = (
361 terminated(alt((tag("function"), tag("\\"))), multispace0),
362 terminated(tag("("), multispace0),
363 many0(terminated(terminated(variable, opt(tag(","))), multispace0)),
364 terminated(tag(")"), multispace0),
365 terminated(parse_block, multispace0),
366 )
367 .parse(s);
368 match res {
369 Ok((_s, (id, _op, _args, _cl, _exp))) if *id.fragment() == "fn" => {
370 panic!("{}", SyntaxError::FunctionWithoutType(id.into()).display())
371 }
372 Ok((s, (id, _op, args, _cl, exp))) => {
373 let args = args.iter().map(|(arg, _)| arg).cloned().collect::<Vec<_>>();
374 Ok((
375 s,
376 Lang::RFunction {
377 parameters: args,
378 body: exp.to_string(),
379 help_data: id.into(),
380 },
381 ))
382 }
383 Err(r) => Err(r),
384 }
385}
386
387pub fn simple_function(s: Span) -> IResult<Span, Lang> {
388 let res = (
389 terminated(tag("fn"), multispace0),
390 terminated(tag("("), multispace0),
391 many0(argument),
392 terminated(tag(")"), multispace0),
393 opt(terminated(tag(":"), multispace0)),
394 opt(terminated(alt((if_type, ltype)), multispace0)),
395 scope,
397 )
398 .parse(s);
399 match res {
400 Ok((s, (_, _, args, _, Some(_), Some(typ), exp))) => Ok((
401 s,
402 Lang::Function {
403 parameters: args,
404 return_type: typ,
405 body: Box::new(exp),
406 help_data: HelpData::default(),
407 },
408 )),
409 Ok((_s, (_, _, _args, _cp, None, None, _exp))) => {
410 panic!("You forgot to specify the function return type: 'fn(...): Type'");
411 }
412 Ok((_s, (_, _, _args, _, Some(tag), None, _exp))) => {
413 panic!(
414 "{}",
415 SyntaxError::FunctionWithoutReturnType(tag.into()).display()
416 );
417 }
418 Ok((_s, (_, _, _args, _, None, Some(typ), _exp))) => {
419 eprintln!(
420 "The type '{}' should be preceded by a ':' :\n 'fn(...): {}'",
421 typ.clone(),
422 typ.clone()
423 );
424 exit(1)
425 }
426 Err(r) => Err(r),
427 }
428}
429
430fn function(s: Span) -> IResult<Span, Lang> {
431 simple_function.parse(s)
432}
433
434fn key_value(s: Span) -> IResult<Span, Lang> {
435 let res = (
436 recognize(variable),
437 terminated(tag("="), multispace0),
438 single_element,
439 )
440 .parse(s);
441 match res {
442 Ok((s, (v, _eq, el))) => Ok((
443 s,
444 Lang::KeyValue {
445 key: (*v).into(),
446 value: Box::new(el),
447 help_data: v.into(),
448 },
449 )),
450 Err(r) => Err(r),
451 }
452}
453
454fn values(s: Span) -> IResult<Span, Vec<Lang>> {
455 many0(terminated(
456 alt((key_value, parse_elements)),
457 terminated(opt(tag(",")), multispace0),
458 ))
459 .parse(s)
460}
461
462pub fn variable2(s: Span) -> IResult<Span, Lang> {
463 let res = variable.parse(s);
464 match res {
465 Ok((s, (lang, _))) => Ok((s, lang)),
466 Err(r) => Err(r),
467 }
468}
469
470fn array_indexing(s: Span) -> IResult<Span, Lang> {
471 let res = (alt((scope, variable2)), array).parse(s);
472
473 match res {
474 Ok((s, (lang1, lang2))) => Ok((
475 s,
476 Lang::ArrayIndexing {
477 identifier: Box::new(lang1.clone()),
478 indexing: Box::new(lang2),
479 help_data: lang1.into(),
480 },
481 )),
482 Err(r) => Err(r),
483 }
484}
485
486fn dataframe_exp(s: Span) -> IResult<Span, Lang> {
487 let res = (
488 alt((tag("data__frame"), tag("data.frame"))),
489 terminated(tag("("), multispace0),
490 many0(argument_val),
491 terminated(tag(")"), multispace0),
492 )
493 .parse(s);
494 match res {
495 Ok((s, (start, _, args, _))) => Ok((
496 s,
497 Lang::DataFrame {
498 value: args.clone(),
499 help_data: start.into(),
500 },
501 )),
502 Err(r) => Err(r),
503 }
504}
505
506fn function_application(s: Span) -> IResult<Span, Lang> {
507 let res = (
508 alt((scope, variable2)),
509 terminated(tag("("), multispace0),
510 values,
511 terminated(tag(")"), multispace0),
512 )
513 .parse(s);
514 match res {
515 Ok((s, (exp, _, v, _))) => Ok((
516 s,
517 Lang::FunctionApp {
518 identifier: Box::new(exp.clone()),
519 arguments: v.clone(),
520 help_data: exp.into(),
521 },
522 )),
523 Err(r) => Err(r),
524 }
525}
526
527fn array(s: Span) -> IResult<Span, Lang> {
528 let res = (
529 terminated(tag("["), multispace0),
530 values,
531 terminated(tag("]"), multispace0),
532 )
533 .parse(s);
534 match res {
535 Ok((s, (_, v, _))) => Ok((
536 s,
537 Lang::Array {
538 value: v.clone(),
539 help_data: v.into(),
540 },
541 )),
542 Err(r) => Err(r),
543 }
544}
545
546pub fn vector(s: Span) -> IResult<Span, Lang> {
547 let res = (
548 terminated(tag("c("), multispace0),
549 values,
550 terminated(tag(")"), multispace0),
551 )
552 .parse(s);
553 match res {
554 Ok((s, (_, v, _))) => Ok((
555 s,
556 Lang::Vector {
557 value: v.clone(),
558 help_data: v.into(),
559 },
560 )),
561 Err(r) => Err(r),
562 }
563}
564
565fn sequence(s: Span) -> IResult<Span, Lang> {
566 let res = (
567 terminated(tag("seq["), multispace0),
568 values,
569 terminated(tag("]"), multispace0),
570 )
571 .parse(s);
572 match res {
573 Ok((s, (_, v, _))) => Ok((
574 s,
575 Lang::Sequence {
576 body: v.clone(),
577 help_data: v.into(),
578 },
579 )),
580 Err(r) => Err(r),
581 }
582}
583
584fn constructor_call(s: Span) -> IResult<Span, Lang> {
585 let res = (
586 pascal_case,
587 terminated(tag(":"), multispace0),
588 terminated(tag("{"), multispace0),
589 many0(argument_val),
590 terminated(tag("}"), multispace0),
591 )
592 .parse(s);
593 match res {
594 Ok((s, ((name, h), _, _, args, _))) => Ok((
595 s,
596 Lang::ConstructorCall {
597 type_name: name,
598 fields: args,
599 help_data: h,
600 },
601 )),
602 Err(r) => Err(r),
603 }
604}
605
606fn array_constructor_call(s: Span) -> IResult<Span, Lang> {
607 let res = (
608 pascal_case,
609 tag(":["),
610 multispace0,
611 values,
612 terminated(tag("]"), multispace0),
613 )
614 .parse(s);
615 match res {
616 Ok((s, ((name, h), _, _, elems, _))) => Ok((
617 s,
618 Lang::ArrayConstructorCall {
619 type_name: name,
620 elements: elems,
621 help_data: h,
622 },
623 )),
624 Err(r) => Err(r),
625 }
626}
627
628fn record_identifier(s: Span) -> IResult<Span, Span> {
629 alt((tag("record"), tag("object"), tag("list"), tag(":"))).parse(s)
630}
631
632pub fn record(s: Span) -> IResult<Span, Lang> {
633 let res = (
634 opt(record_identifier),
635 terminated(alt((tag("{"), tag("("))), multispace0),
636 many0(argument_val),
637 terminated(alt((tag("}"), tag(")"))), multispace0),
638 )
639 .parse(s);
640 match res {
641 Ok((s, (Some(start), _, args, _))) => Ok((
642 s,
643 Lang::List {
644 value: args.clone(),
645 help_data: start.into(),
646 },
647 )),
648 Ok((_s, (None, _ob, args, _))) => {
649 if args.is_empty() {
650 panic!("Error: the scope shouldn't be empty")
651 } else {
652 eprintln!("{}", _s);
653 panic!("You forgot to put a record identifier before the bracket: ':{{...}}'");
654 }
655 }
656 Err(r) => Err(r),
657 }
658}
659
660fn pascal_case_helper(s: Span) -> IResult<Span, (String, HelpData)> {
661 let res = (one_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), alpha1).parse(s);
662 match res {
663 Ok((s, (t1, t2))) => Ok((s.clone(), (format!("{}{}", t1, t2), s.into()))),
664 Err(r) => Err(r),
665 }
666}
667
668fn pascal_case(s: Span) -> IResult<Span, (String, HelpData)> {
669 pascal_case_helper.parse(s)
670}
671
672fn union_constructor(s: Span) -> IResult<Span, Lang> {
673 let res = (
674 pascal_case,
675 terminated(tag("."), multispace0),
676 pascal_case,
677 opt((
678 terminated(tag(":"), multispace0),
679 terminated(tag("{"), multispace0),
680 many0(argument_val),
681 terminated(tag("}"), multispace0),
682 )),
683 )
684 .parse(s);
685 match res {
686 Ok((s, ((union_name, h), _, (variant_name, _), None))) => Ok((
687 s,
688 Lang::UnionConstructor {
689 union_name,
690 variant_name,
691 fields: vec![],
692 help_data: h,
693 },
694 )),
695 Ok((s, ((union_name, h), _, (variant_name, _), Some((_, _, fields, _))))) => Ok((
696 s,
697 Lang::UnionConstructor {
698 union_name,
699 variant_name,
700 fields,
701 help_data: h,
702 },
703 )),
704 Err(r) => Err(r),
705 }
706}
707
708fn parenthese_value(s: Span) -> IResult<Span, Lang> {
709 delimited(
710 terminated(tag("("), multispace0),
711 parse_elements,
712 terminated(tag(")"), multispace0),
713 )
714 .parse(s)
715}
716
717pub fn tag_exp(s: Span) -> IResult<Span, Lang> {
718 let res = terminated((tag("."), pascal_case, opt(parenthese_value)), multispace0).parse(s);
719 match res {
720 Ok((s, (dot, (n, _h), None))) => Ok((
721 s,
722 Lang::Tag {
723 name: n,
724 value: Box::new(Lang::Empty(dot.clone().into())),
725 help_data: dot.into(),
726 },
727 )),
728 Ok((s, (dot, (n, _h), Some(val)))) => Ok((
729 s,
730 Lang::Tag {
731 name: n,
732 value: Box::new(val),
733 help_data: dot.into(),
734 },
735 )),
736 Err(r) => Err(r),
737 }
738}
739
740fn dotdotdot(s: Span) -> IResult<Span, Lang> {
741 let res = terminated(tag("..."), multispace0).parse(s);
742 match res {
743 Ok((s, d)) => Ok((s, Lang::Empty(d.into()))),
744 Err(r) => Err(r),
745 }
746}
747
748fn else_exp(s: Span) -> IResult<Span, Lang> {
749 let res = (
750 terminated(tag("else"), multispace0),
751 terminated(tag("{"), multispace0),
752 parse_elements,
753 terminated(tag("}"), multispace0),
754 )
755 .parse(s);
756 match res {
757 Ok((s, (_else, _o, exp, _c))) => Ok((s, exp)),
758 Err(r) => Err(r),
759 }
760}
761
762fn else_if_exp(s: Span) -> IResult<Span, Lang> {
763 preceded(terminated(tag("else"), multispace1), if_exp).parse(s)
764}
765
766fn if_exp(s: Span) -> IResult<Span, Lang> {
767 let res = (
768 terminated(tag("if"), multispace0),
769 terminated(tag("("), multispace0),
770 parse_elements,
771 terminated(tag(")"), multispace0),
772 terminated(tag("{"), multispace0),
773 parse_elements,
774 terminated(tag("}"), multispace0),
775 opt(alt((else_if_exp, else_exp))),
776 )
777 .parse(s);
778 match res {
779 Ok((s, (_if, _op, cond, _cp, _o, exp, _c, els))) => Ok((
780 s,
781 Lang::If {
782 condition: Box::new(cond),
783 if_block: Box::new(exp),
784 else_block: Box::new(els.unwrap_or(Lang::Empty(HelpData::default()))),
785 help_data: _if.into(),
786 },
787 )),
788 Err(r) => Err(r),
789 }
790}
791
792fn tag_pattern_with_var(s: Span) -> IResult<Span, Lang> {
794 let res = (
795 tag("."),
796 pascal_case,
797 delimited(
798 terminated(tag("("), multispace0),
799 variable2,
800 terminated(tag(")"), multispace0),
801 ),
802 )
803 .parse(s);
804 match res {
805 Ok((s, (dot, (n, _h), var))) => Ok((
806 s,
807 Lang::Tag {
808 name: n,
809 value: Box::new(var),
810 help_data: dot.into(),
811 },
812 )),
813 Err(r) => Err(r),
814 }
815}
816
817fn tag_pattern_no_var(s: Span) -> IResult<Span, Lang> {
819 let res = (tag("."), pascal_case).parse(s);
820 match res {
821 Ok((s, (dot, (n, _h)))) => Ok((
822 s,
823 Lang::Tag {
824 name: n,
825 value: Box::new(Lang::Empty(dot.clone().into())),
826 help_data: dot.into(),
827 },
828 )),
829 Err(r) => Err(r),
830 }
831}
832
833fn wildcard_pattern(s: Span) -> IResult<Span, Lang> {
835 let res = terminated(tag("_"), multispace0).parse(s);
836 match res {
837 Ok((s, underscore)) => Ok((
838 s,
839 Lang::Variable {
840 name: "_".to_string(),
841 is_opaque: false,
842 related_type: builder::empty_type(),
843 help_data: underscore.into(),
844 },
845 )),
846 Err(r) => Err(r),
847 }
848}
849
850fn type_pattern(s: Span) -> IResult<Span, Lang> {
852 let res = (
853 terminated(variable_exp, multispace0),
854 terminated(tag("as"), multispace1),
855 terminated(primitive_types, multispace0),
856 )
857 .parse(s);
858 match res {
859 Ok((s, ((name, h), _as, typ))) => Ok((
860 s,
861 Lang::TypePattern {
862 variable_name: name,
863 matched_type: typ,
864 help_data: h,
865 },
866 )),
867 Err(r) => Err(r),
868 }
869}
870
871fn match_pattern(s: Span) -> IResult<Span, Lang> {
873 terminated(
874 alt((
875 tag_pattern_with_var,
876 tag_pattern_no_var,
877 record,
878 tuple_exp,
879 type_pattern,
880 wildcard_pattern,
881 variable2,
882 )),
883 multispace0,
884 )
885 .parse(s)
886}
887
888fn pattern_branch(s: Span) -> IResult<Span, (Lang, Box<Lang>)> {
890 let res = (
891 terminated(match_pattern, multispace0),
892 terminated(tag("=>"), multispace0),
893 terminated(parse_elements, multispace0),
894 opt(terminated(tag(","), multispace0)),
895 )
896 .parse(s);
897 match res {
898 Ok((s, (pat, _arr, lang, _vir))) => Ok((s, (pat, Box::new(lang)))),
899 Err(r) => Err(r),
900 }
901}
902
903fn match_exp(s: Span) -> IResult<Span, Lang> {
906 let res = (
907 terminated(tag("match"), multispace1),
908 terminated(alt((scope, variable2)), multispace0),
909 terminated(tag("{"), multispace0),
910 many1(pattern_branch),
911 terminated(tag("}"), multispace0),
912 )
913 .parse(s);
914 match res {
915 Ok((s, (_m, exp, _o, bs, _c))) => Ok((
916 s,
917 Lang::Match {
918 target: Box::new(exp),
919 branches: bs,
920 help_data: _m.into(),
921 },
922 )),
923 Err(r) => Err(r),
924 }
925}
926
927pub fn tuple_exp(s: Span) -> IResult<Span, Lang> {
928 let res = (
929 terminated(alt((tag("list"), tag(":"))), multispace0),
930 terminated(alt((tag("{"), tag("("))), multispace0),
931 values,
932 terminated(alt((tag("}"), tag(")"))), multispace0),
933 )
934 .parse(s);
935 match res {
936 Ok((s, (id, _op, vals, _cl))) => Ok((
937 s,
938 Lang::Tuple {
939 value: vals,
940 help_data: id.into(),
941 },
942 )),
943 Err(r) => Err(r),
944 }
945}
946
947fn int_or_var(s: Span) -> IResult<Span, Lang> {
948 alt((integer, variable2)).parse(s)
949}
950
951fn create_range(params: &[Lang]) -> Lang {
952 if params.len() == 2 {
953 Lang::FunctionApp {
954 identifier: Box::new(Var::from_name("seq").to_language()),
955 arguments: vec![
956 params[0].clone(),
957 params[1].clone(),
958 Lang::Integer {
959 value: 1,
960 help_data: HelpData::default(),
961 },
962 ],
963 help_data: params.to_vec().into(),
964 }
965 } else {
966 Lang::FunctionApp {
967 identifier: Box::new(Var::from_name("seq").to_language()),
968 arguments: vec![params[0].clone(), params[1].clone(), params[2].clone()],
969 help_data: params.to_vec().into(),
970 }
971 }
972}
973
974fn range(s: Span) -> IResult<Span, Lang> {
975 let res = (
976 int_or_var,
977 tag(":"),
978 opt(terminated(int_or_var, tag(":"))),
979 int_or_var,
980 )
981 .parse(s);
982 match res {
984 Ok((s, (iv1, _sep, None, iv2))) => Ok((s, create_range(&[iv1.clone(), iv2.clone()]))),
985 Ok((s, (iv1, _sep, Some(iv0), iv2))) => {
986 Ok((s, create_range(&[iv1.clone(), iv2.clone(), iv0.clone()])))
987 }
988 Err(r) => Err(r),
989 }
990}
991
992fn function_application2(s: Span) -> IResult<Span, Lang> {
993 let res = recognize(function_application).parse(s);
994 match res {
995 Ok((s, fun_app)) => Ok((
996 s,
997 Lang::Exp {
998 value: fun_app.to_string(),
999 help_data: fun_app.into(),
1000 },
1001 )),
1002 Err(r) => Err(r),
1003 }
1004}
1005
1006fn dot_variable(s: Span) -> IResult<Span, Lang> {
1007 let res = preceded(tag("."), variable2).parse(s);
1008 match res {
1009 Ok((
1010 s,
1011 Lang::Variable {
1012 name: n,
1013 is_opaque: b,
1014 related_type: c,
1015 help_data: d,
1016 },
1017 )) => Ok((
1018 s,
1019 Lang::Variable {
1020 name: format!(".{}", n),
1021 is_opaque: b,
1022 related_type: c,
1023 help_data: d,
1024 },
1025 )),
1026 Ok((_s, _)) => todo!(),
1027 Err(r) => Err(r),
1028 }
1029}
1030
1031fn element_operator2(s: Span) -> IResult<Span, (Lang, Op)> {
1032 let res = (
1033 opt(op),
1034 alt((
1035 function_application2,
1036 null_value,
1037 number,
1038 integer,
1039 chars,
1040 boolean,
1041 variable2,
1042 dot_variable,
1043 )),
1044 )
1045 .parse(s);
1046 match res {
1047 Ok((s, (Some(ope), ele))) => Ok((s, (ele, ope))),
1048 Ok((s, (None, ele))) => Ok((s.clone(), (ele, Op::Empty(s.into())))),
1049 Err(r) => Err(r),
1050 }
1051}
1052
1053fn vectorial_bloc(s: Span) -> IResult<Span, Lang> {
1054 let res = (
1055 terminated(tag("@{"), multispace0),
1056 recognize(many1(element_operator2)),
1057 terminated(tag("}@"), multispace0),
1058 )
1059 .parse(s);
1060 match res {
1061 Ok((s, (_start, bloc, _end))) => Ok((
1062 s,
1063 Lang::VecBlock {
1064 value: bloc.fragment().to_string(),
1065 help_data: bloc.into(),
1066 },
1067 )),
1068 Err(r) => Err(r),
1069 }
1070}
1071
1072fn lambda(s: Span) -> IResult<Span, Lang> {
1073 let res = (
1074 tag("\\"),
1075 terminated(tag("("), multispace0),
1076 many0(terminated(variable, opt((tag(","), multispace0)))),
1077 terminated(tag(")"), multispace0),
1078 parse_elements,
1079 )
1080 .parse(s);
1081 match res {
1082 Ok((s, (start, _, v, _, body))) => Ok((
1083 s,
1084 Lang::Lambda {
1085 parameters: v.iter().map(|(var, _)| var).cloned().collect(),
1086 body: Box::new(body.clone()),
1087 help_data: start.into(),
1088 },
1089 )),
1090 Err(r) => Err(r),
1091 }
1092}
1093
1094fn not_exp(s: Span) -> IResult<Span, Lang> {
1095 let res = (
1096 tag("!"),
1097 alt((
1098 tag_exp,
1099 range,
1100 lambda,
1101 boolean,
1102 number,
1103 integer,
1104 chars,
1105 match_exp,
1106 if_exp,
1107 dotdotdot,
1108 vector,
1109 record,
1110 r_function,
1111 function,
1112 tuple_exp,
1113 function_application,
1114 array_indexing,
1115 variable2,
1116 scope,
1117 array,
1118 )),
1119 )
1120 .parse(s);
1121 match res {
1122 Ok((s, (not_op, lang))) => Ok((
1123 s,
1124 Lang::Not {
1125 value: Box::new(lang),
1126 help_data: not_op.into(),
1127 },
1128 )),
1129 Err(r) => Err(r),
1130 }
1131}
1132
1133fn array_variant(s: Span) -> IResult<Span, Lang> {
1134 alt((vector, sequence)).parse(s)
1135}
1136
1137fn js_block(s: Span) -> IResult<Span, Lang> {
1138 let res = (terminated(tag("JS"), multispace0), scope).parse(s);
1139
1140 match res {
1141 Ok((s, (js, body))) => Ok((s, Lang::JSBlock(Box::new(body), 0, js.into()))),
1142 Err(r) => Err(r),
1143 }
1144}
1145
1146fn primitive(s: Span) -> IResult<Span, Lang> {
1147 alt((null_value, na_value, boolean, number, integer, chars)).parse(s)
1148}
1149
1150pub fn return_exp(s: Span) -> IResult<Span, Lang> {
1151 let res = terminated(
1152 delimited(tag("return "), parse_elements, tag(";")),
1153 multispace0,
1154 )
1155 .parse(s);
1156 match res {
1157 Ok((s, el)) => Ok((
1158 s,
1159 Lang::Return {
1160 value: Box::new(el.clone()),
1161 help_data: el.into(),
1162 },
1163 )),
1164 Err(r) => Err(r),
1165 }
1166}
1167
1168pub fn break_exp(s: Span) -> IResult<Span, Vec<Lang>> {
1169 let res = tag("break;").parse(s);
1170 match res {
1171 Ok((s, el)) => Ok((s, vec![Lang::Break(el.into())])),
1172 Err(r) => Err(r),
1173 }
1174}
1175
1176pub fn single_element(s: Span) -> IResult<Span, Lang> {
1178 alt((
1179 alt((
1180 not_exp,
1181 tag_exp,
1182 union_constructor,
1183 range,
1184 lambda,
1185 primitive,
1186 js_block,
1187 return_exp,
1188 match_exp,
1189 if_exp,
1190 dotdotdot,
1191 array_variant,
1192 )),
1193 alt((
1194 dataframe_exp,
1195 array_constructor_call,
1196 constructor_call,
1197 record,
1198 r_function,
1199 function,
1200 tuple_exp,
1201 function_application,
1202 array_indexing,
1203 variable2,
1204 scope,
1205 array,
1206 )),
1207 ))
1208 .parse(s)
1209}
1210
1211pub fn scope(s: Span) -> IResult<Span, Lang> {
1212 let res = (
1213 terminated(alt((tag("("), tag("{"))), multispace0),
1214 opt(base_parse),
1215 terminated(
1216 preceded(multispace0, alt((tag(")"), tag("}")))),
1217 multispace0,
1218 ),
1219 )
1220 .parse(s);
1221 match res {
1222 Ok((s, (open, Some(v), _))) if v.is_empty() => Ok((
1223 s,
1224 Lang::Scope {
1225 body: vec![],
1226 help_data: open.into(),
1227 },
1228 )),
1229 Ok((s, (_, Some(v), _))) => Ok((
1230 s,
1231 Lang::Scope {
1232 body: v.clone(),
1233 help_data: v.into(),
1234 },
1235 )),
1236 Ok((s, (open, None, _))) => Ok((
1237 s,
1238 Lang::Scope {
1239 body: vec![],
1240 help_data: open.into(),
1241 },
1242 )),
1243 Err(r) => Err(r),
1244 }
1245}
1246
1247fn element_operator_token(s: Span) -> IResult<Span, LangToken> {
1248 match op.parse(s) {
1249 Ok((s, op)) => Ok((s, LangToken::Operator(op))),
1250 Err(r) => Err(r),
1251 }
1252}
1253
1254fn single_element_token(s: Span) -> IResult<Span, LangToken> {
1255 match single_element.parse(s) {
1256 Ok((s, op)) => Ok((s, LangToken::Expression(op))),
1257 Err(r) => Err(r),
1258 }
1259}
1260
1261fn as_excl_operator_token(s: Span) -> IResult<Span, LangToken> {
1262 let res = terminated(tag("as!"), multispace0).parse(s);
1263 match res {
1264 Ok((s, tok)) => Ok((s, LangToken::Operator(Op::AsExcl(tok.into())))),
1265 Err(r) => Err(r),
1266 }
1267}
1268
1269pub fn elements(s: Span) -> IResult<Span, Lang> {
1270 let res = many1(alt((as_excl_operator_token, single_element_token, element_operator_token))).parse(s);
1271 match res {
1272 Ok((s, v)) => {
1273 if v.len() == 1 {
1274 Ok((s, v[0].clone().into()))
1275 } else {
1276 Ok((s, VectorPriority::from(v).run()))
1277 }
1278 }
1279 Err(r) => Err(r),
1280 }
1281}
1282
1283pub fn parse_elements(s: Span) -> IResult<Span, Lang> {
1285 alt((vectorial_bloc, elements)).parse(s)
1286}
1287
1288#[cfg(test)]
1289mod tests {
1290 use super::*;
1291 use crate::utils::fluent_parser::FluentParser;
1292
1293 #[test]
1294 #[should_panic]
1295 fn test_empty_scope() {
1296 let _ = "{ }".parse::<Lang>();
1297 }
1298
1299 #[test]
1300 fn test_function_with_empty_scope3() {
1301 let res = simple_function("fn(): int { 5 }".into()).unwrap().1;
1302 assert_eq!(res.simple_print(), "Function");
1303 }
1304
1305 #[test]
1306 fn test_variable1() {
1307 let res = variable_exp("hello".into()).unwrap().1 .0;
1308 assert_eq!(res, "hello", "Should return the variable name 'hello'");
1309 }
1310
1311 #[test]
1312 fn test_simple_variable1() {
1313 let res = variable_exp("hello".into()).unwrap().1 .0;
1314 assert_eq!(res, "hello", "Should return the variable name 'hello'");
1315 }
1316
1317 #[test]
1318 fn test_addition1() {
1319 let res = "1 + 2".parse::<Lang>().unwrap();
1320 dbg!(&res);
1321 assert_eq!(res.simple_print(), "Operator", "Should parse 1 + 2");
1322 }
1323
1324 #[test]
1325 fn test_addition2() {
1326 let res = "1 + 2 + 3".parse::<Lang>().unwrap();
1327 dbg!(&res);
1328 assert_eq!(res.simple_print(), "Operator", "Should parse 1 + 2 + 3");
1329 }
1330
1331 #[test]
1332 fn test_multiplication1() {
1333 let res = "1 + 2 * 3".parse::<Lang>().unwrap();
1334 dbg!(&res);
1335 assert_eq!(
1336 res.simple_print(),
1337 "Operator",
1338 "Should put multiplication first 1 + 2 * 3"
1339 );
1340 }
1341
1342 #[test]
1343 fn test_multiplication2() {
1344 let res = "1 * 2 + 3".parse::<Lang>().unwrap();
1345 dbg!(&res);
1346 assert_eq!(
1347 res.simple_print(),
1348 "Operator",
1349 "Should put multiplication first 1 * 2 + 3"
1350 );
1351 }
1352
1353 #[test]
1354 fn test_multiplication3() {
1355 let res = "1 * 2 + 3 * 4".parse::<Lang>().unwrap();
1356 dbg!(&res);
1357 assert_eq!(
1358 res.simple_print(),
1359 "Operator",
1360 "Should put multiplication first 1 * 2 + 3 * 4"
1361 );
1362 }
1363
1364 #[test]
1365 fn test_accessor1() {
1366 let res = "3 + personne$age ".parse::<Lang>().unwrap();
1367 dbg!(&res);
1368 assert_eq!(
1369 res.simple_print(),
1370 "Operator",
1371 "Should put multiplication first 1 * 2 + 3 * 4"
1372 );
1373 }
1374
1375 #[test]
1376 fn test_and1() {
1377 let res = "true & true".parse::<Lang>().unwrap();
1378 dbg!(&res);
1379 assert_eq!(res.simple_print(), "Operator", "Should accept '&&'");
1380 }
1381
1382 #[test]
1383 fn test_array_indexing0() {
1384 let res = array_indexing("name[1, 2, 3]".into()).unwrap().1;
1385 dbg!(&res);
1386 assert!(true);
1387 }
1388
1389 #[test]
1390 fn test_array_indexing() {
1391 let fp = FluentParser::new().push("name[1, 2, 3]").parse_next();
1392 println!("fp: {}", fp);
1393 assert!(true);
1394 }
1395
1396 #[test]
1397 fn test_quoted_variable() {
1398 let res = quoted_variable("`+`".into()).unwrap().1;
1399 assert_eq!(res.0, "`+`");
1400 }
1401
1402 #[test]
1403 fn test_uniform_function_call() {
1404 let res = FluentParser::new().push("true.not()").parse_next();
1405 dbg!(&res.next_code());
1406 assert!(true);
1407 }
1408
1409 #[test]
1410 fn test_key_value1() {
1411 let res = key_value("sep = '3'".into()).unwrap().1;
1412 dbg!(&res);
1413 assert!(true);
1414 }
1415
1416 #[test]
1417 fn test_empty_char0() {
1418 let res = single_element("''".into()).unwrap().1;
1419 dbg!(&res);
1420 assert!(true);
1421 }
1422
1423 #[test]
1424 fn test_empty_char1() {
1425 let res = primitive("''".into()).unwrap().1;
1426 dbg!(&res);
1427 assert!(true);
1428 }
1429
1430 #[test]
1431 fn test_empty_char2() {
1432 let res = chars("''".into()).unwrap().1;
1433 dbg!(&res);
1434 assert!(true);
1435 }
1436
1437 #[test]
1440 fn test_null_value_lowercase() {
1441 let res = null_value("null ".into()).unwrap().1;
1442 assert_eq!(res.simple_print(), "Null");
1443 }
1444
1445 #[test]
1446 fn test_null_value_uppercase() {
1447 let res = null_value("NULL ".into()).unwrap().1;
1448 assert_eq!(res.simple_print(), "Null");
1449 }
1450
1451 #[test]
1452 fn test_null_via_primitive() {
1453 let res = primitive("null ".into()).unwrap().1;
1454 assert_eq!(res.simple_print(), "Null");
1455 }
1456
1457 #[test]
1458 fn test_null_via_single_element() {
1459 let res = single_element("null ".into()).unwrap().1;
1460 assert_eq!(res.simple_print(), "Null");
1461 }
1462
1463 #[test]
1464 fn test_null_parse_lang() {
1465 let res = "null".parse::<Lang>().unwrap();
1466 assert_eq!(res.simple_print(), "Null");
1467 }
1468
1469 #[test]
1470 fn test_null_type_check() {
1471 let fp = FluentParser::new()
1472 .push("let x: null <- null;")
1473 .parse_type_next()
1474 .push("x")
1475 .parse_next();
1476 assert_eq!(fp.get_last_type(), crate::utils::builder::null_type());
1477 }
1478
1479 #[test]
1482 fn test_match_pattern_tag_with_binding() {
1483 let input = "match x { .Some(a) => a, .None => 0 }";
1484 let res = match_exp(input.into()).unwrap().1;
1485 dbg!(&res);
1486 assert_eq!(res.simple_print(), "Match");
1487 }
1488
1489 #[test]
1490 fn test_match_pattern_with_wildcard() {
1491 let input = "match x { .Some(a) => a, _ => 0 }";
1492 let res = match_exp(input.into()).unwrap().1;
1493 dbg!(&res);
1494 assert_eq!(res.simple_print(), "Match");
1495 }
1496
1497 #[test]
1498 fn test_match_pattern_tag_without_binding() {
1499 let input = "match x { .None => 7 }";
1500 let res = match_exp(input.into()).unwrap().1;
1501 assert_eq!(res.simple_print(), "Match");
1502 }
1503
1504 #[test]
1505 fn test_match_pattern_multiple_branches() {
1506 let input = "match value { .Some(a) => a + 1, .None => 0, _ => 9 }";
1507 let res = match_exp(input.into()).unwrap().1;
1508 assert_eq!(res.simple_print(), "Match");
1509 if let Lang::Match { branches, .. } = &res {
1511 assert_eq!(branches.len(), 3, "Should have 3 branches");
1512 } else {
1513 panic!("Expected Match variant");
1514 }
1515 }
1516
1517 #[test]
1518 fn test_match_pattern_via_single_element() {
1519 let input = "match x { .Some(a) => a, .None => 0 } ";
1520 let res = single_element(input.into()).unwrap().1;
1521 assert_eq!(res.simple_print(), "Match");
1522 }
1523
1524 #[test]
1525 fn test_match_pattern_branch_tag_with_var() {
1526 let input = ".Some(a) => a + 1, ";
1527 let res = pattern_branch(input.into()).unwrap().1;
1528 let (pattern, _body) = res;
1529 assert_eq!(pattern.simple_print(), "Tag");
1530 }
1531
1532 #[test]
1533 fn test_match_pattern_branch_wildcard() {
1534 let input = "_ => 42 ";
1535 let res = pattern_branch(input.into()).unwrap().1;
1536 let (pattern, _body) = res;
1537 assert_eq!(pattern.simple_print(), "Variable(_)");
1538 }
1539
1540 #[test]
1541 fn test_match_pattern_branch_tag_no_binding() {
1542 let input = ".None => 7, ";
1543 let res = pattern_branch(input.into()).unwrap().1;
1544 let (pattern, body) = res;
1545 assert_eq!(pattern.simple_print(), "Tag");
1546 assert_eq!(body.simple_print(), "Integer");
1547 }
1548
1549 #[test]
1550 fn test_wildcard_pattern() {
1551 let input = "_ ";
1552 let res = wildcard_pattern(input.into()).unwrap().1;
1553 assert_eq!(res.simple_print(), "Variable(_)");
1554 }
1555
1556 #[test]
1557 fn test_tag_pattern_with_var() {
1558 let input = ".Some(a)";
1559 let res = tag_pattern_with_var(input.into()).unwrap().1;
1560 assert_eq!(res.simple_print(), "Tag");
1561 if let Lang::Tag {
1562 name, value: inner, ..
1563 } = &res
1564 {
1565 assert_eq!(name, "Some");
1566 assert_eq!(inner.simple_print(), "Variable(a)");
1567 } else {
1568 panic!("Expected Tag variant");
1569 }
1570 }
1571
1572 #[test]
1573 fn test_tag_pattern_no_var() {
1574 let input = ".None ";
1575 let res = tag_pattern_no_var(input.into()).unwrap().1;
1576 assert_eq!(res.simple_print(), "Tag");
1577 if let Lang::Tag {
1578 name, value: inner, ..
1579 } = &res
1580 {
1581 assert_eq!(name, "None");
1582 assert_eq!(inner.simple_print(), "Empty");
1583 } else {
1584 panic!("Expected Tag variant");
1585 }
1586 }
1587
1588 #[test]
1589 fn test_match_pattern_multiline() {
1590 let input = "match result {
1591 .Some(value) => value + 1,
1592 .None => 0,
1593 _ => 99
1594 } ";
1595 let res = match_exp(input.into()).unwrap().1;
1596 assert_eq!(res.simple_print(), "Match");
1597 if let Lang::Match { branches, .. } = &res {
1598 assert_eq!(branches.len(), 3);
1599 } else {
1600 panic!("Expected Match variant");
1601 }
1602 }
1603
1604 #[test]
1607 fn test_type_pattern_int() {
1608 let input = "x as int ";
1609 let res = type_pattern(input.into()).unwrap().1;
1610 assert!(
1611 res.simple_print().starts_with("TypePattern"),
1612 "Should parse 'x as int' as TypePattern"
1613 );
1614 if let Lang::TypePattern {
1615 variable_name: name,
1616 ..
1617 } = &res
1618 {
1619 assert_eq!(name, "x");
1620 } else {
1621 panic!("Expected TypePattern variant");
1622 }
1623 }
1624
1625 #[test]
1626 fn test_type_pattern_bool() {
1627 let input = "y as bool ";
1628 let res = type_pattern(input.into()).unwrap().1;
1629 if let Lang::TypePattern {
1630 variable_name: name,
1631 ..
1632 } = &res
1633 {
1634 assert_eq!(name, "y");
1635 } else {
1636 panic!("Expected TypePattern variant");
1637 }
1638 }
1639
1640 #[test]
1641 fn test_type_pattern_num() {
1642 let input = "val as num ";
1643 let res = type_pattern(input.into()).unwrap().1;
1644 if let Lang::TypePattern {
1645 variable_name: name,
1646 ..
1647 } = &res
1648 {
1649 assert_eq!(name, "val");
1650 } else {
1651 panic!("Expected TypePattern variant");
1652 }
1653 }
1654
1655 #[test]
1656 fn test_type_pattern_char() {
1657 let input = "s as char ";
1658 let res = type_pattern(input.into()).unwrap().1;
1659 if let Lang::TypePattern {
1660 variable_name: name,
1661 ..
1662 } = &res
1663 {
1664 assert_eq!(name, "s");
1665 } else {
1666 panic!("Expected TypePattern variant");
1667 }
1668 }
1669
1670 #[test]
1671 fn test_match_with_type_patterns() {
1672 let input = "match x { y as int => y + 1, z as bool => 0 } ";
1673 let res = match_exp(input.into()).unwrap().1;
1674 assert_eq!(res.simple_print(), "Match");
1675 if let Lang::Match { branches, .. } = &res {
1676 assert_eq!(branches.len(), 2, "Should have 2 branches");
1677 assert!(
1678 branches[0].0.simple_print().starts_with("TypePattern"),
1679 "First branch should be a TypePattern"
1680 );
1681 assert!(
1682 branches[1].0.simple_print().starts_with("TypePattern"),
1683 "Second branch should be a TypePattern"
1684 );
1685 } else {
1686 panic!("Expected Match variant");
1687 }
1688 }
1689
1690 #[test]
1691 fn test_match_mixed_tag_and_type_patterns() {
1692 let input = "match value {
1693 .Some(a) => a,
1694 x as int => x + 1,
1695 _ => 0
1696 } ";
1697 let res = match_exp(input.into()).unwrap().1;
1698 assert_eq!(res.simple_print(), "Match");
1699 if let Lang::Match { branches, .. } = &res {
1700 assert_eq!(branches.len(), 3, "Should have 3 branches");
1701 assert_eq!(branches[0].0.simple_print(), "Tag");
1702 assert!(branches[1].0.simple_print().starts_with("TypePattern"));
1703 assert_eq!(branches[2].0.simple_print(), "Variable(_)");
1704 } else {
1705 panic!("Expected Match variant");
1706 }
1707 }
1708
1709 #[test]
1710 fn test_type_pattern_in_match_pattern() {
1711 let input = "x as int ";
1712 let res = match_pattern(input.into()).unwrap().1;
1713 assert!(
1714 res.simple_print().starts_with("TypePattern"),
1715 "match_pattern should accept type patterns"
1716 );
1717 }
1718
1719 #[test]
1722 fn test_record_pattern_colon_syntax() {
1723 let input = ":{nom: n, age: a} ";
1724 let res = match_pattern(input.into()).unwrap().1;
1725 assert_eq!(
1726 res.simple_print(),
1727 "Record",
1728 "Should parse record pattern as Record"
1729 );
1730 if let Lang::List { value: fields, .. } = &res {
1731 assert_eq!(fields.len(), 2);
1732 assert_eq!(fields[0].get_argument(), "nom");
1733 assert_eq!(fields[1].get_argument(), "age");
1734 } else {
1735 panic!("Expected List variant");
1736 }
1737 }
1738
1739 #[test]
1740 fn test_record_pattern_list_syntax() {
1741 let input = "list(nom = n, age = a) ";
1742 let res = match_pattern(input.into()).unwrap().1;
1743 assert_eq!(res.simple_print(), "Record");
1744 if let Lang::List { value: fields, .. } = &res {
1745 assert_eq!(fields.len(), 2);
1746 assert_eq!(fields[0].get_argument(), "nom");
1747 assert_eq!(fields[1].get_argument(), "age");
1748 } else {
1749 panic!("Expected List variant");
1750 }
1751 }
1752
1753 #[test]
1754 fn test_match_with_record_pattern() {
1755 let input = "match x { :{nom: n, age: a} => a, _ => 0 } ";
1756 let res = match_exp(input.into()).unwrap().1;
1757 assert_eq!(res.simple_print(), "Match");
1758 if let Lang::Match { branches, .. } = &res {
1759 assert_eq!(branches.len(), 2, "Should have 2 branches");
1760 assert_eq!(
1761 branches[0].0.simple_print(),
1762 "Record",
1763 "First branch should be a Record pattern"
1764 );
1765 assert_eq!(branches[1].0.simple_print(), "Variable(_)");
1766 } else {
1767 panic!("Expected Match variant");
1768 }
1769 }
1770
1771 #[test]
1772 fn test_match_with_list_pattern() {
1773 let input = "match x { list(nom = n, age = a) => a, _ => 0 } ";
1774 let res = match_exp(input.into()).unwrap().1;
1775 assert_eq!(res.simple_print(), "Match");
1776 if let Lang::Match { branches, .. } = &res {
1777 assert_eq!(branches.len(), 2);
1778 assert_eq!(branches[0].0.simple_print(), "Record");
1779 } else {
1780 panic!("Expected Match variant");
1781 }
1782 }
1783
1784 #[test]
1785 fn test_match_mixed_record_tag_type_patterns() {
1786 let input = "match value {
1787 .Some(a) => a,
1788 :{nom: n, age: a} => a,
1789 x as int => x + 1,
1790 _ => 0
1791 } ";
1792 let res = match_exp(input.into()).unwrap().1;
1793 assert_eq!(res.simple_print(), "Match");
1794 if let Lang::Match { branches, .. } = &res {
1795 assert_eq!(branches.len(), 4);
1796 assert_eq!(branches[0].0.simple_print(), "Tag");
1797 assert_eq!(branches[1].0.simple_print(), "Record");
1798 assert!(branches[2].0.simple_print().starts_with("TypePattern"));
1799 assert_eq!(branches[3].0.simple_print(), "Variable(_)");
1800 } else {
1801 panic!("Expected Match variant");
1802 }
1803 }
1804
1805 #[test]
1806 fn test_record_pattern_single_field() {
1807 let input = ":{nom: n} ";
1808 let res = match_pattern(input.into()).unwrap().1;
1809 assert_eq!(res.simple_print(), "Record");
1810 if let Lang::List { value: fields, .. } = &res {
1811 assert_eq!(fields.len(), 1);
1812 assert_eq!(fields[0].get_argument(), "nom");
1813 } else {
1814 panic!("Expected List variant");
1815 }
1816 }
1817
1818 #[test]
1821 fn test_tuple_pattern_colon_syntax() {
1822 let input = ":{a, b, c} ";
1823 let res = match_pattern(input.into()).unwrap().1;
1824 assert_eq!(res.simple_print(), "Tuple");
1825 if let Lang::Tuple {
1826 value: elements, ..
1827 } = &res
1828 {
1829 assert_eq!(elements.len(), 3);
1830 } else {
1831 panic!("Expected Tuple variant");
1832 }
1833 }
1834
1835 #[test]
1836 fn test_tuple_pattern_list_syntax() {
1837 let input = "list(a, b, c) ";
1838 let res = match_pattern(input.into()).unwrap().1;
1839 assert_eq!(res.simple_print(), "Tuple");
1840 if let Lang::Tuple {
1841 value: elements, ..
1842 } = &res
1843 {
1844 assert_eq!(elements.len(), 3);
1845 } else {
1846 panic!("Expected Tuple variant");
1847 }
1848 }
1849
1850 #[test]
1851 fn test_tuple_pattern_two_elements() {
1852 let input = ":{x, y} ";
1853 let res = match_pattern(input.into()).unwrap().1;
1854 assert_eq!(res.simple_print(), "Tuple");
1855 if let Lang::Tuple {
1856 value: elements, ..
1857 } = &res
1858 {
1859 assert_eq!(elements.len(), 2);
1860 } else {
1861 panic!("Expected Tuple variant");
1862 }
1863 }
1864
1865 #[test]
1866 fn test_match_with_tuple_pattern() {
1867 let input = "match x { :{a, b, c} => a + c, _ => 0 } ";
1868 let res = match_exp(input.into()).unwrap().1;
1869 assert_eq!(res.simple_print(), "Match");
1870 if let Lang::Match { branches, .. } = &res {
1871 assert_eq!(branches.len(), 2);
1872 assert_eq!(branches[0].0.simple_print(), "Tuple");
1873 assert_eq!(branches[1].0.simple_print(), "Variable(_)");
1874 } else {
1875 panic!("Expected Match variant");
1876 }
1877 }
1878
1879 #[test]
1880 fn test_match_with_list_tuple_pattern() {
1881 let input = "match x { list(a, b, c) => a + c, _ => 0 } ";
1882 let res = match_exp(input.into()).unwrap().1;
1883 assert_eq!(res.simple_print(), "Match");
1884 if let Lang::Match { branches, .. } = &res {
1885 assert_eq!(branches.len(), 2);
1886 assert_eq!(branches[0].0.simple_print(), "Tuple");
1887 } else {
1888 panic!("Expected Match variant");
1889 }
1890 }
1891
1892 #[test]
1893 fn test_match_mixed_all_pattern_types() {
1894 let input = "match value {
1895 .Some(a) => a,
1896 :{nom: n, age: a} => a,
1897 :{x, y} => x + y,
1898 z as int => z + 1,
1899 _ => 0
1900 } ";
1901 let res = match_exp(input.into()).unwrap().1;
1902 assert_eq!(res.simple_print(), "Match");
1903 if let Lang::Match { branches, .. } = &res {
1904 assert_eq!(branches.len(), 5);
1905 assert_eq!(branches[0].0.simple_print(), "Tag");
1906 assert_eq!(branches[1].0.simple_print(), "Record");
1907 assert_eq!(branches[2].0.simple_print(), "Tuple");
1908 assert!(branches[3].0.simple_print().starts_with("TypePattern"));
1909 assert_eq!(branches[4].0.simple_print(), "Variable(_)");
1910 } else {
1911 panic!("Expected Match variant");
1912 }
1913 }
1914
1915 #[test]
1916 fn test_character_constructor_fn() {
1917 let input = "fn(name: char, attack: int, health: int): Character {\n :{ name: name, attack: attack, health: health }\n}";
1918 let res = simple_function(input.into());
1919 match &res {
1920 Ok((remaining, _)) => {
1921 println!("SUCCESS, remaining: {:?}", **remaining);
1922 assert!(
1923 remaining.is_empty(),
1924 "Should consume entire input, remaining: {:?}",
1925 **remaining
1926 );
1927 }
1928 Err(e) => panic!("Parse failed: {:?}", e),
1929 }
1930 }
1931
1932 #[test]
1933 fn test_scope_with_record_body() {
1934 let input = "{\n :{ name: name, attack: attack, health: health }\n}";
1935 let res = scope(input.into());
1936 match &res {
1937 Ok((remaining, _)) => {
1938 println!("scope SUCCESS, remaining: {:?}", **remaining);
1939 }
1940 Err(e) => println!("scope FAILED: {:?}", e),
1941 }
1942 assert!(res.is_ok(), "scope should succeed");
1943 }
1944
1945 #[test]
1946 fn test_record_parse_directly() {
1947 use crate::processes::parsing::base_parse;
1948 let input = ":{ name: name, attack: attack, health: health }";
1949 let res = base_parse(input.into());
1950 println!(
1951 "base_parse result: {:?}",
1952 res.as_ref()
1953 .map(|(r, v): &(_, Vec<_>)| (*r.fragment(), v.len()))
1954 );
1955 assert!(res.is_ok());
1956 let (remaining, elems) = res.unwrap();
1957 println!(" remaining: {:?}", *remaining.fragment());
1958 println!(" elements count: {}", elems.len());
1959 for (i, el) in elems.iter().enumerate() {
1960 println!(" elem[{}]: {}", i, el.simple_print());
1961 }
1962 }
1963
1964 #[test]
1965 fn test_parse_elements_record() {
1966 let input = ":{ name: name, attack: attack, health: health }";
1967 let res = parse_elements(input.into());
1968 match &res {
1969 Ok((remaining, lang)) => println!(
1970 "parse_elements OK: {}, remaining: {:?}",
1971 lang.simple_print(),
1972 **remaining
1973 ),
1974 Err(e) => println!("parse_elements FAILED: {:?}", e),
1975 }
1976 assert!(res.is_ok(), "parse_elements should succeed on record");
1977 }
1978
1979 #[test]
1980 fn test_single_element_record() {
1981 let input = ":{ name: name, attack: attack, health: health }";
1982 let res = single_element(input.into());
1983 match &res {
1984 Ok((remaining, lang)) => println!(
1985 "single_element OK: {}, remaining: {:?}",
1986 lang.simple_print(),
1987 **remaining
1988 ),
1989 Err(e) => println!("single_element FAILED: {:?}", e),
1990 }
1991 assert!(res.is_ok(), "single_element should succeed on record");
1992 }
1993
1994 #[test]
1995 fn test_record_logic_inline() {
1996 let input = ":{ name: name, attack: attack, health: health }";
1997 let res = record(input.into());
1998 match &res {
1999 Ok((remaining, lang)) => println!(
2000 "record OK: {}, remaining: {:?}",
2001 lang.simple_print(),
2002 **remaining
2003 ),
2004 Err(e) => println!("record FAILED: {:?}", e),
2005 }
2006 assert!(res.is_ok(), "record should succeed");
2007 }
2008}