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::single_type;
19use crate::processes::parsing::vector_priority::VectorPriority;
20use crate::utils::builder;
21use nom::branch::alt;
22use nom::bytes::complete::escaped;
23use nom::bytes::complete::is_not;
24use nom::bytes::complete::tag;
25use nom::bytes::complete::take_while1;
26use nom::character::complete::alpha1;
27use nom::character::complete::alphanumeric1;
28use nom::character::complete::char;
29use nom::character::complete::digit1;
30use nom::character::complete::multispace0;
31use nom::character::complete::multispace1;
32use nom::character::complete::one_of;
33use nom::combinator::opt;
34use nom::combinator::recognize;
35use nom::multi::many0;
36use nom::multi::many1;
37use nom::sequence::delimited;
38use nom::sequence::preceded;
39use nom::sequence::terminated;
40use nom::IResult;
41use nom::Parser;
42use nom_locate::LocatedSpan;
43use std::process::exit;
44
45type Span<'a> = LocatedSpan<&'a str, String>;
46
47pub fn is_pascal_case(name: &str) -> bool {
48 let res = recognize(pascal_case_no_space).parse(name.into());
49 match res {
50 Ok((_, _)) => true,
51 Err(_) => false,
52 }
53}
54
55fn number_helper(s: Span) -> IResult<Span, Lang> {
56 let res = (opt(tag("-")), digit1, tag("."), digit1).parse(s);
57 match res {
58 Ok((s, (sign, d1, _dot, d2))) => {
59 let sign2 = sign.unwrap_or(LocatedSpan::new_extra("", d1.clone().extra));
60 let n = format!("{}{}.{}", sign2, d1, d2).parse::<f32>().unwrap();
61 Ok((s, Lang::Number(n, sign2.into())))
62 }
63 Err(r) => Err(r),
64 }
65}
66
67pub fn number(s: Span) -> IResult<Span, Lang> {
68 terminated(number_helper, multispace0).parse(s)
69}
70
71fn integer(s: Span) -> IResult<Span, Lang> {
72 let res = terminated((opt(tag("-")), digit1), multispace0).parse(s);
73 match res {
74 Ok((s, (minus, d))) => {
75 let symbol = match minus {
76 Some(_) => "-",
77 None => "",
78 }
79 .to_string()
80 + &d.to_string();
81 Ok((s, Lang::Integer(symbol.parse::<i32>().unwrap(), d.into())))
82 }
83 Err(r) => Err(r),
84 }
85}
86
87fn get_value(l: LocatedSpan<&str, String>) -> Lang {
88 match l.clone().into_fragment() {
89 "true" | "TRUE" => Lang::Bool(true, l.into()),
90 "false" | "FALSE" => Lang::Bool(false, l.into()),
91 _ => panic!("No other boolean notation alolwed"),
92 }
93}
94
95fn boolean(s: Span) -> IResult<Span, Lang> {
96 let res = alt((
97 terminated(tag("true"), multispace0),
98 terminated(tag("TRUE"), multispace0),
99 terminated(tag("false"), multispace0),
100 terminated(tag("FALSE"), multispace0),
101 ))
102 .parse(s);
103 match res {
104 Ok((s, ls)) => Ok((s, get_value(ls))),
105 Err(r) => Err(r),
106 }
107}
108
109pub fn chars(s: Span) -> IResult<Span, Lang> {
110 terminated(alt((double_quotes, single_quotes)), multispace0).parse(s)
111}
112
113pub fn double_quotes(input: Span) -> IResult<Span, Lang> {
114 let res = delimited(
115 char('"'),
116 opt(escaped(is_not("\\\""), '\\', alt((char('"'), char('\''))))),
117 char('"'),
118 )
119 .parse(input);
120 match res {
121 Ok((s, st)) => {
122 let content = st.clone().map(|span| span.to_string()).unwrap_or_default();
123 let location = st
124 .map(|span| span.into())
125 .unwrap_or_else(|| s.clone().into());
126 Ok((s, Lang::Char(content, location)))
127 }
128 Err(r) => Err(r),
129 }
130}
131
132pub fn single_quotes(input: Span) -> IResult<Span, Lang> {
133 let res = delimited(
134 char('\''),
135 opt(escaped(is_not("\\'"), '\\', alt((char('"'), char('\''))))),
136 char('\''),
137 )
138 .parse(input);
139 match res {
140 Ok((s, st)) => {
141 let content = st.clone().map(|span| span.to_string()).unwrap_or_default();
142 let location = st
143 .map(|span| span.into())
144 .unwrap_or_else(|| s.clone().into());
145 Ok((s, Lang::Char(content, location)))
146 }
147 Err(r) => Err(r),
148 }
149}
150
151fn starting_char(s: Span) -> IResult<Span, (char, HelpData)> {
152 let res = one_of("abcdefghijklmnopqrstuvwxyz_")(s);
153 match res {
154 Ok((s, val)) => Ok((s.clone(), (val, s.into()))),
155 Err(r) => Err(r),
156 }
157}
158
159fn body_char(s: Span) -> IResult<Span, (char, HelpData)> {
160 let res = one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789")(s);
161 match res {
162 Ok((s, val)) => Ok((s.clone(), (val, s.into()))),
163 Err(r) => Err(r),
164 }
165}
166
167pub fn variable_exp(s: Span) -> IResult<Span, (String, HelpData)> {
168 let res = (starting_char, many0(body_char)).parse(s);
169 match res {
170 Ok((s, ((s1, h), v))) => {
171 let res2 = v.iter().map(|(val, _h)| val.clone()).collect::<String>();
172 Ok((s, (format!("{}{}", s1, res2), h.clone())))
173 }
174 Err(r) => Err(r),
175 }
176}
177
178fn type_annotation(s: Span) -> IResult<Span, Type> {
179 delimited(tag("<"), ltype, tag(">")).parse(s)
180}
181
182pub enum Case {
183 Maj,
184 Min,
185}
186
187fn variable_exp_2(s: Span) -> IResult<Span, (String, Case, HelpData)> {
188 let res = variable_exp.parse(s);
189 match res {
190 Ok((s, (name, h))) => Ok((s, (name, Case::Min, h))),
191 Err(r) => Err(r),
192 }
193}
194
195fn pascal_case_2(s: Span) -> IResult<Span, (String, Case, HelpData)> {
196 let res = pascal_case.parse(s);
197 match res {
198 Ok((s, (name, h))) => Ok((s, (name, Case::Maj, h))),
199 Err(r) => Err(r),
200 }
201}
202
203fn quoted_variable(s: Span) -> IResult<Span, (String, Case, HelpData)> {
204 let res = delimited(char('`'), is_not("`"), char('`')).parse(s);
205
206 match res {
207 Ok((s, st)) => Ok((s, (format!("`{}`", st.clone()), Case::Min, st.into()))),
208 Err(r) => Err(r),
209 }
210}
211
212pub fn variable_recognizer(s: Span) -> IResult<Span, (String, HelpData)> {
213 let res = alt((quoted_variable, pascal_case_2, variable_exp_2)).parse(s);
214 match res {
215 Ok((s, (s1, _case, h))) => Ok((s, (s1, h))),
216 Err(r) => Err(r),
217 }
218}
219
220fn variable_helper(s: Span) -> IResult<Span, (Lang, Case)> {
221 let res = (
222 alt((quoted_variable, pascal_case_2, variable_exp_2)),
223 opt(type_annotation),
224 )
225 .parse(s);
226 match res {
227 Ok((s, ((v, case, h), typ))) => {
228 let res = Var::from_name(&v)
229 .set_type(typ.unwrap_or(builder::empty_type()))
230 .set_help_data(h);
231 Ok((s, (res.into(), case)))
232 }
233 Err(r) => Err(r),
234 }
235}
236
237pub fn variable(s: Span) -> IResult<Span, (Lang, Case)> {
238 terminated(variable_helper, multispace0).parse(s)
239}
240
241pub fn argument(s: Span) -> IResult<Span, ArgumentType> {
242 let res = (
243 terminated(label, multispace0),
244 terminated(tag(":"), multispace0),
245 ltype,
246 opt(terminated(tag(","), multispace0)),
247 )
248 .parse(s);
249 match res {
250 Ok((s, (e1, _, e2, _))) => Ok((s, ArgumentType(e1, e2, false))),
251 Err(r) => Err(r),
252 }
253}
254
255fn equality_params(s: Span) -> IResult<Span, Span> {
256 terminated(alt((tag("="), tag(":"))), multispace0).parse(s)
257}
258
259fn argument_val(s: Span) -> IResult<Span, ArgumentValue> {
260 let res = (
261 terminated(alphanumeric1, multispace0),
262 equality_params,
263 single_element,
264 opt(terminated(tag(","), multispace0)),
265 )
266 .parse(s);
267 match res {
268 Ok((s, (e1, _, e2, _))) => Ok((s, ArgumentValue(e1.to_string(), e2))),
269 Err(r) => Err(r),
270 }
271}
272
273pub fn parse_block(input: Span) -> IResult<Span, Span> {
274 recognize(parse_nested_braces).parse(input)
275}
276
277fn parse_nested_braces(input: Span) -> IResult<Span, Span> {
278 recognize(delimited(
279 tag("{"),
280 many0(alt((
281 parse_nested_braces,
282 recognize(take_while1(|c| c != '{' && c != '}')),
283 ))),
284 tag("}"),
285 ))
286 .parse(input)
287}
288
289pub fn r_function(s: Span) -> IResult<Span, Lang> {
290 let res = (
291 terminated(alt((tag("function"), tag("\\"))), multispace0),
292 terminated(tag("("), multispace0),
293 many0(terminated(terminated(variable, opt(tag(","))), multispace0)),
294 terminated(tag(")"), multispace0),
295 terminated(parse_block, multispace0),
296 )
297 .parse(s);
298 match res {
299 Ok((_s, (id, _op, _args, _cl, _exp))) if *id.fragment() == "fn" => {
300 panic!("{}", SyntaxError::FunctionWithoutType(id.into()).display())
301 }
302 Ok((s, (id, _op, args, _cl, exp))) => {
303 let args = args.iter().map(|(arg, _)| arg).cloned().collect::<Vec<_>>();
304 Ok((s, Lang::RFunction(args, exp.to_string(), id.into())))
305 }
306 Err(r) => Err(r),
307 }
308}
309
310pub fn simple_function(s: Span) -> IResult<Span, Lang> {
311 let res = (
312 terminated(tag("fn"), multispace0),
313 terminated(tag("("), multispace0),
314 many0(argument),
315 terminated(tag(")"), multispace0),
316 opt(terminated(tag(":"), multispace0)),
317 opt(terminated(alt((if_type, ltype)), multispace0)),
318 scope,
320 )
321 .parse(s);
322 match res {
323 Ok((s, (_, _, args, _, Some(_), Some(typ), exp))) => Ok((
324 s,
325 Lang::Function(args, typ, Box::new(exp), HelpData::default()),
326 )),
327 Ok((_s, (_, _, _args, _cp, None, None, _exp))) => {
328 panic!("You forgot to specify the function return type: 'fn(...): Type'");
329 }
330 Ok((_s, (_, _, _args, _, Some(tag), None, _exp))) => {
331 None::<bool>.expect(&SyntaxError::FunctionWithoutReturnType(tag.into()).display());
332 exit(1)
333 }
334 Ok((_s, (_, _, _args, _, None, Some(typ), _exp))) => {
335 eprintln!(
336 "The type '{}' should be preceded by a ':' :\n 'fn(...): {}'",
337 typ.clone(),
338 typ.clone()
339 );
340 exit(1)
341 }
342 Err(r) => Err(r),
343 }
344}
345
346fn function(s: Span) -> IResult<Span, Lang> {
347 simple_function.parse(s)
348}
349
350fn key_value(s: Span) -> IResult<Span, Lang> {
351 let res = (
352 recognize(variable),
353 terminated(tag("="), multispace0),
354 single_element,
355 )
356 .parse(s);
357 match res {
358 Ok((s, (v, _eq, el))) => Ok((s, Lang::KeyValue((*v).into(), Box::new(el), v.into()))),
359 Err(r) => Err(r),
360 }
361}
362
363fn values(s: Span) -> IResult<Span, Vec<Lang>> {
364 many0(terminated(
365 alt((key_value, parse_elements)),
366 terminated(opt(tag(",")), multispace0),
367 ))
368 .parse(s)
369}
370
371pub fn variable2(s: Span) -> IResult<Span, Lang> {
372 let res = variable.parse(s);
373 match res {
374 Ok((s, (lang, _))) => Ok((s, lang)),
375 Err(r) => Err(r),
376 }
377}
378
379fn array_indexing(s: Span) -> IResult<Span, Lang> {
380 let res = (alt((scope, variable2)), array).parse(s);
381
382 match res {
383 Ok((s, (lang1, lang2))) => Ok((
384 s,
385 Lang::ArrayIndexing(Box::new(lang1.clone()), Box::new(lang2), lang1.into()),
386 )),
387 Err(r) => Err(r),
388 }
389}
390
391fn function_application(s: Span) -> IResult<Span, Lang> {
392 let res = (
393 alt((scope, variable2)),
394 terminated(tag("("), multispace0),
395 values,
396 terminated(tag(")"), multispace0),
397 )
398 .parse(s);
399 match res {
400 Ok((s, (exp, _, v, _))) => Ok((
401 s,
402 Lang::FunctionApp(Box::new(exp.clone()), v.clone(), exp.into()),
403 )),
404 Err(r) => Err(r),
405 }
406}
407
408fn array(s: Span) -> IResult<Span, Lang> {
409 let res = (
410 terminated(tag("["), multispace0),
411 values,
412 terminated(tag("]"), multispace0),
413 )
414 .parse(s);
415 match res {
416 Ok((s, (_, v, _))) => Ok((s, Lang::Array(v.clone(), v.into()))),
417 Err(r) => Err(r),
418 }
419}
420
421pub fn vector(s: Span) -> IResult<Span, Lang> {
422 let res = (
423 terminated(tag("c("), multispace0),
424 values,
425 terminated(tag(")"), multispace0),
426 )
427 .parse(s);
428 match res {
429 Ok((s, (_, v, _))) => Ok((s, Lang::Vector(v.clone(), v.into()))),
430 Err(r) => Err(r),
431 }
432}
433
434fn sequence(s: Span) -> IResult<Span, Lang> {
435 let res = (
436 terminated(tag("seq["), multispace0),
437 values,
438 terminated(tag("]"), multispace0),
439 )
440 .parse(s);
441 match res {
442 Ok((s, (_, v, _))) => Ok((s, Lang::Sequence(v.clone(), v.into()))),
443 Err(r) => Err(r),
444 }
445}
446
447fn record_identifier(s: Span) -> IResult<Span, Span> {
448 alt((tag("record"), tag("object"), tag("list"), tag(":"))).parse(s)
449}
450
451fn record(s: Span) -> IResult<Span, Lang> {
452 let res = (
453 opt(record_identifier),
454 terminated(alt((tag("{"), tag("("))), multispace0),
455 many0(argument_val),
456 terminated(alt((tag("}"), tag(")"))), multispace0),
457 )
458 .parse(s);
459 match res {
460 Ok((s, (Some(start), _, args, _))) => Ok((s, Lang::Record(args.clone(), start.into()))),
461 Ok((_s, (None, _ob, args, _))) => {
462 if args.len() == 0 {
463 panic!("Error: the scope shouldn't be empty")
464 } else {
465 eprintln!("{}", _s);
466 panic!("You forgot to put a record identifier before the bracket: ':{{...}}'");
467 }
468 }
469 Err(r) => Err(r),
470 }
471}
472
473fn pascal_case_helper(s: Span) -> IResult<Span, (String, HelpData)> {
474 let res = (one_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), alpha1).parse(s);
475 match res {
476 Ok((s, (t1, t2))) => Ok((s.clone(), (format!("{}{}", t1, t2), s.into()))),
477 Err(r) => Err(r),
478 }
479}
480
481fn pascal_case(s: Span) -> IResult<Span, (String, HelpData)> {
482 pascal_case_helper.parse(s)
483}
484
485fn parenthese_value(s: Span) -> IResult<Span, Lang> {
486 delimited(
487 terminated(tag("("), multispace0),
488 parse_elements,
489 terminated(tag(")"), multispace0),
490 )
491 .parse(s)
492}
493
494pub fn tag_exp(s: Span) -> IResult<Span, Lang> {
495 let res = (tag("."), pascal_case, opt(parenthese_value)).parse(s);
496 match res {
497 Ok((s, (dot, (n, _h), None))) => Ok((
498 s,
499 Lang::Tag(n, Box::new(Lang::Empty(dot.clone().into())), dot.into()),
500 )),
501 Ok((s, (dot, (n, _h), Some(val)))) => Ok((s, Lang::Tag(n, Box::new(val), dot.into()))),
502 Err(r) => Err(r),
503 }
504}
505
506fn dotdotdot(s: Span) -> IResult<Span, Lang> {
507 let res = terminated(tag("..."), multispace0).parse(s);
508 match res {
509 Ok((s, d)) => Ok((s, Lang::Empty(d.into()))),
510 Err(r) => Err(r),
511 }
512}
513
514fn else_exp(s: Span) -> IResult<Span, Lang> {
515 let res = (
516 terminated(tag("else"), multispace0),
517 terminated(tag("{"), multispace0),
518 parse_elements,
519 terminated(tag("}"), multispace0),
520 )
521 .parse(s);
522 match res {
523 Ok((s, (_else, _o, exp, _c))) => Ok((s, exp)),
524 Err(r) => Err(r),
525 }
526}
527
528fn else_if_exp(s: Span) -> IResult<Span, Lang> {
529 preceded(terminated(tag("else"), multispace1), if_exp).parse(s)
530}
531
532fn if_exp(s: Span) -> IResult<Span, Lang> {
533 let res = (
534 terminated(tag("if"), multispace0),
535 terminated(tag("("), multispace0),
536 parse_elements,
537 terminated(tag(")"), multispace0),
538 terminated(tag("{"), multispace0),
539 parse_elements,
540 terminated(tag("}"), multispace0),
541 opt(alt((else_if_exp, else_exp))),
542 )
543 .parse(s);
544 match res {
545 Ok((s, (_if, _op, cond, _cp, _o, exp, _c, els))) => Ok((
546 s,
547 Lang::If(
548 Box::new(cond),
549 Box::new(exp),
550 Box::new(els.unwrap_or(Lang::Empty(HelpData::default()))),
551 _if.into(),
552 ),
553 )),
554 Err(r) => Err(r),
555 }
556}
557
558fn branch(s: Span) -> IResult<Span, (Type, Box<Lang>)> {
559 let res = (
560 terminated(single_type, multispace0),
561 terminated(tag("=>"), multispace0),
562 terminated(parse_elements, multispace0),
563 opt(terminated(tag(","), multispace0)),
564 )
565 .parse(s);
566 match res {
567 Ok((s, (typ, _arr, lang, _vir))) => Ok((s, (typ, Box::new(lang)))),
568 Err(r) => Err(r),
569 }
570}
571
572fn match_exp(s: Span) -> IResult<Span, Lang> {
573 let res = (
574 terminated(tag("match"), multispace0),
575 alt((variable2, elements)),
576 terminated(tag("as"), multispace0),
577 variable2,
578 terminated(tag("{"), multispace0),
579 many1(branch),
580 terminated(tag("}"), multispace0),
581 )
582 .parse(s);
583 match res {
584 Ok((s, (_m, exp, _as, var, _o, bs, _c))) => Ok((
585 s,
586 Lang::Match(Box::new(exp), Var::try_from(var).unwrap(), bs, _m.into()),
587 )),
588 Err(r) => Err(r),
589 }
590}
591
592fn tuple_exp(s: Span) -> IResult<Span, Lang> {
593 let res = (
594 terminated(alt((tag("list"), tag(":"))), multispace0),
595 terminated(alt((tag("{"), tag("("))), multispace0),
596 values,
597 terminated(alt((tag("}"), tag(")"))), multispace0),
598 )
599 .parse(s);
600 match res {
601 Ok((s, (id, _op, vals, _cl))) => Ok((s, Lang::Tuple(vals, id.into()))),
602 Err(r) => Err(r),
603 }
604}
605
606fn int_or_var(s: Span) -> IResult<Span, Lang> {
607 alt((integer, variable2)).parse(s)
608}
609
610fn create_range(params: &[Lang]) -> Lang {
611 if params.len() == 2 {
612 Lang::FunctionApp(
613 Box::new(Var::from_name("seq").to_language()),
614 vec![
615 params[0].clone(),
616 params[1].clone(),
617 Lang::Integer(1, HelpData::default()),
618 ],
619 params.to_vec().into(),
620 )
621 } else {
622 Lang::FunctionApp(
623 Box::new(Var::from_name("seq").to_language()),
624 vec![params[0].clone(), params[1].clone(), params[2].clone()],
625 params.to_vec().into(),
626 )
627 }
628}
629
630fn range(s: Span) -> IResult<Span, Lang> {
631 let res = (
632 int_or_var,
633 tag(":"),
634 opt(terminated(int_or_var, tag(":"))),
635 int_or_var,
636 )
637 .parse(s);
638 match res {
640 Ok((s, (iv1, _sep, None, iv2))) => Ok((s, create_range(&[iv1.clone(), iv2.clone()]))),
641 Ok((s, (iv1, _sep, Some(iv0), iv2))) => {
642 Ok((s, create_range(&[iv1.clone(), iv2.clone(), iv0.clone()])))
643 }
644 Err(r) => Err(r),
645 }
646}
647
648fn function_application2(s: Span) -> IResult<Span, Lang> {
649 let res = recognize(function_application).parse(s);
650 match res {
651 Ok((s, fun_app)) => Ok((s, Lang::Exp(fun_app.to_string(), fun_app.into()))),
652 Err(r) => Err(r),
653 }
654}
655
656fn dot_variable(s: Span) -> IResult<Span, Lang> {
657 let res = preceded(tag("."), variable2).parse(s);
658 match res {
659 Ok((s, Lang::Variable(n, b, c, d))) => Ok((s, Lang::Variable(format!(".{}", n), b, c, d))),
660 Ok((_s, _)) => todo!(),
661 Err(r) => Err(r),
662 }
663}
664
665fn element_operator2(s: Span) -> IResult<Span, (Lang, Op)> {
666 let res = (
667 opt(op),
668 alt((
669 function_application2,
670 number,
671 integer,
672 chars,
673 boolean,
674 variable2,
675 dot_variable,
676 )),
677 )
678 .parse(s);
679 match res {
680 Ok((s, (Some(ope), ele))) => Ok((s, (ele, ope))),
681 Ok((s, (None, ele))) => Ok((s.clone(), (ele, Op::Empty(s.into())))),
682 Err(r) => Err(r),
683 }
684}
685
686fn vectorial_bloc(s: Span) -> IResult<Span, Lang> {
687 let res = (
688 terminated(tag("@{"), multispace0),
689 recognize(many1(element_operator2)),
690 terminated(tag("}@"), multispace0),
691 )
692 .parse(s);
693 match res {
694 Ok((s, (_start, bloc, _end))) => {
695 Ok((s, Lang::VecBlock(bloc.fragment().to_string(), bloc.into())))
696 }
697 Err(r) => Err(r),
698 }
699}
700
701fn lambda(s: Span) -> IResult<Span, Lang> {
702 let res = preceded(tag("~"), elements).parse(s);
703 match res {
704 Ok((s, e)) => Ok((s, Lang::Lambda(Box::new(e.clone()), e.into()))),
705 Err(r) => Err(r),
706 }
707}
708
709fn not_exp(s: Span) -> IResult<Span, Lang> {
710 let res = (
711 tag("!"),
712 alt((
713 tag_exp,
714 range,
715 lambda,
716 boolean,
717 number,
718 integer,
719 chars,
720 match_exp,
721 if_exp,
722 dotdotdot,
723 vector,
724 record,
725 r_function,
726 function,
727 tuple_exp,
728 function_application,
729 array_indexing,
730 variable2,
731 scope,
732 array,
733 )),
734 )
735 .parse(s);
736 match res {
737 Ok((s, (not_op, lang))) => Ok((s, Lang::Not(Box::new(lang), not_op.into()))),
738 Err(r) => Err(r),
739 }
740}
741
742fn array_variant(s: Span) -> IResult<Span, Lang> {
743 alt((vector, sequence)).parse(s)
744}
745
746fn js_block(s: Span) -> IResult<Span, Lang> {
747 let res = (terminated(tag("JS"), multispace0), scope).parse(s);
748
749 match res {
750 Ok((s, (js, body))) => Ok((s, Lang::JSBlock(Box::new(body), 0, js.into()))),
751 Err(r) => Err(r),
752 }
753}
754
755fn primitive(s: Span) -> IResult<Span, Lang> {
756 alt((boolean, number, integer, chars)).parse(s)
757}
758
759pub fn return_exp(s: Span) -> IResult<Span, Lang> {
760 let res = terminated(
761 delimited(tag("return "), parse_elements, tag(";")),
762 multispace0,
763 )
764 .parse(s);
765 match res {
766 Ok((s, el)) => Ok((s, Lang::Return(Box::new(el.clone()), el.into()))),
767 Err(r) => Err(r),
768 }
769}
770
771pub fn break_exp(s: Span) -> IResult<Span, Vec<Lang>> {
772 let res = tag("break;").parse(s);
773 match res {
774 Ok((s, el)) => Ok((s, vec![Lang::Break(el.into())])),
775 Err(r) => Err(r),
776 }
777}
778
779pub fn single_element(s: Span) -> IResult<Span, Lang> {
781 alt((
782 not_exp,
783 tag_exp,
784 range,
785 lambda,
786 primitive,
787 js_block,
788 return_exp,
789 match_exp,
790 if_exp,
791 dotdotdot,
792 array_variant,
793 record,
794 r_function,
795 function,
796 tuple_exp,
797 function_application,
798 array_indexing,
799 variable2,
800 scope,
801 array,
802 ))
803 .parse(s)
804}
805
806pub fn scope(s: Span) -> IResult<Span, Lang> {
807 let res = delimited(
808 terminated(alt((tag("("), tag("{"))), multispace0),
809 opt(base_parse),
810 terminated(alt((tag(")"), tag("}"))), multispace0),
811 )
812 .parse(s);
813 match res {
814 Ok((s, Some(v))) => Ok((s, Lang::Scope(v.clone(), v.into()))),
815 Ok((_s, None)) => panic!("Error: the scope shouldn't be empty"),
816 Err(r) => Err(r),
817 }
818}
819
820fn element_operator_token(s: Span) -> IResult<Span, LangToken> {
821 match op.parse(s) {
822 Ok((s, op)) => Ok((s, LangToken::Operator(op))),
823 Err(r) => Err(r),
824 }
825}
826
827fn single_element_token(s: Span) -> IResult<Span, LangToken> {
828 match single_element.parse(s) {
829 Ok((s, op)) => Ok((s, LangToken::Expression(op))),
830 Err(r) => Err(r),
831 }
832}
833
834pub fn elements(s: Span) -> IResult<Span, Lang> {
835 let res = many1(alt((single_element_token, element_operator_token))).parse(s);
836 match res {
837 Ok((s, v)) => {
838 if v.len() == 1 {
839 Ok((s, v[0].clone().into()))
840 } else {
841 Ok((s, VectorPriority::from(v).run()))
842 }
843 }
844 Err(r) => Err(r),
845 }
846}
847
848pub fn parse_elements(s: Span) -> IResult<Span, Lang> {
850 alt((vectorial_bloc, elements)).parse(s)
851}
852
853#[cfg(test)]
854mod tests {
855 use super::*;
856 use crate::utils::fluent_parser::FluentParser;
857
858 #[test]
859 #[should_panic]
860 fn test_empty_scope() {
861 let _ = "{ }".parse::<Lang>();
862 }
863
864 #[test]
865 fn test_function_with_empty_scope3() {
866 let res = simple_function("fn(): int { 5 }".into()).unwrap().1;
867 assert_eq!(res.simple_print(), "Function");
868 }
869
870 #[test]
871 fn test_variable1() {
872 let res = variable_exp("hello".into()).unwrap().1 .0;
873 assert_eq!(res, "hello", "Should return the variable name 'hello'");
874 }
875
876 #[test]
877 fn test_simple_variable1() {
878 let res = variable_exp("hello".into()).unwrap().1 .0;
879 assert_eq!(res, "hello", "Should return the variable name 'hello'");
880 }
881
882 #[test]
883 fn test_addition1() {
884 let res = "1 + 2".parse::<Lang>().unwrap();
885 dbg!(&res);
886 assert_eq!(res.simple_print(), "Operator", "Should parse 1 + 2");
887 }
888
889 #[test]
890 fn test_addition2() {
891 let res = "1 + 2 + 3".parse::<Lang>().unwrap();
892 dbg!(&res);
893 assert_eq!(res.simple_print(), "Operator", "Should parse 1 + 2 + 3");
894 }
895
896 #[test]
897 fn test_multiplication1() {
898 let res = "1 + 2 * 3".parse::<Lang>().unwrap();
899 dbg!(&res);
900 assert_eq!(
901 res.simple_print(),
902 "Operator",
903 "Should put multiplication first 1 + 2 * 3"
904 );
905 }
906
907 #[test]
908 fn test_multiplication2() {
909 let res = "1 * 2 + 3".parse::<Lang>().unwrap();
910 dbg!(&res);
911 assert_eq!(
912 res.simple_print(),
913 "Operator",
914 "Should put multiplication first 1 * 2 + 3"
915 );
916 }
917
918 #[test]
919 fn test_multiplication3() {
920 let res = "1 * 2 + 3 * 4".parse::<Lang>().unwrap();
921 dbg!(&res);
922 assert_eq!(
923 res.simple_print(),
924 "Operator",
925 "Should put multiplication first 1 * 2 + 3 * 4"
926 );
927 }
928
929 #[test]
930 fn test_accessor1() {
931 let res = "3 + personne$age ".parse::<Lang>().unwrap();
932 dbg!(&res);
933 assert_eq!(
934 res.simple_print(),
935 "Operator",
936 "Should put multiplication first 1 * 2 + 3 * 4"
937 );
938 }
939
940 #[test]
941 fn test_and1() {
942 let res = "true & true".parse::<Lang>().unwrap();
943 dbg!(&res);
944 assert_eq!(res.simple_print(), "Operator", "Should accept '&&'");
945 }
946
947 #[test]
948 fn test_array_indexing0() {
949 let res = array_indexing("name[1, 2, 3]".into()).unwrap().1;
950 dbg!(&res);
951 assert!(true);
952 }
953
954 #[test]
955 fn test_array_indexing() {
956 let fp = FluentParser::new().push("name[1, 2, 3]").parse_next();
957 println!("fp: {}", fp);
958 assert!(true);
959 }
960
961 #[test]
962 fn test_quoted_variable() {
963 let res = quoted_variable("`+`".into()).unwrap().1;
964 assert_eq!(res.0, "`+`");
965 }
966
967 #[test]
968 fn test_uniform_function_call() {
969 let res = FluentParser::new().push("true.not()").parse_next();
970 dbg!(&res.next_code());
971 assert!(true);
972 }
973
974 #[test]
975 fn test_key_value1() {
976 let res = key_value("sep = '3'".into()).unwrap().1;
977 dbg!(&res);
978 assert!(true);
979 }
980
981 #[test]
982 fn test_empty_char0() {
983 let res = single_element("''".into()).unwrap().1;
984 dbg!(&res);
985 assert!(true);
986 }
987
988 #[test]
989 fn test_empty_char1() {
990 let res = primitive("''".into()).unwrap().1;
991 dbg!(&res);
992 assert!(true);
993 }
994
995 #[test]
996 fn test_empty_char2() {
997 let res = chars("''".into()).unwrap().1;
998 dbg!(&res);
999 assert!(true);
1000 }
1001}