Skip to main content

typr_core/components/language/
mod.rs

1pub mod argument_value;
2pub mod function_lang;
3pub mod var_function;
4pub mod module_lang;
5pub mod array_lang;
6pub mod operators;
7pub mod var;
8pub mod use_lang;
9
10use crate::components::language::argument_value::ArgumentValue;
11use crate::components::language::use_lang::UseSelector;
12use crate::processes::transpiling::translatable::RTranslatable;
13use crate::processes::type_checking::type_context::TypeContext;
14use crate::processes::parsing::operation_priority::TokenKind;
15use crate::components::error_message::locatable::Locatable;
16use crate::components::r#type::argument_type::ArgumentType;
17use crate::components::r#type::function_type::FunctionType;
18use crate::components::error_message::help_data::HelpData;
19use crate::processes::parsing::lang_token::LangToken;
20use crate::components::r#type::vector_type::VecType;
21use crate::components::context::config::Environment;
22use crate::processes::parsing::elements::elements;
23use crate::components::context::config::Config;
24use crate::components::language::operators::Op;
25use crate::processes::type_checking::typing;
26use crate::components::language::var::Var;
27use crate::components::context::Context;
28use crate::components::r#type::Type;
29use serde::{Deserialize, Serialize};
30use crate::utils::builder;
31use std::str::FromStr;
32
33#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
34pub enum ModulePosition {
35    Internal,
36    External,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub enum Lang {
41    Number {
42        value: f32,
43        help_data: HelpData,
44    },
45    Integer {
46        value: i32,
47        help_data: HelpData,
48    },
49    Bool {
50        value: bool,
51        help_data: HelpData,
52    },
53    Char {
54        value: String,
55        help_data: HelpData,
56    },
57    Scope {
58        body: Vec<Lang>,
59        help_data: HelpData,
60    },
61    Function {
62        parameters: Vec<ArgumentType>,
63        return_type: Type,
64        body: Box<Lang>,
65        help_data: HelpData,
66    },
67    Lambda {
68        parameters: Vec<Lang>,
69        body: Box<Lang>,
70        help_data: HelpData,
71    },
72    Module {
73        name: String,
74        body: Vec<Lang>,
75        module_position: ModulePosition,
76        config: Config,
77        help_data: HelpData,
78    },
79    Variable {
80        name: String,
81        is_opaque: bool,
82        related_type: Type,
83        help_data: HelpData,
84    },
85    FunctionApp {
86        identifier: Box<Lang>,
87        arguments: Vec<Lang>,
88        help_data: HelpData,
89    },
90    VecFunctionApp {
91        vector_type: VecType,
92        identifier: Box<Lang>,
93        arguments: Vec<Lang>,
94        help_data: HelpData,
95    },
96    ArrayIndexing {
97        identifier: Box<Lang>,
98        indexing: Box<Lang>,
99        help_data: HelpData,
100    },
101    Let {
102        variable: Box<Lang>,
103        r#type: Type,
104        expression: Box<Lang>,
105        is_public: bool,
106        help_data: HelpData,
107    },
108    Alias {
109        identifier: Box<Lang>,
110        parameters: Vec<Type>,
111        target_type: Type,
112        is_public: bool,
113        help_data: HelpData,
114    },
115    Array {
116        value: Vec<Lang>,
117        help_data: HelpData,
118    },
119    List {
120        value: Vec<ArgumentValue>,
121        help_data: HelpData,
122    },
123    DataFrame {
124        value: Vec<ArgumentValue>,
125        help_data: HelpData,
126    },
127    Tuple {
128        value: Vec<Lang>,
129        help_data: HelpData,
130    },
131    Lines {
132        value: Vec<Lang>,
133        help_data: HelpData,
134    },
135    Comment {
136        value: String,
137        help_data: HelpData,
138    },
139    ModuleImport {
140        value: String,
141        help_data: HelpData,
142    },
143    Import {
144        value: Type,
145        help_data: HelpData,
146    },
147    Test {
148        value: Vec<Lang>,
149        help_data: HelpData,
150    },
151    Return {
152        value: Box<Lang>,
153        help_data: HelpData,
154    },
155    VecBlock {
156        value: String,
157        help_data: HelpData,
158    },
159    Library {
160        value: String,
161        help_data: HelpData,
162    },
163    Exp {
164        value: String,
165        help_data: HelpData,
166    },
167    Vector {
168        value: Vec<Lang>,
169        help_data: HelpData,
170    },
171    Not {
172        value: Box<Lang>,
173        help_data: HelpData,
174    },
175    TestBlock {
176        value: Box<Lang>,
177        help_data: HelpData,
178    },
179    Use {
180        lang: Box<Lang>,
181        members: Box<Lang>,
182        help_data: HelpData,
183    },
184    WhileLoop {
185        condition: Box<Lang>,
186        body: Box<Lang>,
187        help_data: HelpData,
188    },
189    Sequence {
190        body: Vec<Lang>,
191        help_data: HelpData,
192    },
193    Tag {
194        name: String,
195        value: Box<Lang>,
196        help_data: HelpData,
197    },
198    GenFunc {
199        name: String,
200        help_data: HelpData,
201    },
202    If {
203        condition: Box<Lang>,
204        if_block: Box<Lang>,
205        else_block: Box<Lang>,
206        help_data: HelpData,
207    },
208    Match {
209        target: Box<Lang>,
210        branches: Vec<(Lang, Box<Lang>)>,
211        help_data: HelpData,
212    },
213    Assign {
214        identifier: Box<Lang>,
215        expression: Box<Lang>,
216        help_data: HelpData,
217    },
218    Signature {
219        identifier: Var,
220        target_type: Type,
221        help_data: HelpData,
222    },
223    ForLoop {
224        identifier: Var,
225        expression: Box<Lang>,
226        body: Box<Lang>,
227        help_data: HelpData,
228    },
229    RFunction {
230        parameters: Vec<Lang>,
231        body: String,
232        help_data: HelpData,
233    },
234    KeyValue {
235        key: String,
236        value: Box<Lang>,
237        help_data: HelpData,
238    },
239    Operator {
240        operator: Op,
241        rhs: Box<Lang>,
242        lhs: Box<Lang>,
243        help_data: HelpData,
244    },
245    /// Pattern matching on primitive types: `x as int => ...`
246    /// TypePattern(variable_name, matched_type, help_data)
247    TypePattern {
248        variable_name: String,
249        matched_type: Type,
250        help_data: HelpData,
251    },
252    Union(Box<Lang>, Box<Lang>, HelpData),
253    JSBlock(Box<Lang>, u32, HelpData),
254    Break(HelpData),
255    Null(HelpData),
256    NA(HelpData),
257    Empty(HelpData),
258    Dots(HelpData),
259    /// Directive `use M::*;` or `use M::{a, b as c};`
260    UseModule {
261        module_path: Vec<String>,
262        selector: UseSelector,
263        help_data: HelpData,
264    },
265    /// Explicit constructor call: `TypeName:{ field1 = val1, field2 = val2 }`
266    ConstructorCall {
267        type_name: String,
268        fields: Vec<ArgumentValue>,
269        help_data: HelpData,
270    },
271    /// Array constructor call: `TypeName:[expr, expr, ...]`
272    ArrayConstructorCall {
273        type_name: String,
274        elements: Vec<Lang>,
275        help_data: HelpData,
276    },
277    /// Union constructor: `Union.Variant` or `Union.Variant:{ field = val, ... }`
278    UnionConstructor {
279        union_name: String,
280        variant_name: String,
281        fields: Vec<ArgumentValue>,
282        help_data: HelpData,
283    },
284}
285
286impl PartialEq for Lang {
287    fn eq(&self, other: &Self) -> bool {
288        match (self, other) {
289            (Lang::Number { value: a, .. }, Lang::Number { value: b, .. }) => a == b,
290            (Lang::Integer { value: a, .. }, Lang::Integer { value: b, .. }) => a == b,
291            (Lang::Bool { value: a, .. }, Lang::Bool { value: b, .. }) => a == b,
292            (Lang::Char { value: a, .. }, Lang::Char { value: b, .. }) => a == b,
293            (Lang::Union(a1, a2, _), Lang::Union(b1, b2, _)) => a1 == b1 && a2 == b2,
294            (Lang::Scope { body: a, .. }, Lang::Scope { body: b, .. }) => a == b,
295            (
296                Lang::Function {
297                    parameters: a1,
298                    return_type: a2,
299                    body: a3,
300                    ..
301                },
302                Lang::Function {
303                    parameters: b1,
304                    return_type: b2,
305                    body: b3,
306                    ..
307                },
308            ) => a1 == b1 && a2 == b2 && a3 == b3,
309            (
310                Lang::Module {
311                    name: a1,
312                    body: a2,
313                    module_position: a3,
314                    config: a4,
315                    ..
316                },
317                Lang::Module {
318                    name: b1,
319                    body: b2,
320                    module_position: b3,
321                    config: b4,
322                    ..
323                },
324            ) => a1 == b1 && a2 == b2 && a3 == b3 && a4 == b4,
325            (
326                Lang::Variable {
327                    name: a1,
328                    is_opaque: a2,
329                    related_type: a3,
330                    ..
331                },
332                Lang::Variable {
333                    name: b1,
334                    is_opaque: b2,
335                    related_type: b3,
336                    ..
337                },
338            ) => a1 == b1 && a2 == b2 && a3 == b3,
339            (
340                Lang::FunctionApp {
341                    identifier: a1,
342                    arguments: a2,
343                    ..
344                },
345                Lang::FunctionApp {
346                    identifier: b1,
347                    arguments: b2,
348                    ..
349                },
350            ) => a1 == b1 && a2 == b2,
351            (
352                Lang::VecFunctionApp {
353                    vector_type: a0,
354                    identifier: a1,
355                    arguments: a2,
356                    ..
357                },
358                Lang::VecFunctionApp {
359                    vector_type: b0,
360                    identifier: b1,
361                    arguments: b2,
362                    ..
363                },
364            ) => a0 == b0 && a1 == b1 && a2 == b2,
365            (
366                Lang::ArrayIndexing {
367                    identifier: a1,
368                    indexing: a2,
369                    ..
370                },
371                Lang::ArrayIndexing {
372                    identifier: b1,
373                    indexing: b2,
374                    ..
375                },
376            ) => a1 == b1 && a2 == b2,
377            (
378                Lang::Let {
379                    variable: a1,
380                    r#type: a2,
381                    expression: a3,
382                    is_public: _,
383                    help_data: _,
384                },
385                Lang::Let {
386                    variable: b1,
387                    r#type: b2,
388                    expression: b3,
389                    is_public: _,
390                    help_data: _,
391                },
392            ) => a1 == b1 && a2 == b2 && a3 == b3,
393            (
394                Lang::Alias {
395                    identifier: a1,
396                    parameters: a2,
397                    target_type: a3,
398                    ..
399                },
400                Lang::Alias {
401                    identifier: b1,
402                    parameters: b2,
403                    target_type: b3,
404                    ..
405                },
406            ) => a1 == b1 && a2 == b2 && a3 == b3,
407            (Lang::Array { value: a, .. }, Lang::Array { value: b, .. }) => a == b,
408            (
409                Lang::ArrayConstructorCall { type_name: a1, elements: a2, .. },
410                Lang::ArrayConstructorCall { type_name: b1, elements: b2, .. },
411            ) => a1 == b1 && a2 == b2,
412            (Lang::List { value: a, .. }, Lang::List { value: b, .. }) => a == b,
413            (Lang::DataFrame { value: a, .. }, Lang::DataFrame { value: b, .. }) => a == b,
414            (
415                Lang::Tag {
416                    name: a1,
417                    value: a2,
418                    ..
419                },
420                Lang::Tag {
421                    name: b1,
422                    value: b2,
423                    ..
424                },
425            ) => a1 == b1 && a2 == b2,
426            (
427                Lang::If {
428                    condition: a1,
429                    if_block: a2,
430                    else_block: a3,
431                    ..
432                },
433                Lang::If {
434                    condition: b1,
435                    if_block: b2,
436                    else_block: b3,
437                    ..
438                },
439            ) => a1 == b1 && a2 == b2 && a3 == b3,
440            (
441                Lang::Match {
442                    target: a1,
443                    branches: a2,
444                    ..
445                },
446                Lang::Match {
447                    target: b1,
448                    branches: b2,
449                    ..
450                },
451            ) => a1 == b1 && a2 == b2,
452            (Lang::Tuple { value: a, .. }, Lang::Tuple { value: b, .. }) => a == b,
453            (Lang::Lines { value: a, .. }, Lang::Lines { value: b, .. }) => a == b,
454            (
455                Lang::Assign {
456                    identifier: a1,
457                    expression: a2,
458                    ..
459                },
460                Lang::Assign {
461                    identifier: b1,
462                    expression: b2,
463                    ..
464                },
465            ) => a1 == b1 && a2 == b2,
466            (Lang::Comment { value: a, .. }, Lang::Comment { value: b, .. }) => a == b,
467            (Lang::ModuleImport { value: a, .. }, Lang::ModuleImport { value: b, .. }) => a == b,
468            (Lang::Import { value: a, .. }, Lang::Import { value: b, .. }) => a == b,
469            (
470                Lang::GenFunc {
471                    name: a1,
472                    help_data: a2,
473                },
474                Lang::GenFunc {
475                    name: b1,
476                    help_data: b2,
477                },
478            ) => a1 == b1 && a2 == b2,
479            (Lang::Test { value: a, .. }, Lang::Test { value: b, .. }) => a == b,
480            (Lang::Return { value: a, .. }, Lang::Return { value: b, .. }) => a == b,
481            (Lang::VecBlock { value: a, .. }, Lang::VecBlock { value: b, .. }) => a == b,
482            (Lang::Lambda { parameters: a, .. }, Lang::Lambda { parameters: b, .. }) => a == b,
483            (Lang::Library { value: a, .. }, Lang::Library { value: b, .. }) => a == b,
484            (Lang::Exp { value: a, .. }, Lang::Exp { value: b, .. }) => a == b,
485            (
486                Lang::Signature {
487                    identifier: a1,
488                    target_type: a2,
489                    ..
490                },
491                Lang::Signature {
492                    identifier: b1,
493                    target_type: b2,
494                    ..
495                },
496            ) => a1 == b1 && a2 == b2,
497            (
498                Lang::ForLoop {
499                    identifier: a1,
500                    expression: a2,
501                    body: a3,
502                    ..
503                },
504                Lang::ForLoop {
505                    identifier: b1,
506                    expression: b2,
507                    body: b3,
508                    ..
509                },
510            ) => a1 == b1 && a2 == b2 && a3 == b3,
511            (
512                Lang::RFunction {
513                    parameters: a1,
514                    body: a2,
515                    ..
516                },
517                Lang::RFunction {
518                    parameters: b1,
519                    body: b2,
520                    ..
521                },
522            ) => a1 == b1 && a2 == b2,
523            (
524                Lang::KeyValue {
525                    key: a1, value: a2, ..
526                },
527                Lang::KeyValue {
528                    key: b1, value: b2, ..
529                },
530            ) => a1 == b1 && a2 == b2,
531            (Lang::Vector { value: a, .. }, Lang::Vector { value: b, .. }) => a == b,
532            (Lang::Sequence { body: a, .. }, Lang::Sequence { body: b, .. }) => a == b,
533            (Lang::Not { value: a, .. }, Lang::Not { value: b, .. }) => a == b,
534            (Lang::TestBlock { value: a, .. }, Lang::TestBlock { value: b, .. }) => a == b,
535            (Lang::JSBlock(a1, a2, _), Lang::JSBlock(b1, b2, _)) => a1 == b1 && a2 == b2,
536            (
537                Lang::Use {
538                    lang: a1,
539                    members: a2,
540                    ..
541                },
542                Lang::Use {
543                    lang: b1,
544                    members: b2,
545                    ..
546                },
547            ) => a1 == b1 && a2 == b2,
548            (Lang::Empty(_), Lang::Empty(_)) => true,
549            (
550                Lang::WhileLoop {
551                    condition: a1,
552                    body: a2,
553                    ..
554                },
555                Lang::WhileLoop {
556                    condition: b1,
557                    body: b2,
558                    ..
559                },
560            ) => a1 == b1 && a2 == b2,
561            (Lang::Break(_), Lang::Break(_)) => true,
562            (
563                Lang::Operator {
564                    operator: a1,
565                    rhs: a2,
566                    lhs: a3,
567                    ..
568                },
569                Lang::Operator {
570                    operator: b1,
571                    rhs: b2,
572                    lhs: b3,
573                    ..
574                },
575            ) => a1 == b1 && a2 == b2 && a3 == b3,
576            (
577                Lang::TypePattern {
578                    variable_name: a1,
579                    matched_type: a2,
580                    ..
581                },
582                Lang::TypePattern {
583                    variable_name: b1,
584                    matched_type: b2,
585                    ..
586                },
587            ) => a1 == b1 && a2 == b2,
588            (Lang::Null(_), Lang::Null(_)) => true,
589            (Lang::NA(_), Lang::NA(_)) => true,
590            (
591                Lang::UseModule {
592                    module_path: a1,
593                    selector: a2,
594                    ..
595                },
596                Lang::UseModule {
597                    module_path: b1,
598                    selector: b2,
599                    ..
600                },
601            ) => a1 == b1 && a2 == b2,
602            (
603                Lang::UnionConstructor {
604                    union_name: a1,
605                    variant_name: a2,
606                    fields: a3,
607                    ..
608                },
609                Lang::UnionConstructor {
610                    union_name: b1,
611                    variant_name: b2,
612                    fields: b3,
613                    ..
614                },
615            ) => a1 == b1 && a2 == b2 && a3 == b3,
616            _ => false,
617        }
618    }
619}
620
621impl Eq for Lang {}
622
623impl Default for Lang {
624    fn default() -> Lang {
625        builder::empty_lang()
626    }
627}
628
629impl Locatable for Lang {
630    fn get_help_data(&self) -> HelpData {
631        Lang::get_help_data(self)
632    }
633}
634
635impl From<Var> for Lang {
636    fn from(val: Var) -> Self {
637        Lang::Variable {
638            name: val.name,
639            is_opaque: val.is_opaque,
640            related_type: val.related_type,
641            help_data: val.help_data,
642        }
643    }
644}
645
646impl From<LangToken> for Lang {
647    fn from(val: LangToken) -> Self {
648        match val {
649            LangToken::Expression(exp) => exp,
650            LangToken::Operator(op) => panic!("Shouldn't convert the token to lang {}", op),
651            LangToken::EmptyOperator => panic!("Shouldn't be empty "),
652        }
653    }
654}
655
656pub fn set_related_type_if_variable((val, arg): (&Lang, &Type)) -> Lang {
657    let oargs = FunctionType::try_from(arg.clone()).map(|fn_t| fn_t.get_param_types());
658
659    match oargs {
660        Ok(args) if !args.is_empty() => val.set_type_if_variable(&args[0]),
661        Ok(_) => val.clone(),
662        Err(_) => val.clone(),
663    }
664}
665
666//main
667impl Lang {
668    pub fn save_in_memory(&self) -> bool {
669        matches!(self, Lang::Let { .. } | Lang::Assign { .. })
670    }
671
672    pub fn to_module(self, name: &str, environment: Environment) -> Self {
673        match self {
674            Lang::Lines {
675                value: v,
676                help_data: h,
677            } => Lang::Module {
678                name: name.to_string(),
679                body: v,
680                module_position: ModulePosition::External,
681                config: Config::default().set_environment(environment),
682                help_data: h,
683            },
684            s => s,
685        }
686    }
687
688    fn set_type_if_variable(&self, typ: &Type) -> Lang {
689        match self {
690            Lang::Variable {
691                name,
692                is_opaque: spec,
693                related_type: existing_type,
694                help_data: h,
695            } => {
696                let new_type = if typ.is_generic() && !existing_type.is_empty() {
697                    existing_type.clone()
698                } else {
699                    typ.clone()
700                };
701                Lang::Variable {
702                    name: name.clone(),
703                    is_opaque: *spec,
704                    related_type: new_type,
705                    help_data: h.clone(),
706                }
707            }
708            _ => self.clone(),
709        }
710    }
711
712    pub fn to_arg_type(&self) -> Option<ArgumentType> {
713        match self {
714            Lang::Let {
715                variable: var,
716                r#type: ty,
717                expression: _,
718                is_public: _,
719                help_data: _,
720            } => Some(ArgumentType::new(
721                &Var::from_language((**var).clone()).unwrap().get_name(),
722                ty,
723            )),
724            Lang::Alias {
725                identifier: var,
726                parameters: _types,
727                target_type: ty,
728                ..
729            } => Some(ArgumentType::new(
730                &Var::from_language((**var).clone()).unwrap().get_name(),
731                ty,
732            )),
733            _ => None,
734        }
735    }
736
737    pub fn extract_types_from_expression(&self, context: &Context) -> Vec<Type> {
738        if self.is_value() {
739            vec![typing(context, self).value.clone()]
740        } else {
741            match self {
742                Lang::FunctionApp {
743                    identifier: exp,
744                    arguments: arg_typs,
745                    ..
746                } => {
747                    let typs = exp.extract_types_from_expression(context);
748                    let typs2 = arg_typs
749                        .iter()
750                        .flat_map(|x| x.extract_types_from_expression(context))
751                        .collect::<Vec<_>>();
752                    typs.iter().chain(typs2.iter()).cloned().collect()
753                }
754                _ => vec![],
755            }
756        }
757    }
758
759    pub fn is_value(&self) -> bool {
760        matches!(
761            self,
762            Lang::Number { .. }
763                | Lang::Integer { .. }
764                | Lang::Bool { .. }
765                | Lang::Char { .. }
766                | Lang::Null(_)
767                | Lang::Array { .. }
768        )
769    }
770
771    pub fn is_undefined(&self) -> bool {
772        if let Lang::Function { body, .. } = self {
773            if let Lang::Scope { body: v, .. } = *body.clone() {
774                let ele = v.first().unwrap();
775                matches!(ele, Lang::Empty(_))
776            } else {
777                false
778            }
779        } else {
780            false
781        }
782    }
783
784    pub fn is_function(&self) -> bool {
785        matches!(self, Lang::Function { .. } | Lang::RFunction { .. })
786    }
787
788    pub fn infer_var_name(&self, args: &[Lang], context: &Context) -> Var {
789        if let Some(first) = args.first() {
790            let first = typing(context, first).value;
791            Var::from_language(self.clone())
792                .unwrap()
793                .set_type(first.clone())
794        } else {
795            Var::from_language(self.clone()).unwrap()
796        }
797    }
798
799    pub fn get_related_function(self, args: &[Lang], context: &Context) -> Option<FunctionType> {
800        let var_name = self.infer_var_name(args, context);
801        let fn_ty = typing(context, &var_name.to_language()).value;
802        fn_ty.clone().to_function_type()
803    }
804
805    pub fn lang_substitution(&self, sub_var: &Lang, var: &Lang, context: &Context) -> String {
806        if let Lang::Variable { name, .. } = var {
807            let res = match self {
808                Lang::Variable { help_data: h, .. } if self == sub_var => Lang::Exp {
809                    value: format!("{}[[2]]", name),
810                    help_data: h.clone(),
811                },
812                lang => lang.clone(),
813            };
814            res.to_r(context).0
815        } else {
816            panic!("var is not a variable")
817        }
818    }
819
820    pub fn get_help_data(&self) -> HelpData {
821        match self {
822            Lang::Number { help_data: h, .. } => h,
823            Lang::Integer { help_data: h, .. } => h,
824            Lang::Char { help_data: h, .. } => h,
825            Lang::Bool { help_data: h, .. } => h,
826            Lang::Union(_, _, h) => h,
827            Lang::Scope { help_data: h, .. } => h,
828            Lang::Function { help_data: h, .. } => h,
829            Lang::Module { help_data: h, .. } => h,
830            Lang::Variable { help_data: h, .. } => h,
831            Lang::FunctionApp { help_data: h, .. } => h,
832            Lang::VecFunctionApp { help_data: h, .. } => h,
833            Lang::ArrayIndexing { help_data: h, .. } => h,
834            Lang::Let { help_data: h, .. } => h,
835            Lang::Array { help_data: h, .. } => h,
836            Lang::List { help_data: h, .. } => h,
837            Lang::DataFrame { help_data: h, .. } => h,
838            Lang::Alias { help_data: h, .. } => h,
839            Lang::Tag { help_data: h, .. } => h,
840            Lang::If { help_data: h, .. } => h,
841            Lang::Match { help_data: h, .. } => h,
842            Lang::Tuple { help_data: h, .. } => h,
843            Lang::Lines { help_data: h, .. } => h,
844            Lang::Assign { help_data: h, .. } => h,
845            Lang::Comment { help_data: h, .. } => h,
846            Lang::ModuleImport { help_data: h, .. } => h,
847            Lang::Import { help_data: h, .. } => h,
848            Lang::GenFunc { help_data: h, .. } => h,
849            Lang::Test { help_data: h, .. } => h,
850            Lang::Return { help_data: h, .. } => h,
851            Lang::VecBlock { help_data: h, .. } => h,
852            Lang::Lambda { help_data: h, .. } => h,
853            Lang::Library { help_data: h, .. } => h,
854            Lang::Exp { help_data: h, .. } => h,
855            Lang::Empty(h) => h,
856            Lang::Signature { help_data: h, .. } => h,
857            Lang::ForLoop { help_data: h, .. } => h,
858            Lang::RFunction { help_data: h, .. } => h,
859            Lang::KeyValue { help_data: h, .. } => h,
860            Lang::Vector { help_data: h, .. } => h,
861            Lang::Not { help_data: h, .. } => h,
862            Lang::Sequence { help_data: h, .. } => h,
863            Lang::TestBlock { help_data: h, .. } => h,
864            Lang::JSBlock(_, _, h) => h,
865            Lang::Use { help_data: h, .. } => h,
866            Lang::WhileLoop { help_data: h, .. } => h,
867            Lang::Break(h) => h,
868            Lang::Operator { help_data: h, .. } => h,
869            Lang::TypePattern { help_data: h, .. } => h,
870            Lang::Null(h) => h,
871            Lang::NA(h) => h,
872            Lang::Dots(h) => h,
873            Lang::UseModule { help_data: h, .. } => h,
874            Lang::ConstructorCall { help_data: h, .. } => h,
875            Lang::UnionConstructor { help_data: h, .. } => h,
876            Lang::ArrayConstructorCall { help_data: h, .. } => h,
877        }
878        .clone()
879    }
880
881    pub fn linearize_array(&self) -> Vec<Lang> {
882        match self {
883            Lang::Array { value: v, .. } => v.iter().fold(Vec::<Lang>::new(), |acc, x: &Lang| {
884                acc.iter()
885                    .chain(x.linearize_array().iter())
886                    .cloned()
887                    .collect()
888            }),
889            _ => vec![self.to_owned()],
890        }
891    }
892
893    pub fn is_r_function(&self) -> bool {
894        matches!(self, Lang::RFunction { .. })
895    }
896
897    pub fn nb_params(&self) -> usize {
898        self.simple_print();
899        match self {
900            Lang::Function {
901                parameters: params, ..
902            } => params.len(),
903            _ => 0_usize,
904        }
905    }
906
907    pub fn simple_print(&self) -> String {
908        match self {
909            Lang::Number { .. } => "Number".to_string(),
910            Lang::Integer { .. } => "Integer".to_string(),
911            Lang::Char { .. } => "Char".to_string(),
912            Lang::Bool { .. } => "Bool".to_string(),
913            Lang::Union(_, _, _) => "Union".to_string(),
914            Lang::Scope { .. } => "Scope".to_string(),
915            Lang::Function { .. } => "Function".to_string(),
916            Lang::Module { .. } => "Module".to_string(),
917            Lang::Variable { name, .. } => format!("Variable({})", name),
918            Lang::FunctionApp {
919                identifier: var, ..
920            } => format!(
921                "FunctionApp({})",
922                Var::from_language(*(var.clone())).unwrap().get_name()
923            ),
924            Lang::VecFunctionApp {
925                vector_type: vec_typ,
926                identifier: var,
927                ..
928            } => format!(
929                "VecFunctionApp({}, {})",
930                vec_typ,
931                Var::from_language(*(var.clone())).unwrap().get_name()
932            ),
933            Lang::ArrayIndexing { .. } => "ArrayIndexing".to_string(),
934            Lang::Let { variable: var, .. } => format!(
935                "let {}",
936                Var::from_language((**var).clone()).unwrap().get_name()
937            ),
938            Lang::Array { .. } => "Array".to_string(),
939            Lang::List { .. } => "Record".to_string(),
940            Lang::DataFrame { .. } => "DataFrame".to_string(),
941            Lang::Alias { .. } => "Alias".to_string(),
942            Lang::Tag { .. } => "Tag".to_string(),
943            Lang::If { .. } => "If".to_string(),
944            Lang::Match { .. } => "Match".to_string(),
945            Lang::Tuple { .. } => "Tuple".to_string(),
946            Lang::Lines { .. } => "Sequence".to_string(),
947            Lang::Assign { .. } => "Assign".to_string(),
948            Lang::Comment { .. } => "Comment".to_string(),
949            Lang::ModuleImport { .. } => "ModImp".to_string(),
950            Lang::Import { .. } => "Import".to_string(),
951            Lang::GenFunc { .. } => "GenFunc".to_string(),
952            Lang::Test { .. } => "Test".to_string(),
953            Lang::Return { .. } => "Return".to_string(),
954            Lang::VecBlock { .. } => "VecBloc".to_string(),
955            Lang::Lambda { .. } => "Lambda".to_string(),
956            Lang::Library { .. } => "Library".to_string(),
957            Lang::Exp { .. } => "Exp".to_string(),
958            Lang::Empty(_) => "Empty".to_string(),
959            Lang::Signature { .. } => "Signature".to_string(),
960            Lang::ForLoop { .. } => "ForLoop".to_string(),
961            Lang::RFunction { .. } => "RFunction".to_string(),
962            Lang::KeyValue { .. } => "KeyValue".to_string(),
963            Lang::Vector { .. } => "Vector".to_string(),
964            Lang::Not { .. } => "Not".to_string(),
965            Lang::Sequence { .. } => "Sequence".to_string(),
966            Lang::TestBlock { .. } => "TestBlock".to_string(),
967            Lang::JSBlock(_, _, _) => "JSBlock".to_string(),
968            Lang::Use { .. } => "Use".to_string(),
969            Lang::WhileLoop { .. } => "WhileLoop".to_string(),
970            Lang::Break(_) => "Break".to_string(),
971            Lang::Operator { .. } => "Operator".to_string(),
972            Lang::TypePattern {
973                variable_name: name,
974                matched_type: typ,
975                ..
976            } => {
977                format!("TypePattern({} as {})", name, typ.pretty2())
978            }
979            Lang::Null(_) => "Null".to_string(),
980            Lang::NA(_) => "NA".to_string(),
981            Lang::Dots(_) => "Dots".to_string(),
982            Lang::UseModule { module_path, .. } => format!("UseModule({})", module_path.join("::")),
983            Lang::ConstructorCall { type_name, .. } => format!("ConstructorCall({})", type_name),
984            Lang::UnionConstructor { union_name, variant_name, .. } => {
985                format!("UnionConstructor({}.{})", union_name, variant_name)
986            }
987            Lang::ArrayConstructorCall { type_name, .. } => format!("ArrayConstructorCall({})", type_name),
988        }
989    }
990
991    pub fn typing(&self, context: &Context) -> TypeContext {
992        typing(context, self)
993    }
994
995    pub fn to_js(&self, context: &Context) -> (String, Context) {
996        match self {
997            Lang::Char { value: val, .. } => (format!("\\'{}\\'", val), context.clone()),
998            Lang::Null(_) => ("null".to_string(), context.clone()),
999            Lang::NA(_) => ("NA".to_string(), context.clone()),
1000            Lang::Bool { value: b, .. } => (b.to_string().to_uppercase(), context.clone()),
1001            Lang::Number { value: n, .. } => (format!("{}", n), context.clone()),
1002            Lang::Integer { value: i, .. } => (format!("{}", i), context.clone()),
1003            Lang::Let {
1004                variable: var,
1005                r#type: _,
1006                expression: body,
1007                is_public: _,
1008                help_data: _,
1009            } => (
1010                format!(
1011                    "let {} = {};",
1012                    Var::from_language(*(var.clone())).unwrap().get_name(),
1013                    body.to_js(context).0
1014                ),
1015                context.clone(),
1016            ),
1017            Lang::Assign {
1018                identifier: var,
1019                expression: body,
1020                ..
1021            } => (
1022                format!("{} = {};", var.to_js(context).0, body.to_js(context).0),
1023                context.clone(),
1024            ),
1025            Lang::Scope { body: langs, .. } => {
1026                let res = langs
1027                    .iter()
1028                    .map(|x| x.to_js(context).0)
1029                    .collect::<Vec<_>>()
1030                    .join("\n");
1031                (res, context.clone())
1032            }
1033            Lang::Return { value: exp, .. } => {
1034                (format!("return {};", exp.to_js(context).0), context.clone())
1035            }
1036            Lang::FunctionApp {
1037                identifier: exp,
1038                arguments: params,
1039                ..
1040            } => {
1041                let var = Var::try_from(exp.clone()).unwrap();
1042                let res = format!(
1043                    "{}({})",
1044                    var.get_name().replace("__", "."),
1045                    params
1046                        .iter()
1047                        .map(|x| x.to_js(context).0)
1048                        .collect::<Vec<_>>()
1049                        .join(", ")
1050                );
1051                (res, context.clone())
1052            }
1053            Lang::Function {
1054                parameters: params,
1055                body,
1056                ..
1057            } => {
1058                let parameters = &params
1059                    .iter()
1060                    .map(|x| x.get_argument_str())
1061                    .collect::<Vec<_>>()
1062                    .join(", ");
1063                (
1064                    format!("({}) => {{\n{}\n}}", parameters, body.to_js(context).0),
1065                    context.clone(),
1066                )
1067            }
1068            Lang::Use {
1069                lang: lib, members, ..
1070            } => {
1071                let body = match (**members).clone() {
1072                    Lang::Vector { value: v, .. } => v
1073                        .iter()
1074                        .map(|val: &Lang| val.to_js(context).0.replace("\\'", ""))
1075                        .collect::<Vec<_>>()
1076                        .join(", "),
1077                    Lang::Char { value: val, .. } => val.clone(),
1078                    lang => lang.simple_print(),
1079                };
1080                (
1081                    format!("import {{ {} }} from {};", body, lib.to_js(context).0),
1082                    context.clone(),
1083                )
1084            }
1085            Lang::Sequence { body: v, .. } => {
1086                let res = "[".to_string()
1087                    + &v.iter()
1088                        .map(|lang: &Lang| lang.to_js(context).0)
1089                        .collect::<Vec<_>>()
1090                        .join(", ")
1091                    + "]";
1092                (res, context.clone())
1093            }
1094            Lang::Array { value: v, .. } => {
1095                let res = "[".to_string()
1096                    + &v.iter()
1097                        .map(|lang: &Lang| lang.to_js(context).0)
1098                        .collect::<Vec<_>>()
1099                        .join(", ")
1100                    + "]";
1101                (res, context.clone())
1102            }
1103            Lang::Vector { value: v, .. } => {
1104                let res = "[".to_string()
1105                    + &v.iter()
1106                        .map(|lang: &Lang| lang.to_js(context).0)
1107                        .collect::<Vec<_>>()
1108                        .join(", ")
1109                    + "]";
1110                (res, context.clone())
1111            }
1112            Lang::List {
1113                value: arg_vals, ..
1114            } => {
1115                let res = "{".to_string()
1116                    + &arg_vals
1117                        .iter()
1118                        .map(|arg_val: &ArgumentValue| {
1119                            arg_val.get_argument().replace("'", "")
1120                                + ": "
1121                                + &arg_val.get_value().to_js(context).0
1122                        })
1123                        .collect::<Vec<_>>()
1124                        .join(", ")
1125                    + "}";
1126                (res, context.clone())
1127            }
1128            Lang::Lambda {
1129                parameters: params,
1130                body,
1131                ..
1132            } => {
1133                let param_names: Vec<String> = params
1134                    .iter()
1135                    .map(|p: &Lang| match p {
1136                        Lang::Variable { name, .. } => name.clone(),
1137                        _ => "x".to_string(),
1138                    })
1139                    .collect();
1140                let params_str = if param_names.len() == 1 {
1141                    param_names[0].clone()
1142                } else {
1143                    format!("({})", param_names.join(", "))
1144                };
1145                (
1146                    format!("{} => {}", params_str, body.to_js(context).0),
1147                    context.clone(),
1148                )
1149            }
1150            Lang::Operator {
1151                operator: op,
1152                rhs: e1,
1153                lhs: e2,
1154                ..
1155            } => (
1156                format!("{} {} {}", e1.to_js(context).0, op, e2.to_js(context).0),
1157                context.clone(),
1158            ),
1159            _ => self.to_r(context),
1160        }
1161    }
1162
1163    pub fn to_simple_r(&self, context: &Context) -> (String, Context) {
1164        match self {
1165            Lang::Number { value: n, .. } => (n.to_string(), context.clone()),
1166            Lang::Array { value: v, .. } => {
1167                if v.len() == 1 {
1168                    v[0].to_simple_r(context)
1169                } else {
1170                    panic!("Not yet implemented for indexing of multiple elements")
1171                }
1172            }
1173            _ => self.to_r(context),
1174        }
1175    }
1176
1177    pub fn to_module_member(self) -> Lang {
1178        match self {
1179            Lang::Module {
1180                name,
1181                body,
1182                help_data: h,
1183                ..
1184            } => Lang::Lines {
1185                value: body.clone(),
1186                help_data: h,
1187            }
1188            .to_module_helper(&name),
1189            res => res,
1190        }
1191    }
1192
1193    pub fn to_module_helper(self, name: &str) -> Lang {
1194        match self.clone() {
1195            Lang::Variable { help_data: h, .. } => Lang::Operator {
1196                operator: Op::Dollar(h.clone()),
1197                rhs: Box::new(Var::from_name(name).to_language()),
1198                lhs: Box::new(self),
1199                help_data: h,
1200            },
1201            Lang::Let {
1202                variable: var,
1203                r#type: typ,
1204                expression: lang,
1205                is_public: is_pub,
1206                help_data: h,
1207            } => {
1208                let expr = Lang::Operator {
1209                    operator: Op::Dollar(h.clone()),
1210                    rhs: var,
1211                    lhs: Box::new(Var::from_name(name).to_language()),
1212                    help_data: h.clone(),
1213                };
1214                Lang::Let {
1215                    variable: Box::new(expr),
1216                    r#type: typ,
1217                    expression: lang,
1218                    is_public: is_pub,
1219                    help_data: h,
1220                }
1221            }
1222            Lang::Alias {
1223                identifier: var,
1224                parameters: types,
1225                target_type: typ,
1226                is_public: is_pub,
1227                help_data: h,
1228            } => {
1229                let expr = Lang::Operator {
1230                    operator: Op::Dollar(h.clone()),
1231                    rhs: Box::new(Var::from_name(name).to_language()),
1232                    lhs: var,
1233                    help_data: h.clone(),
1234                };
1235                Lang::Alias {
1236                    identifier: Box::new(expr),
1237                    parameters: types,
1238                    target_type: typ,
1239                    is_public: is_pub,
1240                    help_data: h,
1241                }
1242            }
1243            Lang::Function {
1244                parameters: args,
1245                return_type: typ,
1246                body,
1247                help_data: h,
1248            } => Lang::Function {
1249                parameters: args,
1250                return_type: typ,
1251                body: Box::new(body.to_module_helper(name)),
1252                help_data: h,
1253            },
1254            Lang::Lines {
1255                value: exprs,
1256                help_data: h,
1257            } => Lang::Lines {
1258                value: exprs
1259                    .iter()
1260                    .cloned()
1261                    .map(|expr: Lang| expr.to_module_helper(name))
1262                    .collect::<Vec<_>>(),
1263                help_data: h,
1264            },
1265            rest => rest,
1266        }
1267    }
1268
1269    pub fn to_arg_value(self, type_module: &Type, context: &Context) -> Option<Vec<ArgumentValue>> {
1270        match self {
1271            Lang::Let {
1272                variable: lang,
1273                r#type: _,
1274                expression: body,
1275                is_public: _,
1276                help_data: h,
1277            } if Var::from_language(*lang.clone()).is_some() => {
1278                let var = Var::from_language(*lang).unwrap();
1279                type_module
1280                    .get_first_function_parameter_type(&var.get_name())
1281                    .map(|typ_par| {
1282                        var.clone().set_name(&format!(
1283                            "{}.{}",
1284                            var.get_name(),
1285                            context.get_type_anotation_no_parentheses(&typ_par)
1286                        ))
1287                    })
1288                    .map(|var2| {
1289                        Some(vec![
1290                            ArgumentValue(
1291                                var.get_name(),
1292                                Lang::GenFunc {
1293                                    name: var.get_name(),
1294                                    help_data: h,
1295                                },
1296                            ),
1297                            ArgumentValue(var2.get_name(), *body.clone()),
1298                        ])
1299                    })
1300                    .unwrap_or(Some(vec![ArgumentValue(var.get_name(), *body)]))
1301            }
1302            _ => None,
1303        }
1304    }
1305
1306    pub fn get_token_type(&self) -> TokenKind {
1307        TokenKind::Expression
1308    }
1309
1310    pub fn get_binding_power(&self) -> i32 {
1311        1
1312    }
1313
1314    pub fn get_members_if_array(&self) -> Option<Vec<Lang>> {
1315        match self {
1316            Lang::Array { value: members, .. } => Some(members.clone()),
1317            _ => None,
1318        }
1319    }
1320
1321    pub fn len(&self) -> i32 {
1322        match self {
1323            Lang::Integer { value: i, .. } => *i,
1324            Lang::Array { value: v, .. } => v.len() as i32,
1325            Lang::Vector { value: v, .. } => v.len() as i32,
1326            n => panic!("not implemented for language {}", n.simple_print()),
1327        }
1328    }
1329
1330    pub fn is_empty(&self) -> bool {
1331        self.len() == 0
1332    }
1333
1334    pub fn to_vec(self) -> Vec<Lang> {
1335        match self {
1336            Lang::Lines { value: v, .. } => v,
1337            l => vec![l],
1338        }
1339    }
1340}
1341
1342impl From<Lang> for HelpData {
1343    fn from(val: Lang) -> Self {
1344        match val {
1345            Lang::Number { help_data: h, .. } => h,
1346            Lang::Integer { help_data: h, .. } => h,
1347            Lang::Bool { help_data: h, .. } => h,
1348            Lang::Char { help_data: h, .. } => h,
1349            Lang::Variable { help_data: h, .. } => h,
1350            Lang::Match { help_data: h, .. } => h,
1351            Lang::FunctionApp { help_data: h, .. } => h,
1352            Lang::VecFunctionApp { help_data: h, .. } => h,
1353            Lang::Empty(h) => h,
1354            Lang::Array { help_data: h, .. } => h,
1355            Lang::List { help_data: h, .. } => h,
1356            Lang::DataFrame { help_data: h, .. } => h,
1357            Lang::Scope { help_data: h, .. } => h,
1358            Lang::Let { help_data: h, .. } => h,
1359            Lang::Alias { help_data: h, .. } => h,
1360            Lang::Lambda { help_data: h, .. } => h,
1361            Lang::Function { help_data: h, .. } => h,
1362            Lang::VecBlock { help_data: h, .. } => h,
1363            Lang::If { help_data: h, .. } => h,
1364            Lang::Assign { help_data: h, .. } => h,
1365            Lang::Union(_, _, h) => h,
1366            Lang::Module { help_data: h, .. } => h,
1367            Lang::ModuleImport { help_data: h, .. } => h,
1368            Lang::Import { help_data: h, .. } => h,
1369            Lang::ArrayIndexing { help_data: h, .. } => h,
1370            Lang::Tag { help_data: h, .. } => h,
1371            Lang::Tuple { help_data: h, .. } => h,
1372            Lang::Lines { help_data: h, .. } => h,
1373            Lang::Comment { help_data: h, .. } => h,
1374            Lang::GenFunc { help_data: h, .. } => h,
1375            Lang::Test { help_data: h, .. } => h,
1376            Lang::Return { help_data: h, .. } => h,
1377            Lang::Library { help_data: h, .. } => h,
1378            Lang::Exp { help_data: h, .. } => h,
1379            Lang::Signature { help_data: h, .. } => h,
1380            Lang::ForLoop { help_data: h, .. } => h,
1381            Lang::RFunction { help_data: h, .. } => h,
1382            Lang::KeyValue { help_data: h, .. } => h,
1383            Lang::Vector { help_data: h, .. } => h,
1384            Lang::Not { help_data: h, .. } => h,
1385            Lang::Sequence { help_data: h, .. } => h,
1386            Lang::TestBlock { help_data: h, .. } => h,
1387            Lang::JSBlock(_, _, h) => h,
1388            Lang::Use { help_data: h, .. } => h,
1389            Lang::WhileLoop { help_data: h, .. } => h,
1390            Lang::Break(h) => h,
1391            Lang::Operator { help_data: h, .. } => h,
1392            Lang::TypePattern { help_data: h, .. } => h,
1393            Lang::Null(h) => h,
1394            Lang::NA(h) => h,
1395            Lang::Dots(h) => h,
1396            Lang::UseModule { help_data: h, .. } => h,
1397            Lang::ConstructorCall { help_data: h, .. } => h,
1398            Lang::UnionConstructor { help_data: h, .. } => h,
1399            Lang::ArrayConstructorCall { help_data: h, .. } => h,
1400        }
1401        .clone()
1402    }
1403}
1404
1405use std::fmt;
1406impl fmt::Display for Lang {
1407    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1408        let res = match self {
1409            Lang::Variable {
1410                name,
1411                related_type: typ,
1412                ..
1413            } => format!("{} -> {}", name, typ),
1414            _ => format!("{:?}", self),
1415        };
1416        write!(f, "{}", res)
1417    }
1418}
1419
1420pub fn format_backtick(s: String) -> String {
1421    "`".to_string() + &s.replace("`", "") + "`"
1422}
1423
1424#[derive(Debug)]
1425pub struct ErrorStruct;
1426
1427impl FromStr for Lang {
1428    type Err = ErrorStruct;
1429
1430    fn from_str(s: &str) -> Result<Self, Self::Err> {
1431        let val = elements(s.into()).map(|x| x.1).unwrap_or_default();
1432        Ok(val)
1433    }
1434}