Skip to main content

typr_core/processes/parsing/
mod.rs

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::variable;
28use crate::processes::parsing::elements::variable2;
29use crate::processes::parsing::elements::variable_exp;
30use crate::processes::parsing::elements::variable_recognizer;
31use crate::processes::parsing::elements::vector;
32use crate::processes::parsing::elements::Case;
33use crate::processes::parsing::types::ltype;
34use crate::processes::parsing::types::type_alias;
35use nom::branch::alt;
36use nom::bytes::complete::tag;
37use nom::character::complete::line_ending;
38use nom::character::complete::multispace0;
39use nom::character::complete::not_line_ending;
40use nom::combinator::opt;
41use nom::multi::many0;
42use nom::sequence::delimited;
43use nom::sequence::preceded;
44use nom::sequence::terminated;
45use nom::IResult;
46use nom::Parser;
47use nom_locate::LocatedSpan;
48use std::ops::Deref;
49
50type Span<'a> = LocatedSpan<&'a str, String>;
51
52/// Result of parsing containing the AST and any syntax errors collected
53#[derive(Debug, Clone)]
54pub struct ParseResult {
55    /// The parsed AST (may contain Lang::SyntaxErr nodes)
56    pub ast: Lang,
57    /// All syntax errors collected from the AST
58    pub errors: Vec<SyntaxError>,
59}
60
61impl ParseResult {
62    /// Create a new ParseResult from an AST, automatically collecting errors
63    pub fn new(ast: Lang) -> Self {
64        let errors = collect_syntax_errors(&ast);
65        ParseResult { ast, errors }
66    }
67
68    /// Check if parsing produced any errors
69    pub fn has_errors(&self) -> bool {
70        !self.errors.is_empty()
71    }
72
73    /// Get the AST (regardless of errors)
74    pub fn get_ast(&self) -> &Lang {
75        &self.ast
76    }
77
78    /// Get a clean AST with SyntaxErr nodes replaced by their inner expressions
79    pub fn get_clean_ast(&self) -> Lang {
80        clean_syntax_errors(&self.ast)
81    }
82}
83
84/// Recursively collect all SyntaxError from a Lang AST
85fn collect_syntax_errors(lang: &Lang) -> Vec<SyntaxError> {
86    let mut errors = Vec::new();
87    collect_syntax_errors_recursive(lang, &mut errors);
88    errors
89}
90
91fn collect_syntax_errors_recursive(lang: &Lang, errors: &mut Vec<SyntaxError>) {
92    match lang {
93        Lang::SyntaxErr(inner, err) => {
94            errors.push(err.clone());
95            collect_syntax_errors_recursive(inner, errors);
96        }
97        Lang::Lines(v, _)
98        | Lang::Scope(v, _)
99        | Lang::Array(v, _)
100        | Lang::Tuple(v, _)
101        | Lang::Vector(v, _)
102        | Lang::Sequence(v, _)
103        | Lang::Test(v, _) => {
104            for item in v {
105                collect_syntax_errors_recursive(item, errors);
106            }
107        }
108        Lang::Module(_, v, _, _, _) => {
109            for item in v {
110                collect_syntax_errors_recursive(item, errors);
111            }
112        }
113        Lang::Function(_, _, body, _) => {
114            collect_syntax_errors_recursive(body, errors);
115        }
116        Lang::Let(var, _, body, _) => {
117            collect_syntax_errors_recursive(var, errors);
118            collect_syntax_errors_recursive(body, errors);
119        }
120        Lang::Alias(var, _, _, _) => {
121            collect_syntax_errors_recursive(var, errors);
122        }
123        Lang::If(cond, then_branch, else_branch, _) => {
124            collect_syntax_errors_recursive(cond, errors);
125            collect_syntax_errors_recursive(then_branch, errors);
126            collect_syntax_errors_recursive(else_branch, errors);
127        }
128        Lang::Match(expr, _, cases, _) => {
129            collect_syntax_errors_recursive(expr, errors);
130            for (_, case_body) in cases {
131                collect_syntax_errors_recursive(case_body, errors);
132            }
133        }
134        Lang::FunctionApp(func, args, _) | Lang::VecFunctionApp(func, args, _) => {
135            collect_syntax_errors_recursive(func, errors);
136            for arg in args {
137                collect_syntax_errors_recursive(arg, errors);
138            }
139        }
140        Lang::MethodCall(obj, args, _, _) => {
141            collect_syntax_errors_recursive(obj, errors);
142            for arg in args {
143                collect_syntax_errors_recursive(arg, errors);
144            }
145        }
146        Lang::Operator(_, left, right, _) => {
147            collect_syntax_errors_recursive(left, errors);
148            collect_syntax_errors_recursive(right, errors);
149        }
150        Lang::Union(left, right, _) => {
151            collect_syntax_errors_recursive(left, errors);
152            collect_syntax_errors_recursive(right, errors);
153        }
154        Lang::Assign(target, value, _) => {
155            collect_syntax_errors_recursive(target, errors);
156            collect_syntax_errors_recursive(value, errors);
157        }
158        Lang::ArrayIndexing(arr, idx, _) => {
159            collect_syntax_errors_recursive(arr, errors);
160            collect_syntax_errors_recursive(idx, errors);
161        }
162        Lang::Tag(_, inner, _) => {
163            collect_syntax_errors_recursive(inner, errors);
164        }
165        Lang::Return(inner, _)
166        | Lang::Lambda(inner, _)
167        | Lang::Not(inner, _)
168        | Lang::TestBlock(inner, _) => {
169            collect_syntax_errors_recursive(inner, errors);
170        }
171        Lang::ForLoop(_, iter, body, _) => {
172            collect_syntax_errors_recursive(iter, errors);
173            collect_syntax_errors_recursive(body, errors);
174        }
175        Lang::WhileLoop(cond, body, _) => {
176            collect_syntax_errors_recursive(cond, errors);
177            collect_syntax_errors_recursive(body, errors);
178        }
179        Lang::Use(lib, members, _) => {
180            collect_syntax_errors_recursive(lib, errors);
181            collect_syntax_errors_recursive(members, errors);
182        }
183        Lang::KeyValue(_, value, _) => {
184            collect_syntax_errors_recursive(value, errors);
185        }
186        Lang::JSBlock(inner, _, _) => {
187            collect_syntax_errors_recursive(inner, errors);
188        }
189        Lang::Record(args, _) => {
190            for arg in args {
191                collect_syntax_errors_recursive(&arg.1, errors);
192            }
193        }
194        Lang::RFunction(args, _, _) => {
195            for arg in args {
196                collect_syntax_errors_recursive(arg, errors);
197            }
198        }
199        // Leaf nodes - no children to check
200        Lang::Number(_, _)
201        | Lang::Integer(_, _)
202        | Lang::Bool(_, _)
203        | Lang::Char(_, _)
204        | Lang::Variable(_, _, _, _)
205        | Lang::Comment(_, _)
206        | Lang::ModuleImport(_, _)
207        | Lang::Import(_, _)
208        | Lang::GenFunc(_, _, _)
209        | Lang::VecBlock(_, _)
210        | Lang::Library(_, _)
211        | Lang::Exp(_, _)
212        | Lang::Signature(_, _, _)
213        | Lang::Empty(_)
214        | Lang::Break(_)
215        | Lang::ModuleDecl(_, _) => {}
216    }
217}
218
219/// Clean an AST by replacing SyntaxErr nodes with their inner expressions
220fn clean_syntax_errors(lang: &Lang) -> Lang {
221    match lang {
222        Lang::SyntaxErr(inner, _) => clean_syntax_errors(inner),
223        Lang::Lines(v, h) => Lang::Lines(v.iter().map(clean_syntax_errors).collect(), h.clone()),
224        Lang::Scope(v, h) => Lang::Scope(v.iter().map(clean_syntax_errors).collect(), h.clone()),
225        Lang::Array(v, h) => Lang::Array(v.iter().map(clean_syntax_errors).collect(), h.clone()),
226        Lang::Tuple(v, h) => Lang::Tuple(v.iter().map(clean_syntax_errors).collect(), h.clone()),
227        Lang::Vector(v, h) => Lang::Vector(v.iter().map(clean_syntax_errors).collect(), h.clone()),
228        Lang::Sequence(v, h) => {
229            Lang::Sequence(v.iter().map(clean_syntax_errors).collect(), h.clone())
230        }
231        Lang::Test(v, h) => Lang::Test(v.iter().map(clean_syntax_errors).collect(), h.clone()),
232        Lang::Module(name, v, pos, config, h) => Lang::Module(
233            name.clone(),
234            v.iter().map(clean_syntax_errors).collect(),
235            pos.clone(),
236            config.clone(),
237            h.clone(),
238        ),
239        Lang::Function(params, ret_ty, body, h) => Lang::Function(
240            params.clone(),
241            ret_ty.clone(),
242            Box::new(clean_syntax_errors(body)),
243            h.clone(),
244        ),
245        Lang::Let(var, ty, body, h) => Lang::Let(
246            Box::new(clean_syntax_errors(var)),
247            ty.clone(),
248            Box::new(clean_syntax_errors(body)),
249            h.clone(),
250        ),
251        Lang::If(cond, then_b, else_b, h) => Lang::If(
252            Box::new(clean_syntax_errors(cond)),
253            Box::new(clean_syntax_errors(then_b)),
254            Box::new(clean_syntax_errors(else_b)),
255            h.clone(),
256        ),
257        Lang::Match(expr, var, cases, h) => {
258            let clean_cases = cases
259                .iter()
260                .map(|(ty, body)| (ty.clone(), Box::new(clean_syntax_errors(body))))
261                .collect();
262            Lang::Match(
263                Box::new(clean_syntax_errors(expr)),
264                var.clone(),
265                clean_cases,
266                h.clone(),
267            )
268        }
269        Lang::FunctionApp(func, args, h) => Lang::FunctionApp(
270            Box::new(clean_syntax_errors(func)),
271            args.iter().map(clean_syntax_errors).collect(),
272            h.clone(),
273        ),
274        Lang::VecFunctionApp(func, args, h) => Lang::VecFunctionApp(
275            Box::new(clean_syntax_errors(func)),
276            args.iter().map(clean_syntax_errors).collect(),
277            h.clone(),
278        ),
279        Lang::MethodCall(obj, args, ty, h) => Lang::MethodCall(
280            Box::new(clean_syntax_errors(obj)),
281            args.iter().map(clean_syntax_errors).collect(),
282            ty.clone(),
283            h.clone(),
284        ),
285        Lang::Operator(op, left, right, h) => Lang::Operator(
286            op.clone(),
287            Box::new(clean_syntax_errors(left)),
288            Box::new(clean_syntax_errors(right)),
289            h.clone(),
290        ),
291        Lang::Union(left, right, h) => Lang::Union(
292            Box::new(clean_syntax_errors(left)),
293            Box::new(clean_syntax_errors(right)),
294            h.clone(),
295        ),
296        Lang::Assign(target, value, h) => Lang::Assign(
297            Box::new(clean_syntax_errors(target)),
298            Box::new(clean_syntax_errors(value)),
299            h.clone(),
300        ),
301        Lang::ArrayIndexing(arr, idx, h) => Lang::ArrayIndexing(
302            Box::new(clean_syntax_errors(arr)),
303            Box::new(clean_syntax_errors(idx)),
304            h.clone(),
305        ),
306        Lang::Tag(name, inner, h) => Lang::Tag(
307            name.clone(),
308            Box::new(clean_syntax_errors(inner)),
309            h.clone(),
310        ),
311        Lang::Return(inner, h) => Lang::Return(Box::new(clean_syntax_errors(inner)), h.clone()),
312        Lang::Lambda(inner, h) => Lang::Lambda(Box::new(clean_syntax_errors(inner)), h.clone()),
313        Lang::Not(inner, h) => Lang::Not(Box::new(clean_syntax_errors(inner)), h.clone()),
314        Lang::TestBlock(inner, h) => {
315            Lang::TestBlock(Box::new(clean_syntax_errors(inner)), h.clone())
316        }
317        Lang::ForLoop(var, iter, body, h) => Lang::ForLoop(
318            var.clone(),
319            Box::new(clean_syntax_errors(iter)),
320            Box::new(clean_syntax_errors(body)),
321            h.clone(),
322        ),
323        Lang::WhileLoop(cond, body, h) => Lang::WhileLoop(
324            Box::new(clean_syntax_errors(cond)),
325            Box::new(clean_syntax_errors(body)),
326            h.clone(),
327        ),
328        Lang::Use(lib, members, h) => Lang::Use(
329            Box::new(clean_syntax_errors(lib)),
330            Box::new(clean_syntax_errors(members)),
331            h.clone(),
332        ),
333        Lang::KeyValue(key, value, h) => {
334            Lang::KeyValue(key.clone(), Box::new(clean_syntax_errors(value)), h.clone())
335        }
336        Lang::JSBlock(inner, n, h) => {
337            Lang::JSBlock(Box::new(clean_syntax_errors(inner)), *n, h.clone())
338        }
339        // Nodes that don't need deep cleaning or are leaf nodes
340        other => other.clone(),
341    }
342}
343
344fn pattern_var(s: Span) -> IResult<Span, (Vec<Lang>, Option<String>)> {
345    let res = alt((tag_exp, variable2)).parse(s);
346    match res {
347        Ok((s, Lang::Tag(name, val, _h))) => {
348            if let Lang::Variable(name2, mutopa, typ, h) = *val {
349                Ok((
350                    s,
351                    (
352                        vec![Lang::Variable(name2.to_string(), mutopa, typ, h.clone())],
353                        Some(name.to_string()),
354                    ),
355                ))
356            } else {
357                Ok((s, (vec![], Some(name.to_string()))))
358            }
359        }
360        Ok((s, Lang::Variable(name, mutopa, typ, h))) => Ok((
361            s,
362            (vec![Lang::Variable(name, mutopa, typ, h.clone())], None),
363        )),
364        Err(r) => Err(r),
365        _ => todo!(),
366    }
367}
368
369fn single_parse(s: Span) -> IResult<Span, Lang> {
370    let res = (parse_elements, opt(terminated(tag(";"), multispace0))).parse(s);
371    match res {
372        Ok((s, (exp, Some(_)))) => Ok((s, exp)),
373        Ok((s, (exp, None))) => {
374            // Return a SyntaxError wrapped in the Lang to be collected later
375            Ok((
376                s,
377                Lang::SyntaxErr(
378                    Box::new(exp.clone()),
379                    SyntaxError::ForgottenSemicolon(exp.into()),
380                ),
381            ))
382        }
383        Err(r) => Err(r),
384    }
385}
386
387fn equality_operator(s: Span) -> IResult<Span, Span> {
388    terminated(alt((tag("="), tag("<-"))), multispace0).parse(s)
389}
390
391fn base_let_exp(s: Span) -> IResult<Span, Vec<Lang>> {
392    let res = (
393        terminated(tag("let"), multispace0),
394        pattern_var,
395        opt(preceded(terminated(tag(":"), multispace0), ltype)),
396        equality_operator,
397        single_parse,
398    )
399        .parse(s);
400    match res {
401        Ok((s, (_let, (pat_var, None), typ, _eq, Lang::Function(params, ty, body, h))))
402            if params.len() > 0 =>
403        {
404            let newvar = Var::from_language(pat_var[0].clone())
405                .unwrap()
406                .set_type(params[0].1.clone());
407            Ok((
408                s,
409                vec![Lang::Let(
410                    Box::new(newvar.to_language()),
411                    typ.unwrap_or(Type::Empty(HelpData::default())),
412                    Box::new(Lang::Function(params, ty, body, h)),
413                    _let.into(),
414                )],
415            ))
416        }
417        Ok((s, (_let, (pat_var, None), typ, _eq, body))) => Ok((
418            s,
419            vec![Lang::Let(
420                Box::new(pat_var[0].clone()),
421                typ.clone().unwrap_or(Type::Empty(HelpData::default())),
422                Box::new(body),
423                _let.into(),
424            )],
425        )),
426        Ok((s, (_let, (pat_var, Some(_)), typ, eq, body))) => {
427            if pat_var.len() == 1 {
428                Ok((
429                    s,
430                    vec![Lang::Let(
431                        Box::new(pat_var[0].clone()),
432                        typ.clone().unwrap_or(Type::Empty(HelpData::default())),
433                        Box::new(Lang::Operator(
434                            Op::Dollar(HelpData::default()),
435                            Box::new(Lang::Number(0.0, eq.into())),
436                            Box::new(body),
437                            pat_var.into(),
438                        )),
439                        _let.into(),
440                    )],
441                ))
442            } else {
443                Ok((
444                    s,
445                    pat_var
446                        .iter()
447                        .map(|x| {
448                            Lang::Let(
449                                Box::new(x.clone()),
450                                typ.clone().unwrap_or(Type::Empty(HelpData::default())),
451                                Box::new(body.clone()),
452                                HelpData::default(),
453                            )
454                        })
455                        .collect::<Vec<_>>(),
456                ))
457            }
458        }
459        Err(r) => Err(r),
460    }
461}
462
463fn let_exp(s: Span) -> IResult<Span, Vec<Lang>> {
464    let res = (opt(terminated(tag("pub"), multispace0)), base_let_exp).parse(s);
465    match res {
466        Ok((s, (None, le))) => Ok((s, le)),
467        Ok((s, (Some(_pu), le))) => {
468            let new_le = le
469                .iter()
470                .map(|x| match x {
471                    Lang::Let(var, typ, body, h) => {
472                        let vari = Var::from_language(var.deref().clone())
473                            .unwrap()
474                            .to_language();
475                        Lang::Let(Box::new(vari), typ.clone(), body.clone(), h.clone())
476                    }
477                    lan => lan.clone(),
478                })
479                .collect();
480            Ok((s, new_le))
481        }
482        Err(r) => Err(r),
483    }
484}
485
486fn base_type_exp(s: Span) -> IResult<Span, Lang> {
487    let res = (
488        terminated(tag("type"), multispace0),
489        type_alias,
490        equality_operator,
491        ltype,
492        terminated(tag(";"), multispace0),
493    )
494        .parse(s);
495    match res {
496        Ok((s, (_ty, Type::Alias(name, params, _, h), _eq, ty, _))) => {
497            let h2 = if params.len() > 0 {
498                params[0].clone().into()
499            } else {
500                HelpData::default()
501            };
502            let vari = Var::from_name(&name)
503                .set_type(Type::Params(params.clone(), h2))
504                .to_language();
505            Ok((s, Lang::Alias(Box::new(vari), params, ty, h)))
506        }
507        Ok((s, (_ty, _, _eq, _ty2, _))) => Ok((s, Lang::Empty(_ty.into()))),
508        Err(r) => Err(r),
509    }
510}
511
512fn type_exp(s: Span) -> IResult<Span, Vec<Lang>> {
513    let res = (opt(terminated(tag("pub"), multispace0)), base_type_exp).parse(s);
514    match res {
515        Ok((s, (Some(_pu), ali))) => Ok((s, vec![ali])),
516        Ok((s, (None, Lang::Alias(var, params, typ, h)))) => {
517            let vari = Var::from_language(var.deref().clone())
518                .unwrap()
519                .to_language();
520            Ok((s, vec![Lang::Alias(Box::new(vari), params, typ, h)]))
521        }
522        Err(r) => Err(r),
523        _ => todo!(),
524    }
525}
526
527fn base_opaque_exp(s: Span) -> IResult<Span, Lang> {
528    let res = (
529        terminated(tag("opaque"), multispace0),
530        type_alias,
531        terminated(tag("="), multispace0),
532        ltype,
533        terminated(tag(";"), multispace0),
534    )
535        .parse(s);
536    match res {
537        Ok((s, (_ty, Type::Alias(name, params, _, h), _eq, ty, _))) => {
538            let vari = Var::from_name(&name)
539                .set_type(Type::Params(params.clone(), params.clone().into()))
540                .set_opacity(true)
541                .to_language();
542            Ok((s, Lang::Alias(Box::new(vari), params, ty, h)))
543        }
544        Ok((s, (_ty, _, _eq, _ty2, _))) => Ok((s, Lang::Empty(_ty.into()))),
545        Err(r) => Err(r),
546    }
547}
548
549fn opaque_exp(s: Span) -> IResult<Span, Vec<Lang>> {
550    let res = (opt(terminated(tag("pub"), multispace0)), base_opaque_exp).parse(s);
551    match res {
552        Ok((s, (Some(_pu), Lang::Alias(var, params, typ, h)))) => {
553            let vari = Var::from_language(var.deref().clone())
554                .unwrap()
555                .set_opacity(true)
556                .to_language();
557            Ok((s, vec![Lang::Alias(Box::new(vari), params, typ, h)]))
558        }
559        Ok((s, (None, Lang::Alias(var, params, typ, h)))) => {
560            let vari = Var::from_language(var.deref().clone())
561                .unwrap()
562                .set_opacity(true)
563                .to_language();
564            Ok((s, vec![Lang::Alias(Box::new(vari), params, typ, h)]))
565        }
566        Err(r) => Err(r),
567        _ => todo!(),
568    }
569}
570
571pub fn module(s: Span) -> IResult<Span, Vec<Lang>> {
572    let res = (
573        terminated(tag("module"), multispace0),
574        terminated(variable_exp, multispace0),
575        terminated(tag("{"), multispace0),
576        base_parse,
577        terminated(tag("}"), multispace0),
578        terminated(tag(";"), multispace0),
579    )
580        .parse(s);
581    match res {
582        Ok((s, (modu, (name, _), _op, v, _cl, _dv))) => Ok((
583            s,
584            vec![Lang::Module(
585                name,
586                v,
587                ModulePosition::Internal,
588                Config::default(),
589                modu.into(),
590            )],
591        )),
592        Err(r) => Err(r),
593    }
594}
595
596fn assign(s: Span) -> IResult<Span, Vec<Lang>> {
597    let res = (
598        variable,
599        alt((
600            terminated(tag("="), multispace0),
601            terminated(tag("<-"), multispace0),
602        )),
603        parse_elements,
604        terminated(tag(";"), multispace0),
605    )
606        .parse(s);
607    match res {
608        Ok((s, ((var, _), _eq, exp, _pv))) => Ok((
609            s,
610            vec![Lang::Assign(
611                Box::new(var.clone()),
612                Box::new(exp),
613                var.into(),
614            )],
615        )),
616        Err(r) => Err(r),
617    }
618}
619
620fn comment(s: Span) -> IResult<Span, Vec<Lang>> {
621    let res = (tag("#"), not_line_ending, opt(line_ending), multispace0).parse(s);
622    match res {
623        Ok((s, (_hashtag, txt, _, _))) => {
624            Ok((s, vec![Lang::Comment(txt.to_string(), _hashtag.into())]))
625        }
626        Err(r) => Err(r),
627    }
628}
629
630pub fn simple_exp(s: Span) -> IResult<Span, Vec<Lang>> {
631    let res = (parse_elements, terminated(tag(";"), multispace0)).parse(s);
632    match res {
633        Ok((s, (lang, _sc))) => Ok((s, vec![lang])),
634        Err(r) => Err(r),
635    }
636}
637
638fn mod_imp(s: Span) -> IResult<Span, Vec<Lang>> {
639    let res = (
640        terminated(tag("mod"), multispace0),
641        terminated(variable_exp, multispace0),
642        terminated(tag(";"), multispace0),
643    )
644        .parse(s);
645    match res {
646        Ok((s, (_mod, (name, _), _sc))) => {
647            Ok((s, vec![Lang::ModuleImport(name.to_string(), _mod.into())]))
648        }
649        Err(r) => Err(r),
650    }
651}
652
653fn import_var(s: Span) -> IResult<Span, Vec<Lang>> {
654    let res = (
655        terminated(tag("use"), multispace0),
656        variable,
657        terminated(tag(";"), multispace0),
658    )
659        .parse(s);
660    match res {
661        Ok((s, (_use, (lang, case), _sc))) => {
662            let res = match case {
663                Case::Maj => Var::from_language(lang).unwrap().to_alias_lang(),
664                _ => Var::from_language(lang).unwrap().to_let(),
665            };
666            Ok((s, vec![res]))
667        }
668        Err(r) => Err(r),
669    }
670}
671
672fn import_type(s: Span) -> IResult<Span, Vec<Lang>> {
673    let res = (
674        terminated(tag("use"), multispace0),
675        type_alias,
676        terminated(tag(";"), multispace0),
677    )
678        .parse(s);
679
680    match res {
681        Ok((s, (_use, alias, _sc))) => Ok((s, vec![Lang::Import(alias, _use.into())])),
682        Err(r) => Err(r),
683    }
684}
685
686fn tests(s: Span) -> IResult<Span, Vec<Lang>> {
687    let res = (tag("Test"), delimited(tag("["), base_parse, tag("]"))).parse(s);
688    match res {
689        Ok((s, (_t, body))) => Ok((s, vec![Lang::Test(body, _t.into())])),
690        Err(r) => Err(r),
691    }
692}
693
694fn library(s: Span) -> IResult<Span, Vec<Lang>> {
695    let res = (
696        tag("library("),
697        variable_exp,
698        tag(")"),
699        opt(tag(";")),
700        multispace0,
701    )
702        .parse(s);
703
704    match res {
705        Ok((s, (_lib, (var, h), _cl, Some(_col), _))) => {
706            Ok((s, vec![Lang::Library(var, h.clone())]))
707        }
708        Ok((_, (_lib, _var, _cl, None, _))) => {
709            panic!("You forgot to put a ';' at the end of the line")
710        }
711        Err(r) => Err(r),
712    }
713}
714
715fn use_exp(s: Span) -> IResult<Span, Vec<Lang>> {
716    let res = (
717        tag("use("),
718        chars,
719        tag(", "),
720        alt((vector, chars)),
721        terminated(tag(");"), multispace0),
722    )
723        .parse(s);
724    match res {
725        Ok((s, (us, lib, _, members, _))) => Ok((
726            s,
727            vec![Lang::Use(Box::new(lib), Box::new(members), us.into())],
728        )),
729        Err(r) => Err(r),
730    }
731}
732
733fn custom_operators(s: Span) -> IResult<Span, (String, HelpData)> {
734    let res = custom_op.parse(s);
735    match res {
736        Ok((s, co)) => Ok((s, (co.clone().to_string(), co.into()))),
737        Err(r) => Err(r),
738    }
739}
740
741fn signature_variable(s: Span) -> IResult<Span, Vec<Lang>> {
742    let res = (
743        tag("@"),
744        alt((variable_recognizer, custom_operators)),
745        terminated(tag(":"), multispace0),
746        ltype,
747        terminated(tag(";"), multispace0),
748    )
749        .parse(s);
750    match res {
751        Ok((s, (at, (name, h), _col, typ, _))) => {
752            let var2 = Var::from_name(&name).set_help_data(h).set_type(typ.clone());
753            Ok((s, vec![Lang::Signature(var2, typ, at.into())]))
754        }
755        Err(r) => Err(r),
756    }
757}
758
759fn signature_opaque(s: Span) -> IResult<Span, Vec<Lang>> {
760    let res = (
761        tag("@"),
762        type_alias,
763        terminated(tag(":"), multispace0),
764        ltype,
765        terminated(tag(";"), multispace0),
766    )
767        .parse(s);
768    match res {
769        Ok((s, (at, Type::Alias(name, _params, _, h), _, typ, _))) => {
770            let var2 = Var::from_name(&name)
771                .set_help_data(h.clone())
772                .set_type(typ.clone());
773            Ok((s, vec![Lang::Signature(var2, typ, at.into())]))
774        }
775        Ok((_s, (_, _, _, _, _))) => todo!(),
776        Err(r) => Err(r),
777    }
778}
779
780pub fn signature(s: Span) -> IResult<Span, Vec<Lang>> {
781    alt((signature_opaque, signature_variable)).parse(s)
782}
783
784fn for_loop(s: Span) -> IResult<Span, Vec<Lang>> {
785    let res = (
786        terminated(tag("for"), multispace0),
787        terminated(tag("("), multispace0),
788        terminated(variable_exp, multispace0),
789        terminated(tag("in"), multispace0),
790        terminated(single_element, multispace0),
791        terminated(tag(")"), multispace0),
792        scope,
793        terminated(tag(";"), multispace0),
794    )
795        .parse(s);
796    match res {
797        Ok((s, (_for, _op, (var_str, _h), _in, iterator, _cl, scop, _semi))) => Ok((
798            s,
799            vec![Lang::ForLoop(
800                Var::from_name(&var_str),
801                Box::new(iterator),
802                Box::new(scop),
803                _for.into(),
804            )],
805        )),
806        Err(r) => Err(r),
807    }
808}
809
810fn while_loop(s: Span) -> IResult<Span, Vec<Lang>> {
811    let res = (
812        terminated(tag("while"), multispace0),
813        terminated(tag("("), multispace0),
814        terminated(single_element, multispace0),
815        terminated(tag(")"), multispace0),
816        scope,
817        terminated(tag(";"), multispace0),
818    )
819        .parse(s);
820    match res {
821        Ok((s, (_while, _op, condition, _cl, scop, _semi))) => Ok((
822            s,
823            vec![Lang::WhileLoop(
824                Box::new(condition),
825                Box::new(scop),
826                _while.into(),
827            )],
828        )),
829        Err(r) => Err(r),
830    }
831}
832
833fn test_block(s: Span) -> IResult<Span, Vec<Lang>> {
834    let res = (terminated(tag("Test"), multispace0), scope).parse(s);
835    //parse_block).parse(s);
836
837    match res {
838        Ok((s, (tst, body))) => Ok((s, vec![Lang::TestBlock(Box::new(body), tst.into())])),
839        Err(r) => Err(r),
840    }
841}
842
843// main
844pub fn base_parse(s: Span) -> IResult<Span, Vec<Lang>> {
845    let res = (
846        opt(multispace0),
847        many0(alt((
848            library,
849            break_exp,
850            use_exp,
851            test_block,
852            while_loop,
853            for_loop,
854            signature,
855            tests,
856            import_type,
857            import_var,
858            mod_imp,
859            comment,
860            type_exp,
861            opaque_exp,
862            let_exp,
863            module,
864            assign,
865            simple_exp,
866        ))),
867        opt(alt((return_exp, parse_elements))),
868    )
869        .parse(s);
870    match res {
871        Ok((s, (_, v, Some(exp)))) => {
872            let mut new_v = v.iter().flatten().cloned().collect::<Vec<_>>();
873            new_v.push(exp);
874            Ok((s, new_v))
875        }
876        Ok((s, (_, v, None))) => Ok((s, v.iter().flatten().cloned().collect())),
877        Err(r) => Err(r),
878    }
879}
880
881/// Parse source code and return a ParseResult containing the AST and any syntax errors
882///
883/// This function collects syntax errors instead of panicking, allowing the caller
884/// to handle errors appropriately (e.g., display all errors, continue with partial AST)
885pub fn parse(s: Span) -> ParseResult {
886    let res = base_parse(s.clone());
887    match res {
888        Ok((_, v)) => ParseResult::new(Lang::Lines(v.clone(), v.into())),
889        Err(_) => panic!("Can't parse string {}", s),
890    }
891}
892
893/// Parse source code and return just the Lang AST (legacy behavior)
894///
895/// This function is kept for backwards compatibility. It returns the AST directly
896/// and will panic if parsing fails completely.
897pub fn parse_legacy(s: Span) -> Lang {
898    parse(s).ast
899}
900
901pub fn parse2(s: Span) -> Result<Lang, String> {
902    let res = base_parse(s.clone());
903    match res {
904        Ok((_, v)) => Ok(v[0].clone()),
905        Err(_) => Err(format!("Can't parse string {}", s)),
906    }
907}
908
909/// Parse source code from a string with a filename for error reporting
910///
911/// This is the main entry point for parsing source code in the public API.
912/// It registers the source for error display and returns the AST.
913pub fn parse_from_string(source: &str, filename: &str) -> Lang {
914    use crate::components::error_message::help_data::register_source;
915
916    // Register source for error display
917    register_source(filename, source);
918
919    // Create a span with the filename as extra data
920    let span: Span = LocatedSpan::new_extra(source, filename.to_string());
921
922    // Parse and return the AST
923    parse(span).ast
924}
925
926/// Parse source code from a string with a filename, returning full ParseResult
927pub fn parse_from_string_with_errors(source: &str, filename: &str) -> ParseResult {
928    use crate::components::error_message::help_data::register_source;
929
930    // Register source for error display
931    register_source(filename, source);
932
933    // Create a span with the filename as extra data
934    let span: Span = LocatedSpan::new_extra(source, filename.to_string());
935
936    // Parse and return full result
937    parse(span)
938}
939
940// main test
941#[cfg(test)]
942mod tesus {
943    use super::*;
944
945    #[test]
946    fn test_semicolon1() {
947        let res = parse("let a <- 5".into());
948        // This should now collect a ForgottenSemicolon error
949        assert!(
950            res.has_errors(),
951            "Missing semicolon should produce a syntax error"
952        );
953        assert_eq!(res.errors.len(), 1, "Should have exactly one error");
954        match &res.errors[0] {
955            SyntaxError::ForgottenSemicolon(_) => (),
956            _ => panic!("Expected ForgottenSemicolon error"),
957        }
958    }
959
960    #[test]
961    fn test_assign1() {
962        let res = assign("a <- 12;".into()).unwrap().1;
963        assert_eq!(
964            "Assign",
965            res[0].simple_print(),
966            "The expression 'a <- 12;' should be identified as an assignation"
967        );
968    }
969}