1#![allow(dead_code)]
2
3pub mod elements;
4pub mod indexation;
5pub mod lang_token;
6pub mod operation_priority;
7pub mod type_token;
8pub mod types;
9pub mod vector_priority;
10
11use crate::components::context::config::Config;
12use crate::components::error_message::help_data::HelpData;
13use crate::components::error_message::syntax_error::SyntaxError;
14use crate::components::language::operators::custom_op;
15use crate::components::language::operators::Op;
16use crate::components::language::var::Var;
17use crate::components::language::Lang;
18use crate::components::language::ModulePosition;
19use crate::components::r#type::Type;
20use crate::processes::parsing::elements::break_exp;
21use crate::processes::parsing::elements::chars;
22use crate::processes::parsing::elements::parse_elements;
23use crate::processes::parsing::elements::return_exp;
24use crate::processes::parsing::elements::scope;
25use crate::processes::parsing::elements::single_element;
26use crate::processes::parsing::elements::tag_exp;
27use crate::processes::parsing::elements::tuple_exp;
28use crate::processes::parsing::elements::variable;
29use crate::processes::parsing::elements::variable2;
30use crate::processes::parsing::elements::variable_exp;
31use crate::processes::parsing::elements::variable_recognizer;
32use crate::processes::parsing::elements::vector;
33use crate::processes::parsing::elements::Case;
34use crate::processes::parsing::types::ltype;
35use crate::processes::parsing::types::type_alias;
36use nom::branch::alt;
37use nom::bytes::complete::tag;
38use nom::character::complete::line_ending;
39use nom::character::complete::multispace0;
40use nom::character::complete::not_line_ending;
41use nom::combinator::map;
42use nom::combinator::opt;
43use nom::multi::many0;
44use nom::multi::separated_list0;
45use nom::sequence::delimited;
46use nom::sequence::pair;
47use nom::sequence::preceded;
48use nom::sequence::terminated;
49use nom::IResult;
50use nom::Parser;
51use nom_locate::LocatedSpan;
52use std::ops::Deref;
53
54type Span<'a> = LocatedSpan<&'a str, String>;
55
56use std::cell::RefCell;
57
58thread_local! {
59 static PARSE_ERRORS: RefCell<Vec<SyntaxError>> = RefCell::new(Vec::new());
60}
61
62fn push_parse_error(err: SyntaxError) {
63 PARSE_ERRORS.with(|e| e.borrow_mut().push(err));
64}
65
66fn take_parse_errors() -> Vec<SyntaxError> {
67 PARSE_ERRORS.with(|e| e.borrow_mut().drain(..).collect())
68}
69
70#[derive(Debug, Clone)]
72pub struct ParseResult {
73 pub ast: Lang,
74 pub errors: Vec<SyntaxError>,
75}
76
77impl ParseResult {
78 pub fn new(ast: Lang) -> Self {
79 let errors = take_parse_errors();
80 ParseResult { ast, errors }
81 }
82
83 pub fn has_errors(&self) -> bool {
84 !self.errors.is_empty()
85 }
86
87 pub fn get_ast(&self) -> &Lang {
88 &self.ast
89 }
90
91 pub fn get_clean_ast(&self) -> Lang {
92 self.ast.clone()
93 }
94}
95
96fn pattern_var(s: Span) -> IResult<Span, (Vec<Lang>, Option<String>)> {
97 let res = alt((tag_exp, variable2)).parse(s);
98 match res {
99 Ok((
100 s,
101 Lang::Tag {
102 name, value: val, ..
103 },
104 )) => {
105 if let Lang::Variable {
106 name: name2,
107 is_opaque: mutopa,
108 related_type: typ,
109 help_data: h,
110 } = *val
111 {
112 Ok((
113 s,
114 (
115 vec![Lang::Variable {
116 name: name2.to_string(),
117 is_opaque: mutopa,
118 related_type: typ,
119 help_data: h.clone(),
120 }],
121 Some(name.to_string()),
122 ),
123 ))
124 } else {
125 Ok((s, (vec![], Some(name.to_string()))))
126 }
127 }
128 Ok((
129 s,
130 Lang::Variable {
131 name,
132 is_opaque: mutopa,
133 related_type: typ,
134 help_data: h,
135 },
136 )) => Ok((
137 s,
138 (
139 vec![Lang::Variable {
140 name,
141 is_opaque: mutopa,
142 related_type: typ,
143 help_data: h.clone(),
144 }],
145 None,
146 ),
147 )),
148 Err(r) => Err(r),
149 _ => todo!(),
150 }
151}
152
153fn single_parse(s: Span) -> IResult<Span, Lang> {
154 let res = (parse_elements, opt(terminated(tag(";"), multispace0))).parse(s);
155 match res {
156 Ok((s, (exp, Some(_)))) => Ok((s, exp)),
157 Ok((s, (exp, None))) => {
158 push_parse_error(SyntaxError::ForgottenSemicolon(exp.clone().into()));
159 Ok((s, exp))
160 }
161 Err(r) => Err(r),
162 }
163}
164
165fn equality_operator(s: Span) -> IResult<Span, Span> {
166 terminated(alt((tag("="), tag("<-"))), multispace0).parse(s)
167}
168
169fn base_let_exp(s: Span) -> IResult<Span, Vec<Lang>> {
170 let res = (
171 terminated(tag("let"), multispace0),
172 pattern_var,
173 opt(preceded(terminated(tag(":"), multispace0), ltype)),
174 equality_operator,
175 single_parse,
176 )
177 .parse(s);
178 match res {
179 Ok((
180 s,
181 (
182 _let,
183 (pat_var, None),
184 typ,
185 _eq,
186 Lang::Function {
187 parameters: params,
188 return_type: ty,
189 body,
190 help_data: h,
191 },
192 ),
193 )) if !params.is_empty() => {
194 let newvar = Var::from_language(pat_var[0].clone())
195 .unwrap()
196 .set_type(params[0].1.clone());
197 Ok((
198 s,
199 vec![Lang::Let {
200 variable: Box::new(newvar.to_language()),
201 r#type: typ.unwrap_or(Type::Empty(HelpData::default())),
202 expression: Box::new(Lang::Function {
203 parameters: params,
204 return_type: ty,
205 body,
206 help_data: h,
207 }),
208 is_public: false,
209 help_data: _let.into(),
210 }],
211 ))
212 }
213 Ok((s, (_let, (pat_var, None), typ, _eq, body))) => Ok((
214 s,
215 vec![Lang::Let {
216 variable: Box::new(pat_var[0].clone()),
217 r#type: typ.clone().unwrap_or(Type::Empty(HelpData::default())),
218 expression: Box::new(body),
219 is_public: false,
220 help_data: _let.into(),
221 }],
222 )),
223 Ok((s, (_let, (pat_var, Some(_)), typ, eq, body))) => {
224 if pat_var.len() == 1 {
225 Ok((
226 s,
227 vec![Lang::Let {
228 variable: Box::new(pat_var[0].clone()),
229 r#type: typ.clone().unwrap_or(Type::Empty(HelpData::default())),
230 expression: Box::new(Lang::Operator {
231 operator: Op::Dollar(HelpData::default()),
232 rhs: Box::new(Lang::Number {
233 value: 0.0,
234 help_data: eq.into(),
235 }),
236 lhs: Box::new(body),
237 help_data: pat_var.into(),
238 }),
239 is_public: false,
240 help_data: _let.into(),
241 }],
242 ))
243 } else {
244 Ok((
245 s,
246 pat_var
247 .iter()
248 .map(|x| Lang::Let {
249 variable: Box::new(x.clone()),
250 r#type: typ.clone().unwrap_or(Type::Empty(HelpData::default())),
251 expression: Box::new(body.clone()),
252 is_public: false,
253 help_data: HelpData::default(),
254 })
255 .collect::<Vec<_>>(),
256 ))
257 }
258 }
259 Err(r) => Err(r),
260 }
261}
262
263fn let_tuple_exp(s: Span) -> IResult<Span, Vec<Lang>> {
264 let res = (
265 terminated(tag("let"), multispace0),
266 tuple_exp,
267 opt(preceded(terminated(tag(":"), multispace0), ltype)),
268 equality_operator,
269 single_parse,
270 )
271 .parse(s);
272 match res {
273 Ok((
274 s,
275 (
276 _let,
277 Lang::Tuple {
278 value: elements,
279 help_data: _th,
280 },
281 typ,
282 _eq,
283 body,
284 ),
285 )) => {
286 let tmp_name = "__tuple_tmp__";
287 let tmp_var = Var::from_name(tmp_name).to_language();
288
289 let tmp_let = Lang::Let {
291 variable: Box::new(tmp_var.clone()),
292 r#type: typ.unwrap_or(Type::Empty(HelpData::default())),
293 expression: Box::new(body),
294 is_public: false,
295 help_data: _let.into(),
296 };
297
298 let mut result = vec![tmp_let];
300 for (i, elem) in elements.iter().enumerate() {
301 if let Lang::Variable { name, .. } = elem {
302 if name == "_" {
303 continue; }
305 }
306 result.push(Lang::Let {
307 variable: Box::new(elem.clone()),
308 r#type: Type::Empty(HelpData::default()),
309 expression: Box::new(Lang::Operator {
310 operator: Op::Dot(HelpData::default()),
311 rhs: Box::new(Lang::Integer {
312 value: (i + 1) as i32,
313 help_data: HelpData::default(),
314 }),
315 lhs: Box::new(tmp_var.clone()),
316 help_data: HelpData::default(),
317 }),
318 is_public: false,
319 help_data: HelpData::default(),
320 });
321 }
322
323 Ok((s, result))
324 }
325 Ok(_) => unreachable!("tuple_exp always returns Lang::Tuple"),
326 Err(r) => Err(r),
327 }
328}
329
330fn let_exp(s: Span) -> IResult<Span, Vec<Lang>> {
331 let res = (opt(terminated(tag("@pub"), multispace0)), base_let_exp).parse(s);
332 match res {
333 Ok((s, (None, le))) => Ok((s, le)),
334 Ok((s, (Some(_pu), le))) => {
335 let new_le = le
336 .iter()
337 .map(|x| match x {
338 Lang::Let {
339 variable: var,
340 r#type: typ,
341 expression: body,
342 is_public: _,
343 help_data: h,
344 } => {
345 let vari = Var::from_language(var.deref().clone())
346 .unwrap()
347 .to_language();
348 Lang::Let {
349 variable: Box::new(vari),
350 r#type: typ.clone(),
351 expression: body.clone(),
352 is_public: true,
353 help_data: h.clone(),
354 }
355 }
356 lan => lan.clone(),
357 })
358 .collect();
359 Ok((s, new_le))
360 }
361 Err(r) => Err(r),
362 }
363}
364
365fn base_type_exp(s: Span) -> IResult<Span, Lang> {
366 let res = (
367 terminated(tag("type"), multispace0),
368 type_alias,
369 equality_operator,
370 ltype,
371 terminated(tag(";"), multispace0),
372 )
373 .parse(s);
374 match res {
375 Ok((s, (_ty, Type::Alias(name, params, _, h), _eq, ty, _))) => {
376 let h2 = if !params.is_empty() {
377 params[0].clone().into()
378 } else {
379 HelpData::default()
380 };
381 let vari = Var::from_name(&name)
382 .set_type(Type::Params(params.clone(), h2))
383 .to_language();
384 Ok((
385 s,
386 Lang::Alias {
387 identifier: Box::new(vari),
388 parameters: params,
389 target_type: ty,
390 is_public: false,
391 help_data: h,
392 },
393 ))
394 }
395 Ok((s, (_ty, _, _eq, _ty2, _))) => Ok((s, Lang::Empty(_ty.into()))),
396 Err(r) => Err(r),
397 }
398}
399
400fn type_exp(s: Span) -> IResult<Span, Vec<Lang>> {
401 let res = (opt(terminated(tag("@pub"), multispace0)), base_type_exp).parse(s);
402 match res {
403 Ok((
404 s,
405 (
406 Some(_pu),
407 Lang::Alias {
408 identifier: var,
409 parameters: params,
410 target_type: typ,
411 help_data: h,
412 ..
413 },
414 ),
415 )) => Ok((
416 s,
417 vec![Lang::Alias {
418 identifier: var,
419 parameters: params,
420 target_type: typ,
421 is_public: true,
422 help_data: h,
423 }],
424 )),
425 Ok((
426 s,
427 (
428 None,
429 Lang::Alias {
430 identifier: var,
431 parameters: params,
432 target_type: typ,
433 help_data: h,
434 ..
435 },
436 ),
437 )) => {
438 let vari = Var::from_language(var.deref().clone())
439 .unwrap()
440 .to_language();
441 Ok((
442 s,
443 vec![Lang::Alias {
444 identifier: Box::new(vari),
445 parameters: params,
446 target_type: typ,
447 is_public: false,
448 help_data: h,
449 }],
450 ))
451 }
452 Err(r) => Err(r),
453 _ => todo!(),
454 }
455}
456
457fn base_opaque_exp(s: Span) -> IResult<Span, Lang> {
458 let res = (
459 terminated(tag("opaque"), multispace0),
460 type_alias,
461 equality_operator,
462 ltype,
463 terminated(tag(";"), multispace0),
464 )
465 .parse(s);
466 match res {
467 Ok((s, (_ty, Type::Alias(name, params, _, h), _eq, ty, _))) => {
468 let vari = Var::from_name(&name)
469 .set_type(Type::Params(params.clone(), params.clone().into()))
470 .set_opacity(true)
471 .to_language();
472 Ok((
473 s,
474 Lang::Alias {
475 identifier: Box::new(vari),
476 parameters: params,
477 target_type: ty,
478 is_public: false,
479 help_data: h,
480 },
481 ))
482 }
483 Ok((s, (_ty, _, _eq, _ty2, _))) => Ok((s, Lang::Empty(_ty.into()))),
484 Err(r) => Err(r),
485 }
486}
487
488fn opaque_exp(s: Span) -> IResult<Span, Vec<Lang>> {
489 let res = (opt(terminated(tag("@pub"), multispace0)), base_opaque_exp).parse(s);
490 match res {
491 Ok((
492 s,
493 (
494 Some(_pu),
495 Lang::Alias {
496 identifier: var,
497 parameters: params,
498 target_type: typ,
499 help_data: h,
500 ..
501 },
502 ),
503 )) => {
504 let vari = Var::from_language(var.deref().clone())
505 .unwrap()
506 .set_opacity(true)
507 .to_language();
508 Ok((
509 s,
510 vec![Lang::Alias {
511 identifier: Box::new(vari),
512 parameters: params,
513 target_type: typ,
514 is_public: true,
515 help_data: h,
516 }],
517 ))
518 }
519 Ok((
520 s,
521 (
522 None,
523 Lang::Alias {
524 identifier: var,
525 parameters: params,
526 target_type: typ,
527 help_data: h,
528 ..
529 },
530 ),
531 )) => {
532 let vari = Var::from_language(var.deref().clone())
533 .unwrap()
534 .set_opacity(true)
535 .to_language();
536 Ok((
537 s,
538 vec![Lang::Alias {
539 identifier: Box::new(vari),
540 parameters: params,
541 target_type: typ,
542 is_public: false,
543 help_data: h,
544 }],
545 ))
546 }
547 Err(r) => Err(r),
548 _ => todo!(),
549 }
550}
551
552pub fn module(s: Span) -> IResult<Span, Vec<Lang>> {
553 let res = (
554 terminated(tag("module"), multispace0),
555 terminated(variable_recognizer, multispace0),
556 terminated(tag("{"), multispace0),
557 base_parse,
558 terminated(tag("}"), multispace0),
559 opt(terminated(tag(";"), multispace0)),
560 )
561 .parse(s);
562 match res {
563 Ok((s, (modu, (name, _), _op, v, _cl, _dv))) => Ok((
564 s,
565 vec![Lang::Module {
566 name,
567 body: v,
568 module_position: ModulePosition::Internal,
569 config: Config::default(),
570 help_data: modu.into(),
571 }],
572 )),
573 Err(r) => Err(r),
574 }
575}
576
577fn import_module(s: Span) -> IResult<Span, Vec<Lang>> {
578 let res = (
579 terminated(tag("import"), multispace0),
580 terminated(variable_recognizer, multispace0),
581 opt((
582 terminated(tag("as"), multispace0),
583 terminated(variable_recognizer, multispace0),
584 )),
585 opt(terminated(tag(";"), multispace0)),
586 )
587 .parse(s);
588 match res {
589 Ok((s, (import_kw, (name, _), None, _))) => Ok((
590 s,
591 vec![Lang::ModuleImport {
592 value: name,
593 help_data: import_kw.into(),
594 }],
595 )),
596 Ok((s, (_, (name, h), Some((_, (alias, _))), _))) => {
597 let module_var = Lang::Variable {
598 name,
599 is_opaque: false,
600 related_type: Type::Empty(HelpData::default()),
601 help_data: h.clone(),
602 };
603 let alias_var = Var::from_name(&alias).to_language();
604 Ok((
605 s,
606 vec![Lang::Let {
607 variable: Box::new(alias_var),
608 r#type: Type::Empty(HelpData::default()),
609 expression: Box::new(module_var),
610 is_public: false,
611 help_data: h,
612 }],
613 ))
614 }
615 Err(r) => Err(r),
616 }
617}
618
619fn assign(s: Span) -> IResult<Span, Vec<Lang>> {
620 let res = (
621 variable,
622 alt((
623 terminated(tag("="), multispace0),
624 terminated(tag("<-"), multispace0),
625 )),
626 parse_elements,
627 opt(terminated(tag(";"), multispace0)),
628 )
629 .parse(s);
630 match res {
631 Ok((s, ((var, _), _eq, exp, Some(_)))) => Ok((
632 s,
633 vec![Lang::Assign {
634 identifier: Box::new(var.clone()),
635 expression: Box::new(exp),
636 help_data: var.into(),
637 }],
638 )),
639 Ok((s, ((var, _), _eq, exp, None))) => {
640 push_parse_error(SyntaxError::ForgottenSemicolon(exp.clone().into()));
641 let assign = Lang::Assign {
642 identifier: Box::new(var.clone()),
643 expression: Box::new(exp),
644 help_data: var.into(),
645 };
646 Ok((s, vec![assign]))
647 }
648 Err(r) => Err(r),
649 }
650}
651
652fn comment(s: Span) -> IResult<Span, Vec<Lang>> {
653 let res = (tag("#"), not_line_ending, opt(line_ending), multispace0).parse(s);
654 match res {
655 Ok((s, (_hashtag, txt, _, _))) => Ok((
656 s,
657 vec![Lang::Comment {
658 value: txt.to_string(),
659 help_data: _hashtag.into(),
660 }],
661 )),
662 Err(r) => Err(r),
663 }
664}
665
666pub fn simple_exp(s: Span) -> IResult<Span, Vec<Lang>> {
667 let res = (parse_elements, opt(terminated(tag(";"), multispace0))).parse(s);
668 match res {
669 Ok((s, (lang, Some(_)))) => Ok((s, vec![lang])),
670 Ok((s, (lang, None))) => {
671 push_parse_error(SyntaxError::ForgottenSemicolon(lang.clone().into()));
672 Ok((s, vec![lang]))
673 }
674 Err(r) => Err(r),
675 }
676}
677
678fn mod_imp(s: Span) -> IResult<Span, Vec<Lang>> {
679 let res = (
680 terminated(tag("mod"), multispace0),
681 terminated(variable_exp, multispace0),
682 terminated(tag(";"), multispace0),
683 )
684 .parse(s);
685 match res {
686 Ok((s, (_mod, (name, _), _sc))) => Ok((
687 s,
688 vec![Lang::ModuleImport {
689 value: name.to_string(),
690 help_data: _mod.into(),
691 }],
692 )),
693 Err(r) => Err(r),
694 }
695}
696
697fn import_var(s: Span) -> IResult<Span, Vec<Lang>> {
698 let res = (
699 terminated(tag("use"), multispace0),
700 variable,
701 terminated(tag(";"), multispace0),
702 )
703 .parse(s);
704 match res {
705 Ok((s, (_use, (lang, case), _sc))) => {
706 let res = match case {
707 Case::Maj => Var::from_language(lang).unwrap().to_alias_lang(),
708 _ => Var::from_language(lang).unwrap().to_let(),
709 };
710 Ok((s, vec![res]))
711 }
712 Err(r) => Err(r),
713 }
714}
715
716fn import_type(s: Span) -> IResult<Span, Vec<Lang>> {
717 let res = (
718 terminated(tag("use"), multispace0),
719 type_alias,
720 terminated(tag(";"), multispace0),
721 )
722 .parse(s);
723
724 match res {
725 Ok((s, (_use, alias, _sc))) => Ok((
726 s,
727 vec![Lang::Import {
728 value: alias,
729 help_data: _use.into(),
730 }],
731 )),
732 Err(r) => Err(r),
733 }
734}
735
736fn tests(s: Span) -> IResult<Span, Vec<Lang>> {
737 let res = (tag("Test"), delimited(tag("["), base_parse, tag("]"))).parse(s);
738 match res {
739 Ok((s, (_t, body))) => Ok((
740 s,
741 vec![Lang::Test {
742 value: body,
743 help_data: _t.into(),
744 }],
745 )),
746 Err(r) => Err(r),
747 }
748}
749
750fn library(s: Span) -> IResult<Span, Vec<Lang>> {
751 let res = (
752 tag("library("),
753 variable_exp,
754 tag(")"),
755 opt(tag(";")),
756 multispace0,
757 )
758 .parse(s);
759
760 match res {
761 Ok((s, (_lib, (var, h), _cl, Some(_col), _))) => Ok((
762 s,
763 vec![Lang::Library {
764 value: var,
765 help_data: h.clone(),
766 }],
767 )),
768 Ok((_, (_lib, _var, _cl, None, _))) => {
769 panic!("You forgot to put a ';' at the end of the line")
770 }
771 Err(r) => Err(r),
772 }
773}
774
775fn use_item_exp(s: Span) -> IResult<Span, crate::components::language::use_lang::UseItem> {
776 use crate::components::language::use_lang::UseItem;
777 let res = (
779 terminated(variable_recognizer, multispace0),
780 opt(preceded(
781 pair(tag("as"), multispace0),
782 terminated(variable_recognizer, multispace0),
783 )),
784 )
785 .parse(s);
786 match res {
787 Ok((s, ((name, _), alias_opt))) => {
788 let alias = alias_opt.map(|(alias_name, _)| alias_name);
789 Ok((s, UseItem { name, alias }))
790 }
791 Err(r) => Err(r),
792 }
793}
794
795fn use_items_selector(
796 s: Span,
797) -> IResult<Span, crate::components::language::use_lang::UseSelector> {
798 use crate::components::language::use_lang::UseSelector;
799 let res = (
800 pair(tag("{"), multispace0),
801 separated_list0(pair(tag(","), multispace0), use_item_exp),
802 opt(pair(tag(","), multispace0)),
803 pair(tag("}"), multispace0),
804 )
805 .parse(s);
806 match res {
807 Ok((s, (_, items, _, _))) => Ok((s, UseSelector::Items(items))),
808 Err(r) => Err(r),
809 }
810}
811
812fn use_selector_exp(s: Span) -> IResult<Span, crate::components::language::use_lang::UseSelector> {
813 use crate::components::language::use_lang::UseSelector;
814 alt((
815 map(terminated(tag("*"), multispace0), |_| UseSelector::Wildcard),
816 use_items_selector,
817 ))
818 .parse(s)
819}
820
821fn use_module_directive(s: Span) -> IResult<Span, Vec<Lang>> {
822 use crate::components::language::use_lang::UseSelector;
823
824 let res = (
826 terminated(tag("use"), multispace0),
827 terminated(variable_recognizer, multispace0),
828 pair(tag("::"), multispace0),
829 )
830 .parse(s);
831
832 let (s, (use_kw, (first_seg, _), _)) = match res {
833 Ok(r) => r,
834 Err(r) => return Err(r),
835 };
836
837 let mut path = vec![first_seg];
838 let mut current_s = s;
839 let selector;
840
841 loop {
842 match use_selector_exp(current_s.clone()) {
843 Ok((s2, sel)) => {
844 selector = sel;
845 current_s = s2;
846 break;
847 }
848 Err(_) => match terminated(variable_recognizer, multispace0).parse(current_s.clone()) {
849 Ok((s2, (seg, _))) => {
850 let colon_res: IResult<Span, (Span, Span)> =
851 pair(tag("::"), multispace0).parse(s2.clone());
852 match colon_res {
853 Ok((s3, _)) => {
854 path.push(seg);
855 current_s = s3;
856 }
857 Err(_) => {
858 use crate::components::language::use_lang::UseItem;
859 selector = UseSelector::Items(vec![UseItem {
860 name: seg,
861 alias: None,
862 }]);
863 current_s = s2;
864 break;
865 }
866 }
867 }
868 Err(e) => return Err(e),
869 },
870 }
871 }
872
873 let res = terminated(tag(";"), multispace0).parse(current_s);
874 let (s, _) = match res {
875 Ok(r) => r,
876 Err(r) => return Err(r),
877 };
878
879 Ok((
880 s,
881 vec![Lang::UseModule {
882 module_path: path,
883 selector,
884 help_data: use_kw.into(),
885 }],
886 ))
887}
888
889fn use_exp(s: Span) -> IResult<Span, Vec<Lang>> {
890 let res = (
891 tag("use("),
892 chars,
893 tag(", "),
894 alt((vector, chars)),
895 terminated(tag(");"), multispace0),
896 )
897 .parse(s);
898 match res {
899 Ok((s, (us, lib, _, members, _))) => Ok((
900 s,
901 vec![Lang::Use {
902 lang: Box::new(lib),
903 members: Box::new(members),
904 help_data: us.into(),
905 }],
906 )),
907 Err(r) => Err(r),
908 }
909}
910
911fn custom_operators(s: Span) -> IResult<Span, (String, HelpData)> {
912 let res = custom_op.parse(s);
913 match res {
914 Ok((s, co)) => Ok((s, (co.clone().to_string(), co.into()))),
915 Err(r) => Err(r),
916 }
917}
918
919fn return_stmt(s: Span) -> IResult<Span, Vec<Lang>> {
920 let (s, e) = return_exp(s)?;
921 Ok((s, vec![e]))
922}
923
924fn stmt_exp(s: Span) -> IResult<Span, Vec<Lang>> {
925 let res = (parse_elements, terminated(tag(";"), multispace0)).parse(s);
926 match res {
927 Ok((s, (lang, _))) => Ok((s, vec![lang])),
928 Err(r) => Err(r),
929 }
930}
931
932fn signature_variable(s: Span) -> IResult<Span, Vec<Lang>> {
933 let res = (
934 tag("@"),
935 alt((variable_recognizer, custom_operators)),
936 terminated(tag(":"), multispace0),
937 ltype,
938 terminated(tag(";"), multispace0),
939 )
940 .parse(s);
941 match res {
942 Ok((s, (at, (name, h), _col, typ, _))) => {
943 let var2 = Var::from_name(&name).set_help_data(h).set_type(typ.clone());
944 Ok((
945 s,
946 vec![Lang::Signature {
947 identifier: var2,
948 target_type: typ,
949 help_data: at.into(),
950 }],
951 ))
952 }
953 Err(r) => Err(r),
954 }
955}
956
957fn signature_opaque(s: Span) -> IResult<Span, Vec<Lang>> {
958 let res = (
959 tag("@"),
960 type_alias,
961 terminated(tag(":"), multispace0),
962 ltype,
963 terminated(tag(";"), multispace0),
964 )
965 .parse(s);
966 match res {
967 Ok((s, (at, Type::Alias(name, _params, _, h), _, typ, _))) => {
968 let var2 = Var::from_name(&name)
969 .set_help_data(h.clone())
970 .set_type(typ.clone());
971 Ok((
972 s,
973 vec![Lang::Signature {
974 identifier: var2,
975 target_type: typ,
976 help_data: at.into(),
977 }],
978 ))
979 }
980 Ok((_s, (_, _, _, _, _))) => todo!(),
981 Err(r) => Err(r),
982 }
983}
984
985pub fn signature(s: Span) -> IResult<Span, Vec<Lang>> {
986 alt((signature_opaque, signature_variable)).parse(s)
987}
988
989fn for_loop(s: Span) -> IResult<Span, Vec<Lang>> {
990 let res = (
991 terminated(tag("for"), multispace0),
992 terminated(tag("("), multispace0),
993 terminated(variable_exp, multispace0),
994 terminated(tag("in"), multispace0),
995 terminated(single_element, multispace0),
996 terminated(tag(")"), multispace0),
997 scope,
998 terminated(tag(";"), multispace0),
999 )
1000 .parse(s);
1001 match res {
1002 Ok((s, (_for, _op, (var_str, _h), _in, iterator, _cl, scop, _semi))) => Ok((
1003 s,
1004 vec![Lang::ForLoop {
1005 identifier: Var::from_name(&var_str),
1006 expression: Box::new(iterator),
1007 body: Box::new(scop),
1008 help_data: _for.into(),
1009 }],
1010 )),
1011 Err(r) => Err(r),
1012 }
1013}
1014
1015fn while_loop(s: Span) -> IResult<Span, Vec<Lang>> {
1016 let res = (
1017 terminated(tag("while"), multispace0),
1018 terminated(tag("("), multispace0),
1019 terminated(single_element, multispace0),
1020 terminated(tag(")"), multispace0),
1021 scope,
1022 terminated(tag(";"), multispace0),
1023 )
1024 .parse(s);
1025 match res {
1026 Ok((s, (_while, _op, condition, _cl, scop, _semi))) => Ok((
1027 s,
1028 vec![Lang::WhileLoop {
1029 condition: Box::new(condition),
1030 body: Box::new(scop),
1031 help_data: _while.into(),
1032 }],
1033 )),
1034 Err(r) => Err(r),
1035 }
1036}
1037
1038fn loop_loop(s: Span) -> IResult<Span, Vec<Lang>> {
1039 let res = (
1040 terminated(tag("loop"), multispace0),
1041 scope,
1042 terminated(tag(";"), multispace0),
1043 )
1044 .parse(s);
1045 match res {
1046 Ok((s, (_loop, scop, _semi))) => Ok((
1047 s,
1048 vec![Lang::Loop {
1049 body: Box::new(scop),
1050 help_data: _loop.into(),
1051 }],
1052 )),
1053 Err(r) => Err(r),
1054 }
1055}
1056
1057fn test_block(s: Span) -> IResult<Span, Vec<Lang>> {
1058 let res = (terminated(tag("Test"), multispace0), scope).parse(s);
1059 match res {
1062 Ok((s, (tst, body))) => Ok((
1063 s,
1064 vec![Lang::TestBlock {
1065 value: Box::new(body),
1066 help_data: tst.into(),
1067 }],
1068 )),
1069 Err(r) => Err(r),
1070 }
1071}
1072
1073pub fn base_parse(s: Span) -> IResult<Span, Vec<Lang>> {
1075 let res = (
1076 opt(multispace0),
1077 many0(alt((
1078 alt((
1079 library,
1080 break_exp,
1081 use_exp,
1082 test_block,
1083 while_loop,
1084 loop_loop,
1085 for_loop,
1086 signature,
1087 tests,
1088 import_module,
1089 use_module_directive,
1090 import_type,
1091 )),
1092 alt((
1093 import_var,
1094 mod_imp,
1095 comment,
1096 type_exp,
1097 opaque_exp,
1098 let_tuple_exp,
1099 let_exp,
1100 module,
1101 assign,
1102 return_stmt,
1103 stmt_exp,
1104 )),
1105 ))),
1106 opt(parse_elements),
1107 )
1108 .parse(s);
1109 match res {
1110 Ok((s, (_, v, None))) if v.is_empty() => Ok((s, vec![])),
1112 Ok((s, (_, v, Some(expr)))) if v.is_empty() => Ok((s, vec![expr])),
1114 Ok((s, (_, v, trailing))) => {
1116 let mut result: Vec<Lang> = v.into_iter().flatten().collect();
1117 if let Some(expr) = trailing {
1118 result.push(expr);
1119 }
1120 Ok((s, result))
1121 }
1122 Err(r) => Err(r),
1123 }
1124}
1125
1126pub fn parse(s: Span) -> ParseResult {
1131 let res = base_parse(s.clone());
1132 match res {
1133 Ok((remaining, v)) => {
1134 if !remaining.fragment().is_empty() {
1135 let element = remaining
1136 .fragment()
1137 .lines()
1138 .next()
1139 .unwrap_or("")
1140 .trim()
1141 .to_string();
1142 let line = remaining.location_line();
1143 let help_data = HelpData::from(remaining);
1144 push_parse_error(SyntaxError::UnknownElement {
1145 element,
1146 line,
1147 help_data,
1148 });
1149 }
1150 ParseResult::new(Lang::Lines {
1151 value: v.clone(),
1152 help_data: v.into(),
1153 })
1154 }
1155 Err(_) => panic!("Can't parse string {}", s),
1156 }
1157}
1158
1159pub fn parse_legacy(s: Span) -> Lang {
1164 parse(s).ast
1165}
1166
1167pub fn parse2(s: Span) -> Result<Lang, String> {
1168 let res = base_parse(s.clone());
1169 let _ = take_parse_errors();
1171 match res {
1172 Ok((_, v)) => Ok(v[0].clone()),
1173 Err(_) => Err(format!("Can't parse string {}", s)),
1174 }
1175}
1176
1177pub fn parse_from_string(source: &str, filename: &str) -> Lang {
1182 use crate::components::error_message::help_data::register_source;
1183
1184 register_source(filename, source);
1186
1187 let span: Span = LocatedSpan::new_extra(source, filename.to_string());
1189
1190 parse(span).ast
1192}
1193
1194pub fn parse_from_string_with_errors(source: &str, filename: &str) -> ParseResult {
1196 use crate::components::error_message::help_data::register_source;
1197
1198 register_source(filename, source);
1200
1201 let span: Span = LocatedSpan::new_extra(source, filename.to_string());
1203
1204 parse(span)
1206}
1207
1208#[cfg(test)]
1210mod tesus {
1211 use super::*;
1212
1213 #[test]
1214 fn test_semicolon1() {
1215 let res = parse("let a <- 5".into());
1216 assert!(
1218 res.has_errors(),
1219 "Missing semicolon should produce a syntax error"
1220 );
1221 assert_eq!(res.errors.len(), 1, "Should have exactly one error");
1222 match &res.errors[0] {
1223 SyntaxError::ForgottenSemicolon(_) => (),
1224 _ => panic!("Expected ForgottenSemicolon error"),
1225 }
1226 }
1227
1228 #[test]
1229 fn test_semicolon_standalone_exp() {
1230 let res = parse("f(x)".into());
1231 assert!(
1233 !res.has_errors(),
1234 "A standalone expression without semicolon is valid (case 2)"
1235 );
1236 }
1237
1238 #[test]
1239 fn test_semicolon_assign() {
1240 let res = parse("a <- 12".into());
1241 assert!(
1242 res.has_errors(),
1243 "An assign expression without semicolon should produce a syntax error"
1244 );
1245 match &res.errors[0] {
1246 SyntaxError::ForgottenSemicolon(_) => (),
1247 _ => panic!("Expected ForgottenSemicolon error"),
1248 }
1249 }
1250
1251 #[test]
1252 fn test_assign1() {
1253 let res = assign("a <- 12;".into()).unwrap().1;
1254 assert_eq!(
1255 "Assign",
1256 res[0].simple_print(),
1257 "The expression 'a <- 12;' should be identified as an assignation"
1258 );
1259 }
1260
1261 #[test]
1264 fn test_let_tuple_basic() {
1265 let res = let_tuple_exp("let :{a, b, c} <- :{1, 2, 3};".into())
1266 .unwrap()
1267 .1;
1268 assert_eq!(
1270 res.len(),
1271 4,
1272 "Should produce 4 Let statements (1 tmp + 3 bindings)"
1273 );
1274 for item in &res {
1275 assert!(
1276 item.simple_print().starts_with("let"),
1277 "Each item should be a Let, got: {}",
1278 item.simple_print()
1279 );
1280 }
1281 }
1282
1283 #[test]
1284 fn test_let_tuple_tmp_variable() {
1285 let res = let_tuple_exp("let :{a, b} <- :{1, 2};".into()).unwrap().1;
1286 if let Lang::Let { variable: var, .. } = &res[0] {
1288 if let Lang::Variable { name, .. } = var.as_ref() {
1289 assert_eq!(name, "__tuple_tmp__");
1290 } else {
1291 panic!("Expected Variable in first Let");
1292 }
1293 } else {
1294 panic!("Expected Let");
1295 }
1296 }
1297
1298 #[test]
1299 fn test_let_tuple_bindings() {
1300 let res = let_tuple_exp("let :{x, y} <- :{10, 20};".into()).unwrap().1;
1301 if let Lang::Let {
1303 variable: var,
1304 expression: body,
1305 ..
1306 } = &res[1]
1307 {
1308 if let Lang::Variable { name, .. } = var.as_ref() {
1309 assert_eq!(name, "x");
1310 } else {
1311 panic!("Expected Variable 'x'");
1312 }
1313 assert_eq!(
1314 body.simple_print(),
1315 "Operator",
1316 "Body should be a Dot operator"
1317 );
1318 } else {
1319 panic!("Expected Let");
1320 }
1321 if let Lang::Let { variable: var, .. } = &res[2] {
1323 if let Lang::Variable { name, .. } = var.as_ref() {
1324 assert_eq!(name, "y");
1325 } else {
1326 panic!("Expected Variable 'y'");
1327 }
1328 } else {
1329 panic!("Expected Let");
1330 }
1331 }
1332
1333 #[test]
1334 fn test_let_tuple_wildcard() {
1335 let res = let_tuple_exp("let :{a, _, c} <- :{1, 2, 3};".into())
1336 .unwrap()
1337 .1;
1338 assert_eq!(
1340 res.len(),
1341 3,
1342 "Should produce 3 Let statements (wildcard skipped)"
1343 );
1344 if let Lang::Let { variable: var, .. } = &res[1] {
1346 if let Lang::Variable { name, .. } = var.as_ref() {
1347 assert_eq!(name, "a");
1348 } else {
1349 panic!("Expected Variable 'a'");
1350 }
1351 } else {
1352 panic!("Expected Let");
1353 }
1354 if let Lang::Let { variable: var, .. } = &res[2] {
1356 if let Lang::Variable { name, .. } = var.as_ref() {
1357 assert_eq!(name, "c");
1358 } else {
1359 panic!("Expected Variable 'c'");
1360 }
1361 } else {
1362 panic!("Expected Let");
1363 }
1364 }
1365
1366 #[test]
1367 fn test_let_tuple_in_full_parse() {
1368 let res = parse("let :{a, b, c} <- :{1, 2, 3};".into());
1369 assert!(
1370 !res.has_errors(),
1371 "Let tuple destructuring should parse without errors"
1372 );
1373 }
1374
1375 #[test]
1376 fn test_let_tuple_with_equals() {
1377 let res = let_tuple_exp("let :{a, b} = :{1, 2};".into()).unwrap().1;
1378 assert_eq!(res.len(), 3, "Should work with '=' operator too");
1379 }
1380
1381 #[test]
1382 fn test_let_tuple_type_check() {
1383 use crate::components::context::Context;
1384 use crate::processes::type_checking::typing;
1385 use crate::utils::builder;
1386
1387 let ast = parse("let :{a, b, c} <- :{1, 2, 3};".into()).ast;
1388 let context = Context::empty();
1389 let tc = typing(&context, &ast);
1390
1391 let ty_a = tc
1393 .context
1394 .get_type_from_existing_variable(crate::components::language::var::Var::from_name("a"));
1395 let ty_b = tc
1396 .context
1397 .get_type_from_existing_variable(crate::components::language::var::Var::from_name("b"));
1398 let ty_c = tc
1399 .context
1400 .get_type_from_existing_variable(crate::components::language::var::Var::from_name("c"));
1401
1402 assert_eq!(
1403 ty_a,
1404 builder::integer_type(1),
1405 "Variable 'a' should be Integer(1)"
1406 );
1407 assert_eq!(
1408 ty_b,
1409 builder::integer_type(2),
1410 "Variable 'b' should be Integer(2)"
1411 );
1412 assert_eq!(
1413 ty_c,
1414 builder::integer_type(3),
1415 "Variable 'c' should be Integer(3)"
1416 );
1417 }
1418
1419 #[test]
1420 fn test_let_tuple_type_check_mixed_types() {
1421 use crate::components::context::Context;
1422 use crate::processes::type_checking::typing;
1423 use crate::utils::builder;
1424
1425 let ast = parse("let :{x, y} <- :{1, 'hello'};".into()).ast;
1426 let context = Context::empty();
1427 let tc = typing(&context, &ast);
1428
1429 let ty_x = tc
1430 .context
1431 .get_type_from_existing_variable(crate::components::language::var::Var::from_name("x"));
1432 let ty_y = tc
1433 .context
1434 .get_type_from_existing_variable(crate::components::language::var::Var::from_name("y"));
1435
1436 assert_eq!(
1437 ty_x,
1438 builder::integer_type(1),
1439 "Variable 'x' should be Integer(1)"
1440 );
1441 assert_eq!(
1442 ty_y,
1443 builder::character_type("hello"),
1444 "Variable 'y' should be Character('hello')"
1445 );
1446 }
1447
1448 #[test]
1449 fn test_fn_function_type_syntax_error() {
1450 let res = parse("let f: fn(a: int) -> int <- fn(x: int): int { x };".into());
1451 assert!(
1452 res.has_errors(),
1453 "Using 'fn(...)' in type position should produce a syntax error"
1454 );
1455 let fn_type_error = res
1456 .errors
1457 .iter()
1458 .any(|e| matches!(e, SyntaxError::FunctionTypeSyntax(_)));
1459 assert!(
1460 fn_type_error,
1461 "Expected FunctionTypeSyntax error, got: {:?}",
1462 res.errors
1463 );
1464 }
1465
1466 #[test]
1467 fn test_use_wildcard_parses() {
1468 use crate::components::language::use_lang::UseSelector;
1469 let lang = parse2("use Math::*;".into()).expect("parse failed");
1470 match lang {
1471 Lang::UseModule {
1472 module_path,
1473 selector,
1474 ..
1475 } => {
1476 assert_eq!(module_path, vec!["Math".to_string()]);
1477 assert_eq!(selector, UseSelector::Wildcard);
1478 }
1479 other => panic!("Expected UseModule, got {:?}", other),
1480 }
1481 }
1482
1483 #[test]
1484 fn test_use_items_parses() {
1485 use crate::components::language::use_lang::{UseItem, UseSelector};
1486 let lang = parse2("use Math::{pi, sin as s};".into()).expect("parse failed");
1487 match lang {
1488 Lang::UseModule {
1489 module_path,
1490 selector,
1491 ..
1492 } => {
1493 assert_eq!(module_path, vec!["Math".to_string()]);
1494 assert_eq!(
1495 selector,
1496 UseSelector::Items(vec![
1497 UseItem {
1498 name: "pi".to_string(),
1499 alias: None
1500 },
1501 UseItem {
1502 name: "sin".to_string(),
1503 alias: Some("s".to_string())
1504 },
1505 ])
1506 );
1507 }
1508 other => panic!("Expected UseModule, got {:?}", other),
1509 }
1510 }
1511
1512 #[test]
1513 fn test_use_nested_path_parses() {
1514 use crate::components::language::use_lang::UseSelector;
1515 let lang = parse2("use Aa::Bb::Cc::*;".into()).expect("parse failed");
1516 match lang {
1517 Lang::UseModule {
1518 module_path,
1519 selector,
1520 ..
1521 } => {
1522 assert_eq!(
1523 module_path,
1524 vec!["Aa".to_string(), "Bb".to_string(), "Cc".to_string()]
1525 );
1526 assert_eq!(selector, UseSelector::Wildcard);
1527 }
1528 other => panic!("Expected UseModule, got {:?}", other),
1529 }
1530 }
1531}