Skip to main content

typr_core/processes/parsing/
elements.rs

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        //alt((scope, parse_elements))
319        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    //from_name().to_language()
639    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
779// main
780pub 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
848// main
849pub 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}