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