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