Skip to main content

typr_core/components/language/
mod.rs

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