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