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