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 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 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 UseModule {
287 module_path: Vec<String>,
288 selector: UseSelector,
289 help_data: HelpData,
290 },
291 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 ArrayConstructorCall {
309 type_name: String,
310 elements: Vec<Lang>,
311 help_data: HelpData,
312 },
313 ValidatingCast {
320 expression: Box<Lang>,
321 type_name: String,
322 #[serde(default)]
323 literal_type: Option<Type>,
324 help_data: HelpData,
325 },
326 UnionConstructor {
328 union_name: String,
329 variant_name: String,
330 fields: Vec<ArgumentValue>,
331 help_data: HelpData,
332 },
333 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
776impl 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 = ¶ms
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}