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