nessa/
types.rs

1use std::collections::HashMap;
2use std::collections::HashSet;
3
4use colored::Colorize;
5use serde::{Serialize, Deserialize};
6use malachite::Integer;
7
8use crate::annotations::Annotation;
9use crate::context::NessaContext;
10use crate::html_ext::HTMLColorable;
11use crate::id_mapper::IdMapper;
12use crate::interfaces::InterfaceConstraint;
13use crate::nessa_error;
14use crate::object::Object;
15use crate::parser::Location;
16use crate::patterns::Pattern;
17
18/*
19                                                  ╒══════════════════╕
20    ============================================= │  IMPLEMENTATION  │ =============================================
21                                                  ╘══════════════════╛
22*/
23
24pub type ParsingFunction = fn(&NessaContext, &TypeTemplate, &String) -> Result<Object, String>;
25
26#[derive(Clone, Serialize, Deserialize)]
27pub struct TypeTemplate {
28    pub id: usize,
29    pub name: String,
30    pub params: Vec<String>,
31
32    #[serde(skip)]
33    pub location: Location,
34    
35    #[serde(skip)]
36    pub annotations: Vec<Annotation>,
37
38    #[serde(skip)]
39    pub attributes: Vec<(String, Type)>,
40
41    pub alias: Option<Type>,
42    
43    #[serde(skip)]
44    pub patterns: Vec<Pattern>,
45
46    #[serde(skip)]
47    pub parser: Option<ParsingFunction>
48}
49
50impl TypeTemplate {
51    pub fn is_nominal(&self) -> bool {
52        self.alias.is_none()
53    }
54
55    pub fn is_structural(&self) -> bool {
56        self.alias.is_some()
57    }
58}
59
60#[allow(clippy::derived_hash_with_manual_eq)]
61#[derive(Clone, Hash, Debug, Serialize, Deserialize)]
62pub enum Type {
63    // Empty type (also called void)
64    Empty,
65
66    // Type to infer later
67    InferenceMarker,
68
69    // Type to substitute in interfaces
70    SelfType,
71
72    // Simple types
73    Basic(usize),
74
75    // References
76    Ref(Box<Type>),
77    MutRef(Box<Type>),
78
79    // Algebraic types
80    Or(Vec<Type>),
81    And(Vec<Type>),
82
83    // Parametric types
84    Wildcard,
85    TemplateParam(usize, Vec<InterfaceConstraint>),
86    TemplateParamStr(String, Vec<InterfaceConstraint>),
87    Template(usize, Vec<Type>),
88
89    // Function type
90    Function(Box<Type>, Box<Type>)
91}
92
93impl PartialEq for Type {
94    fn eq(&self, b: &Self) -> bool {
95        return match (self, b) {
96            (Type::SelfType, Type::SelfType) |
97            (Type::Empty, Type::Empty) |
98            (Type::InferenceMarker, Type::InferenceMarker) |
99            (Type::Wildcard, Type::Wildcard) => true,
100            (Type::Basic(id_a), Type::Basic(id_b)) => id_a == id_b,
101            (Type::Ref(ta), Type::Ref(tb)) => ta == tb,
102            (Type::MutRef(ta), Type::MutRef(tb)) => ta == tb,
103            (Type::Or(va), Type::Or(vb)) => va.iter().all(|i| vb.contains(i)) && vb.iter().all(|i| va.contains(i)),
104            (Type::And(va), Type::And(vb)) => va == vb,
105            (Type::And(va), b) => va.len() == 1 && va[0] == *b,
106            (a, Type::And(vb)) => vb.len() == 1 && vb[0] == *a,
107            (Type::TemplateParam(id_a, v_a), Type::TemplateParam(id_b, v_b)) => id_a == id_b && v_a == v_b,
108            (Type::TemplateParamStr(n_a, v_a), Type::TemplateParamStr(n_b, v_b)) => n_a == n_b && v_a == v_b,
109            (Type::Template(id_a, va), Type::Template(id_b, vb)) => id_a == id_b && va == vb,
110            (Type::Function(fa, ta), Type::Function(fb, tb)) => fa == fb && ta == tb,
111            
112            _ => false
113        }
114    }
115}
116
117impl Eq for Type {}
118
119impl Type {
120    pub fn is_ref(&self) -> bool {
121        matches!(
122            self,
123            Type::Ref(_) | Type::MutRef(_)
124        )
125    }
126
127    pub fn to_ref(self) -> Type {
128        Type::Ref(Box::new(self))
129    }
130
131    pub fn to_mut(self) -> Type {
132        Type::MutRef(Box::new(self))
133    }
134
135    pub fn or(self, other: Type) -> Type {
136        Type::Or(vec!(self, other))
137    }
138
139    pub fn deref_type(&self) -> &Type {
140        match self {
141            Type::Ref(t) | Type::MutRef(t) => t,
142            _ => self
143        }
144    }
145
146    pub fn get_name(&self, ctx: &NessaContext) -> String {
147        return match self {
148            Type::Empty => "()".into(),
149            Type::SelfType => format!("{}", "Self".green()),
150            Type::InferenceMarker => "[Inferred]".into(),
151
152            Type::Basic(id) => ctx.type_templates[*id].name.clone().cyan().to_string(),
153            Type::Ref(t) => format!("{}{}", "&".magenta(), t.get_name(ctx)),
154            Type::MutRef(t) => format!("{}{}", "@".magenta(), t.get_name(ctx)),
155            Type::Or(v) => v.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(" | "),
156            Type::And(v) => format!("({})", v.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")),
157
158            Type::Wildcard => "*".cyan().to_string(),
159
160            Type::TemplateParam(id, v) => {
161                if !v.is_empty() {
162                    format!(
163                        "{} [{}]", 
164                        format!("'T_{}", id).green(), 
165                        v.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
166                    )
167
168                } else {
169                    format!("'T_{}", id).green().to_string()
170                }
171            },
172            Type::TemplateParamStr(name, v) => {
173                if !v.is_empty() {
174                    format!(
175                        "{} [{}]", 
176                        format!("'{}", name).green(), 
177                        v.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
178                    )
179                    
180                } else {
181                    format!("'{}", name).green().to_string()
182                }   
183            },
184            Type::Template(id, v) => format!("{}<{}>", ctx.type_templates[*id].name.cyan().to_string().clone(), 
185                                                       v.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")),
186            Type::Function(from, to) => format!("{} => {}", from.get_name(ctx), to.get_name(ctx))
187        }
188    }
189
190    pub fn get_name_html(&self, ctx: &NessaContext) -> String {
191        return match self {
192            Type::Empty => "()".into(),
193            Type::SelfType => format!("{}", "Self".html_cyan()),
194            Type::InferenceMarker => "[Inferred]".into(),
195
196            Type::Basic(id) => ctx.type_templates[*id].name.clone().html_green().to_string(),
197            Type::Ref(t) => format!("{}{}", "&".html_magenta(), t.get_name_html(ctx)),
198            Type::MutRef(t) => format!("{}{}", "@".html_magenta(), t.get_name_html(ctx)),
199            Type::Or(v) => v.iter().map(|i| i.get_name_html(ctx)).collect::<Vec<_>>().join(" | "),
200            Type::And(v) => format!("({})", v.iter().map(|i| i.get_name_html(ctx)).collect::<Vec<_>>().join(", ")),
201
202            Type::Wildcard => "*".html_cyan().to_string(),
203
204            Type::TemplateParam(id, v) => {
205                if !v.is_empty() {
206                    format!(
207                        "{} [{}]", 
208                        format!("'T_{}", id).html_blue(), 
209                        v.iter().map(|i| i.get_name_html(ctx)).collect::<Vec<_>>().join(", ")
210                    )
211
212                } else {
213                    format!("'T_{}", id).html_blue().to_string()
214                }
215            },
216            Type::TemplateParamStr(name, v) => {
217                if !v.is_empty() {
218                    format!(
219                        "{} [{}]", 
220                        format!("'{}", name).html_blue(), 
221                        v.iter().map(|i| i.get_name_html(ctx)).collect::<Vec<_>>().join(", ")
222                    )
223                    
224                } else {
225                    format!("'{}", name).html_blue().to_string()
226                }   
227            },
228            Type::Template(id, v) => format!("{}&lt;{}&gt;", ctx.type_templates[*id].name.html_green().to_string().clone(), 
229                                                       v.iter().map(|i| i.get_name_html(ctx)).collect::<Vec<_>>().join(", ")),
230            Type::Function(from, to) => format!("{} => {}", from.get_name_html(ctx), to.get_name_html(ctx))
231        }
232    }
233
234    pub fn get_name_plain(&self, ctx: &NessaContext) -> String {
235        return match self {
236            Type::Empty => "()".into(),
237            Type::SelfType => "Self".to_string(),
238            Type::InferenceMarker => "[Inferred]".into(),
239
240            Type::Basic(id) => ctx.type_templates[*id].name.clone().to_string(),
241            Type::Ref(t) => format!("{}{}", "&", t.get_name_plain(ctx)),
242            Type::MutRef(t) => format!("{}{}", "@", t.get_name_plain(ctx)),
243            Type::Or(v) => v.iter().map(|i| i.get_name_plain(ctx)).collect::<Vec<_>>().join(" | "),
244            Type::And(v) => format!("({})", v.iter().map(|i| i.get_name_plain(ctx)).collect::<Vec<_>>().join(", ")),
245
246            Type::Wildcard => "*".to_string(),
247
248            Type::TemplateParam(id, v) => {
249                if !v.is_empty() {
250                    format!(
251                        "T_{} [{}]", 
252                        id, 
253                        v.iter().map(|i| i.get_name_plain(ctx)).collect::<Vec<_>>().join(", ")
254                    )
255
256                } else {
257                    format!("'T_{}", id).to_string()
258                }
259            },
260            Type::TemplateParamStr(name, v) => {
261                if !v.is_empty() {
262                    format!(
263                        "'{} [{}]", 
264                        name, 
265                        v.iter().map(|i| i.get_name_plain(ctx)).collect::<Vec<_>>().join(", ")
266                    )
267                    
268                } else {
269                    format!("'{}", name).to_string()
270                }   
271            },
272            Type::Template(id, v) => format!("{}<{}>", ctx.type_templates[*id].name.to_string().clone(), 
273                                                       v.iter().map(|i| i.get_name_plain(ctx)).collect::<Vec<_>>().join(", ")),
274            Type::Function(from, to) => format!("{} => {}", from.get_name_plain(ctx), to.get_name_plain(ctx))
275        }
276    }
277
278    pub fn has_templates(&self) -> bool {
279        return match self {
280            Type::Wildcard |
281            Type::Empty |
282            Type::Basic(_) => false,
283
284            Type::Ref(a) |
285            Type::MutRef(a) => a.has_templates(),
286
287            Type::Template(_, a) |
288            Type::Or(a) |
289            Type::And(a) => a.iter().any(Type::has_templates),
290
291            Type::TemplateParam(..) => true,
292            
293            Type::Function(a, b) => a.has_templates() || b.has_templates(),
294
295            _ => unimplemented!()
296        };
297    }
298
299    pub fn has_self(&self) -> bool {
300        return match self {
301            Type::SelfType => true,
302
303            Type::Wildcard |
304            Type::Empty |
305            Type::Basic(_) => false,
306
307            Type::Ref(a) |
308            Type::MutRef(a) => a.has_self(),
309
310            Type::Template(_, a) |
311            Type::Or(a) |
312            Type::And(a) => a.iter().any(Type::has_self),
313
314            Type::TemplateParamStr(_, c) |
315            Type::TemplateParam(_, c) => c.iter().flat_map(|i| &i.args).any(Type::has_self),
316
317            Type::Function(a, b) => a.has_self() || b.has_self(),
318
319            e => unimplemented!("{e:?}")
320        };
321    }
322
323    pub fn template_dependencies(&self, templates: &mut HashSet<usize>) {
324        return match self {
325            Type::Wildcard |
326            Type::Empty  |
327            Type::InferenceMarker  |
328            Type::SelfType  |
329            Type::Basic(..)  |
330            Type::TemplateParamStr(..) => {}
331
332            Type::Ref(t) |
333            Type::MutRef(t) => t.template_dependencies(templates),
334
335            Type::Template(_, ts) |
336            Type::Or(ts) |
337            Type::And(ts) => ts.iter().for_each(|i| i.template_dependencies(templates)),
338
339            Type::TemplateParam(id, cs) => {
340                templates.insert(*id);
341
342                for c in cs {
343                    for t in &c.args {
344                        t.template_dependencies(templates);
345                    }
346                }
347            },
348
349            Type::Function(a, b) => {
350                a.template_dependencies(templates);
351                b.template_dependencies(templates);
352            },
353        };
354    }
355
356    pub fn type_dependencies(&self) -> Vec<usize> {
357        return match self {
358            Type::Wildcard |
359            Type::Empty  |
360            Type::InferenceMarker  |
361            Type::SelfType  |
362            Type::TemplateParamStr(..) => vec!(),
363
364            Type::Basic(id) => vec!(*id),
365
366            Type::Ref(a) |
367            Type::MutRef(a) => a.type_dependencies(),
368
369            Type::Or(ts) |
370            Type::And(ts) => ts.iter().flat_map(|t| t.type_dependencies()).collect(),
371
372            Type::Function(a, b) => {
373                let mut res = a.type_dependencies();
374                res.append(&mut b.type_dependencies());
375
376                res
377            }
378
379            Type::TemplateParam(_, v) => {
380                v.iter().flat_map(|i| i.args.clone()).flat_map(|i| i.type_dependencies()).collect()
381            }
382
383            Type::Template(id, ts) => {
384                let mut res = vec!(*id);
385                res.append(&mut ts.iter().flat_map(|t| t.type_dependencies()).collect());
386
387                res
388            }
389        };
390    }
391
392    pub fn interface_dependencies(&self) -> Vec<usize> {
393        return match self {
394            Type::Wildcard |
395            Type::Empty  |
396            Type::InferenceMarker  |
397            Type::SelfType  |
398            Type::Basic(..) |
399            Type::TemplateParamStr(..) => vec!(),
400
401            Type::Ref(a) |
402            Type::MutRef(a) => a.interface_dependencies(),
403
404            Type::Or(ts) |
405            Type::And(ts) => ts.iter().flat_map(|t| t.interface_dependencies()).collect(),
406
407            Type::Function(a, b) => {
408                let mut res = a.interface_dependencies();
409                res.append(&mut b.interface_dependencies());
410
411                res
412            }
413
414            Type::TemplateParam(_, v) => {
415                let mut res = v.iter().map(|i| i.id).collect::<Vec<_>>();
416
417                for i in v {
418                    res.extend(i.args.iter().flat_map(|i| i.interface_dependencies()));
419                }
420
421                res
422            },
423
424            Type::Template(_, ts) => {
425                let mut res = vec!();
426                res.append(&mut ts.iter().flat_map(|t| t.interface_dependencies()).collect());
427
428                res
429            }
430        };
431    }
432
433    pub fn bindable_to(&self, other: &Type, ctx: &NessaContext) -> bool {
434        self.template_bindable_to(other, &mut HashMap::new(), &mut HashMap::new(), ctx)
435    }
436
437    pub fn bindable_to_subtitutions(&self, other: &Type, ctx: &NessaContext) -> (bool, HashMap<usize, Type>) {
438        let mut assignments = HashMap::new();
439        let res = self.template_bindable_to(other, &mut assignments, &mut HashMap::new(), ctx);
440
441        (res, assignments)
442    }
443
444    pub fn bindable_to_template(&self, other: &Type, templates: &[Type], ctx: &NessaContext) -> bool {
445        return self.template_bindable_to(other, &mut templates.iter().cloned().enumerate().collect(), &mut HashMap::new(), ctx);
446    }
447
448    pub fn template_bindable_to(&self, other: &Type, t_assignments: &mut HashMap<usize, Type>, t_deps: &mut HashMap<usize, HashSet<usize>>, ctx: &NessaContext) -> bool {
449        return match (self, other) {
450            (_, Type::Wildcard) => true,
451
452            (a, b) if a == b => true,
453
454            (_, Type::Empty) => false,
455
456            (Type::Ref(ta), Type::Ref(tb)) => ta.template_bindable_to(tb, t_assignments, t_deps, ctx),
457            (Type::MutRef(ta), Type::MutRef(tb)) => ta.template_bindable_to(tb, t_assignments, t_deps, ctx),
458
459            (Type::Basic(id), b) if ctx.type_templates[*id].is_structural() => {
460                let alias = ctx.type_templates[*id].alias.as_ref().unwrap();
461                return alias.template_bindable_to(b, t_assignments, t_deps, ctx);
462            },
463
464            (a, Type::Basic(id)) if ctx.type_templates[*id].is_structural() => {
465                let alias = ctx.type_templates[*id].alias.as_ref().unwrap();
466                return a.template_bindable_to(alias, t_assignments, t_deps, ctx);
467            },
468
469            (Type::Template(id, v), b) if ctx.type_templates[*id].is_structural() => {
470                let alias = ctx.type_templates[*id].alias.as_ref().unwrap();
471                let sub_alias = alias.sub_templates(&v.iter().cloned().enumerate().collect());
472
473                return sub_alias.template_bindable_to(b, t_assignments, t_deps, ctx);
474            },
475
476            (a, Type::Template(id, v)) if ctx.type_templates[*id].is_structural() => {
477                let alias = ctx.type_templates[*id].alias.as_ref().unwrap();
478                let sub_alias = alias.sub_templates(&v.iter().cloned().enumerate().collect());   
479
480                return a.template_bindable_to(&sub_alias, t_assignments, t_deps, ctx);
481            },
482
483            (Type::TemplateParam(id, cs), b) |
484            (b, Type::TemplateParam(id, cs)) => {
485                if let Some(t) = t_assignments.get(id).cloned() {    
486                    // More specific type
487                    if b.template_bindable_to(&t, t_assignments, t_deps, ctx) {
488                        t_assignments.insert(*id, b.clone());
489    
490                        return true;
491                    } 
492                    
493                    false
494                
495                } else {
496                    for c in cs {
497                        if !ctx.implements_interface(b, c, t_assignments, t_deps) {
498                            return false;
499                        }
500                    }
501
502                    t_assignments.insert(*id, b.clone());
503
504                    return b.template_cyclic_reference_check(*id, t_deps);
505                }
506            },
507
508            (Type::Or(v), b) => v.iter().all(|i| i.template_bindable_to(b, t_assignments, t_deps, ctx)),
509
510            (a, Type::Or(v)) => {
511                let mut t_assignments_cpy = t_assignments.clone();
512                let mut t_deps_cpy = t_deps.clone();
513
514                for i in v {
515                    if a.template_bindable_to(i, &mut t_assignments_cpy, &mut t_deps_cpy, ctx) {
516                        *t_assignments = t_assignments_cpy;
517                        *t_deps = t_deps_cpy;
518    
519                        return true;
520                    }
521                }
522
523                return false;
524            },
525
526            (Type::And(va), Type::And(vb)) => va.len() == vb.len() && va.iter().zip(vb).all(|(i, j)| i.template_bindable_to(j, t_assignments, t_deps, ctx)),
527            (Type::And(va), b) => va.len() == 1 && va[0].template_bindable_to(b, t_assignments, t_deps, ctx),
528            (a, Type::And(vb)) => vb.len() == 1 && a.template_bindable_to(&vb[0], t_assignments, t_deps, ctx),
529                        
530            (Type::Template(id_a, va), Type::Template(id_b, vb)) => id_a == id_b && va.len() == vb.len() && 
531                                                                    va.iter().zip(vb).all(|(i, j)| i.template_bindable_to(j, t_assignments, t_deps, ctx)),
532
533            (Type::Function(fa, ta), Type::Function(fb, tb)) => fa.template_bindable_to(fb, t_assignments, t_deps, ctx) && ta.template_bindable_to(tb, t_assignments, t_deps, ctx),
534
535            _ => false
536        }
537    }
538
539    fn template_cyclic_reference_check(&self, t_id: usize, t_deps: &mut HashMap<usize, HashSet<usize>>) -> bool {
540        return match self {
541            Type::Ref(t) => t.template_cyclic_reference_check(t_id, t_deps),
542            Type::MutRef(t) => t.template_cyclic_reference_check(t_id, t_deps),
543
544            Type::Or(v) => v.iter().all(|i| i.template_cyclic_reference_check(t_id, t_deps)),
545            Type::And(v) => v.iter().all(|i| i.template_cyclic_reference_check(t_id, t_deps)),
546            
547            Type::TemplateParam(id, _) => {
548                t_deps.entry(t_id).or_default().insert(*id);
549
550                t_id != *id && !t_deps.entry(*id).or_default().contains(&t_id)
551            },
552            
553            Type::Template(_, v) => v.iter().all(|i| i.template_cyclic_reference_check(t_id, t_deps)),
554
555            Type::Function(f, t) => f.template_cyclic_reference_check(t_id, t_deps) && t.template_cyclic_reference_check(t_id, t_deps),
556
557            _ => true
558        }
559    }
560
561    pub fn compile_templates(&mut self, templates: &Vec<String>) {
562        return match self {
563            Type::Ref(t) => t.compile_templates(templates),
564            Type::MutRef(t) => t.compile_templates(templates),
565
566            Type::Or(v) => v.iter_mut().for_each(|i| i.compile_templates(templates)),
567            Type::And(v) => v.iter_mut().for_each(|i| i.compile_templates(templates)),
568            
569            Type::TemplateParamStr(name, v) => {
570                v.iter_mut().for_each(|i| {
571                    i.args.iter_mut().for_each(|j| j.compile_templates(templates));
572                });
573                
574                if let Some(idx) = templates.iter().position(|i| i == name) {
575                    *self = Type::TemplateParam(idx, v.clone());
576                }
577            },
578            
579            Type::Template(_, v) => v.iter_mut().for_each(|i| i.compile_templates(templates)),
580
581            Type::Function(f, t) => {
582                f.compile_templates(templates); 
583                t.compile_templates(templates)
584            },
585
586            _ => { }
587        }
588    }
589
590    pub fn offset_templates(&mut self, offset: usize) {
591        return match self {
592            Type::Ref(t) => t.offset_templates(offset),
593            Type::MutRef(t) => t.offset_templates(offset),
594
595            Type::Or(v) => v.iter_mut().for_each(|i| i.offset_templates(offset)),
596            Type::And(v) => v.iter_mut().for_each(|i| i.offset_templates(offset)),
597            
598            Type::TemplateParam(id, v) => {
599                *id += offset;
600
601                v.iter_mut().for_each(|i| {
602                    i.args.iter_mut().for_each(|j| j.offset_templates(offset));
603                });
604            },
605            
606            Type::Template(_, v) => v.iter_mut().for_each(|i| i.offset_templates(offset)),
607
608            Type::Function(f, t) => {
609                f.offset_templates(offset); 
610                t.offset_templates(offset)
611            },
612
613            _ => { }
614        }
615    }
616
617    pub fn max_template(&self) -> i32 {
618        return match self {
619            Type::Ref(t) => t.max_template(),
620            Type::MutRef(t) => t.max_template(),
621
622            Type::Or(v) => v.iter().map(|i| i.max_template()).max().unwrap_or(-1),
623            Type::And(v) => v.iter().map(|i| i.max_template()).max().unwrap_or(-1),
624            
625            Type::TemplateParam(id, v) => {
626                v.iter().flat_map(|i| {
627                    i.args.iter().map(|j| j.max_template())
628                }).max().unwrap_or(-1).max(*id as i32)
629            },
630            
631            Type::Template(_, v) => v.iter().map(|i| i.max_template()).max().unwrap_or(-1),
632
633            Type::Function(f, t) => {
634                f.max_template().max(t.max_template())
635            },
636
637            _ => -1
638        }
639    }
640
641    pub fn sub_templates(&self, args: &HashMap<usize, Type>) -> Type {
642        self.sub_templates_rec(args, 100)
643    }
644
645    pub fn sub_templates_rec(&self, args: &HashMap<usize, Type>, rec: i32) -> Type {
646        return match self {
647            Type::Ref(t) => Type::Ref(Box::new(t.sub_templates_rec(args, rec))),
648            Type::MutRef(t) => Type::MutRef(Box::new(t.sub_templates_rec(args, rec))),
649            Type::Or(t) => Type::Or(t.iter().map(|i| i.sub_templates_rec(args, rec)).collect()),
650            Type::And(t) => Type::And(t.iter().map(|i| i.sub_templates_rec(args, rec)).collect()),
651            Type::Function(f, t) => Type::Function(Box::new(f.sub_templates_rec(args, rec)), Box::new(t.sub_templates_rec(args, rec))),
652            Type::TemplateParam(id, v) => {
653                let res = args.get(id).cloned().unwrap_or_else(||
654                    Type::TemplateParam(*id, v.iter().map(|i| {
655                        let mapped_args = i.args.iter().map(|j| j.sub_templates_rec(args, rec)).collect();
656                        InterfaceConstraint::new(i.id, mapped_args)
657                    }).collect())
658                );
659
660                let mut templates = HashSet::new();
661                res.template_dependencies(&mut templates);
662                
663                if templates.contains(id) { // Edge case
664                    res
665
666                } else if rec > 0 {
667                    res.sub_templates_rec(args, rec - 1)
668                    
669                } else {
670                    nessa_error!("Exceeded type recursion limit (100)"); // TODO: return a compiler error
671                }
672            },
673            Type::Template(id, t) => Type::Template(*id, t.iter().map(|i| i.sub_templates_rec(args, rec)).collect()),
674            _ => self.clone()
675        };
676    }
677
678    pub fn sub_self(&self, sub: &Type) -> Type {
679        return match self {
680            Type::SelfType => sub.clone(),
681            Type::Ref(t) => Type::Ref(Box::new(t.sub_self(sub))),
682            Type::MutRef(t) => Type::MutRef(Box::new(t.sub_self(sub))),
683            Type::Or(t) => Type::Or(t.iter().map(|i| i.sub_self(sub)).collect()),
684            Type::And(t) => Type::And(t.iter().map(|i| i.sub_self(sub)).collect()),
685            Type::Function(f, t) => Type::Function(Box::new(f.sub_self(sub)), Box::new(t.sub_self(sub))),
686            Type::TemplateParam(id, v) => {
687                Type::TemplateParam(*id, v.iter().map(|i| {
688                    let mapped_args = i.args.iter().map(|j| j.sub_self(sub)).collect();
689                    InterfaceConstraint::new(i.id, mapped_args)
690                }).collect())
691            }
692            Type::Template(id, t) => Type::Template(*id, t.iter().map(|i| i.sub_self(sub)).collect()),
693            _ => self.clone()
694        };
695    }
696
697    pub fn map_type(&self, ctx: &mut NessaContext, other_ctx: &NessaContext, id_mapper: &mut IdMapper, l: &Location) -> Type {
698        self.map_basic_types(&mut |id| ctx.map_nessa_class(other_ctx, id, id_mapper, l))
699            .map_interfaces(&mut |id| ctx.map_nessa_interface(other_ctx, id, id_mapper, l))
700    }
701
702    pub fn map_basic_types(&self, mapping: &mut impl FnMut(usize) -> Result<usize, String>) -> Type {
703        return match self {
704            Type::Basic(id) => Type::Basic(mapping(*id).unwrap()),
705            
706            Type::Ref(t) => Type::Ref(Box::new(t.map_basic_types(mapping))),
707            Type::MutRef(t) => Type::MutRef(Box::new(t.map_basic_types(mapping))),
708            Type::Or(t) => Type::Or(t.iter().map(|i| i.map_basic_types(mapping)).collect()),
709            Type::And(t) => Type::And(t.iter().map(|i| i.map_basic_types(mapping)).collect()),
710            Type::Function(f, t) => Type::Function(Box::new(f.map_basic_types(mapping)), Box::new(t.map_basic_types(mapping))),
711            Type::TemplateParam(id, v) => {
712                Type::TemplateParam(*id, v.iter().map(|i| {
713                    let mapped_args = i.args.iter().map(|j| j.map_basic_types(mapping)).collect();
714                    InterfaceConstraint::new(i.id, mapped_args)
715                }).collect())
716            }
717            Type::Template(id, t) => Type::Template(mapping(*id).unwrap(), t.iter().map(|i| i.map_basic_types(mapping)).collect()),
718
719            _ => self.clone()
720        };
721    }
722
723    pub fn map_interfaces(&self, mapping: &mut impl FnMut(usize) -> Result<usize, String>) -> Type {
724        return match self {            
725            Type::Ref(t) => Type::Ref(Box::new(t.map_interfaces(mapping))),
726            Type::MutRef(t) => Type::MutRef(Box::new(t.map_interfaces(mapping))),
727            Type::Or(t) => Type::Or(t.iter().map(|i| i.map_interfaces(mapping)).collect()),
728            Type::And(t) => Type::And(t.iter().map(|i| i.map_interfaces(mapping)).collect()),
729            Type::Function(f, t) => Type::Function(Box::new(f.map_interfaces(mapping)), Box::new(t.map_interfaces(mapping))),
730            Type::TemplateParam(id, v) => {
731                Type::TemplateParam(*id, v.iter().map(|i| {
732                    let mapped_args = i.args.iter().map(|j| j.map_interfaces(mapping)).collect();
733                    InterfaceConstraint::new(mapping(i.id).unwrap(), mapped_args)
734                }).collect())
735            }
736            Type::Template(id, t) => Type::Template(*id, t.iter().map(|i| i.map_interfaces(mapping)).collect()),
737
738            _ => self.clone()
739        };
740    }
741}
742
743/*
744                                                  ╒══════════════════╕
745    ============================================= │  STANDARD TYPES  │ =============================================
746                                                  ╘══════════════════╛
747*/
748
749// Constants for common types
750pub const INT_ID: usize = 0;
751pub const FLOAT_ID: usize = 1;
752pub const STR_ID: usize = 2;
753pub const BOOL_ID: usize = 3;
754pub const ARR_ID: usize = 4;
755pub const ARR_IT_ID: usize = 5;
756pub const FILE_ID: usize = 6;
757
758pub const INT: Type = Type::Basic(INT_ID);
759pub const FLOAT: Type = Type::Basic(FLOAT_ID);
760pub const STR: Type = Type::Basic(STR_ID);
761pub const BOOL: Type = Type::Basic(BOOL_ID);
762pub const FILE: Type = Type::Basic(FILE_ID);
763
764#[macro_export]
765macro_rules! ARR_OF { ($t: expr) => { Type::Template($crate::types::ARR_ID, vec!($t)) }; }
766
767#[macro_export]
768macro_rules! ARR_IT_OF { ($t: expr) => { Type::Template($crate::types::ARR_IT_ID, vec!($t)) }; }
769
770pub const T_0: Type = Type::TemplateParam(0, vec!());
771pub const T_1: Type = Type::TemplateParam(1, vec!());
772pub const T_2: Type = Type::TemplateParam(2, vec!());
773
774// Standard context
775pub fn standard_types(ctx: &mut NessaContext) {
776    ctx.define_type(Location::none(), vec!(), "Int".into(), vec!(), vec!(), None, vec!(), Some(|_, _, s| s.parse::<Integer>().map(Object::new).map_err(|_| "Invalid Int format".into()))).unwrap();
777    ctx.define_type(Location::none(), vec!(), "Float".into(), vec!(), vec!(), None, vec!(), Some(|_, _, s| s.parse::<f64>().map(Object::new).map_err(|_| "Invalid float format".to_string()))).unwrap();
778    ctx.define_type(Location::none(), vec!(), "String".into(), vec!(), vec!(), None, vec!(), None).unwrap();
779
780    ctx.define_type(Location::none(), vec!(), "Bool".into(), vec!(), vec!(), None, vec!(), Some(|_, _, s| 
781        if s == "true" || s == "false" {
782            Ok(Object::new(s.starts_with('t')))
783
784        } else {
785            Err(format!("Unable to parse bool from {}", s))
786        }
787    )).unwrap();
788
789    ctx.define_type(Location::none(), vec!(), "Array".into(), vec!("Inner".into()), vec!(), None, vec!(), None).unwrap();
790    ctx.define_type(Location::none(), vec!(), "ArrayIterator".into(), vec!("Inner".into()), vec!(), None, vec!(), None).unwrap();
791
792    ctx.define_type(Location::none(), vec!(), "File".into(), vec!(), vec!(), None, vec!(), None).unwrap();
793}
794
795/*
796                                                  ╒═════════╕
797    ============================================= │  TESTS  │ =============================================
798                                                  ╘═════════╛
799*/
800
801#[cfg(test)]
802mod tests {
803    use crate::{types::*, context::standard_ctx};
804
805    #[test]
806    fn basic_type_binding() {
807        let ctx = standard_ctx();
808
809        let number_t = TypeTemplate {
810            id: 0,
811            name: "Int".into(),
812            params: vec!(),
813            location: Location::none(),
814            annotations: vec!(),
815            attributes: vec!(),
816            alias: None,
817            patterns: vec!(),
818            parser: None
819        };
820
821        let string_t = TypeTemplate {
822            id: 1,
823            name: "String".into(),
824            params: vec!(),
825            location: Location::none(),
826            annotations: vec!(),
827            attributes: vec!(),
828            alias: None,
829            patterns: vec!(),
830            parser: None
831        };
832
833        let bool_t = TypeTemplate {
834            id: 2,
835            name: "Bool".into(),
836            params: vec!(),
837            location: Location::none(),
838            annotations: vec!(),
839            attributes: vec!(),
840            alias: None,
841            patterns: vec!(),
842            parser: None
843        };
844
845        let vector_t = TypeTemplate {
846            id: 3,
847            name: "Vector".into(),
848            params: vec!("T".into()),
849            location: Location::none(),
850            annotations: vec!(),
851            attributes: vec!(),
852            alias: None,
853            patterns: vec!(),
854            parser: None
855        };
856
857        let number = Type::Basic(number_t.id);
858        let string = Type::Basic(string_t.id);
859        let boolean = Type::Basic(bool_t.id);
860
861        assert!(number.bindable_to(&number, &ctx));
862        assert!(string.bindable_to(&string, &ctx));
863        assert!(!number.bindable_to(&string, &ctx));
864
865        let number_ref = Type::Ref(Box::new(number.clone()));
866        let number_mut = Type::MutRef(Box::new(number.clone()));
867
868        assert!(number_ref.bindable_to(&number_ref, &ctx));
869        assert!(number_mut.bindable_to(&number_mut, &ctx));
870        assert!(!number_mut.bindable_to(&number_ref, &ctx));
871        assert!(!number_ref.bindable_to(&number_mut, &ctx));
872
873        let string_or_number = Type::Or(vec!(string.clone(), number.clone()));
874        let number_or_string = Type::Or(vec!(number.clone(), string.clone()));
875
876        assert!(string_or_number.bindable_to(&string_or_number, &ctx));
877        assert!(number_or_string.bindable_to(&number_or_string, &ctx));
878        assert!(string_or_number.bindable_to(&number_or_string, &ctx));
879        assert!(number_or_string.bindable_to(&string_or_number, &ctx));
880
881        assert!(number.bindable_to(&string_or_number, &ctx));
882        assert!(string.bindable_to(&string_or_number, &ctx));
883        assert!(!boolean.bindable_to(&string_or_number, &ctx));
884
885        assert!(!string_or_number.bindable_to(&string, &ctx));
886
887        let string_and_number = Type::And(vec!(string.clone(), number.clone()));
888
889        assert!(string_and_number.bindable_to(&string_and_number, &ctx));
890        assert!(!string_or_number.bindable_to(&string_and_number, &ctx));
891        assert!(!string.bindable_to(&string_and_number, &ctx));
892        assert!(!number.bindable_to(&string_and_number, &ctx));
893
894        let wildcard = Type::Wildcard;
895
896        assert!(number.bindable_to(&wildcard, &ctx));
897        assert!(string.bindable_to(&wildcard, &ctx));
898        assert!(boolean.bindable_to(&wildcard, &ctx));
899        assert!(number_or_string.bindable_to(&wildcard, &ctx));
900        assert!(string_and_number.bindable_to(&wildcard, &ctx));
901        assert!(wildcard.bindable_to(&wildcard, &ctx));
902
903        let empty = Type::Empty;
904
905        assert!(!number.bindable_to(&empty, &ctx));
906        assert!(!string.bindable_to(&empty, &ctx));
907        assert!(!boolean.bindable_to(&empty, &ctx));
908        assert!(!number_or_string.bindable_to(&empty, &ctx));
909        assert!(!string_and_number.bindable_to(&empty, &ctx));
910        assert!(empty.bindable_to(&empty, &ctx));
911
912        let vector_number = Type::Template(vector_t.id, vec!(number.clone()));
913        let vector_string = Type::Template(vector_t.id, vec!(string));
914        let vector_number_or_string = Type::Template(vector_t.id, vec!(number_or_string.clone()));
915
916        assert!(vector_number.bindable_to(&vector_number, &ctx));
917        assert!(vector_number.bindable_to(&vector_number_or_string, &ctx));
918        assert!(!vector_number.bindable_to(&vector_string, &ctx));
919
920        let f_number_number = Type::Function(Box::new(number.clone()), Box::new(number.clone()));
921        let f_number_or_string_number = Type::Function(Box::new(number_or_string.clone()), Box::new(number.clone()));
922
923        assert!(f_number_number.bindable_to(&f_number_number, &ctx));
924        assert!(f_number_or_string_number.bindable_to(&f_number_or_string_number, &ctx));
925        assert!(f_number_number.bindable_to(&f_number_or_string_number, &ctx));
926        assert!(!f_number_or_string_number.bindable_to(&f_number_number, &ctx));
927    }
928
929    #[test]
930    fn template_binding() {
931        let ctx = standard_ctx();
932
933        let number_t = TypeTemplate {
934            id: 0,
935            name: "Int".into(),
936            params: vec!(),
937            location: Location::none(),
938            annotations: vec!(),
939            attributes: vec!(),
940            alias: None,
941            patterns: vec!(),
942            parser: None
943        };
944
945        let string_t = TypeTemplate {
946            id: 1,
947            name: "String".into(),
948            params: vec!(),
949            location: Location::none(),
950            annotations: vec!(),
951            attributes: vec!(),
952            alias: None,
953            patterns: vec!(),
954            parser: None
955        };
956
957        let bool_t = TypeTemplate {
958            id: 2,
959            name: "Bool".into(),
960            params: vec!(),
961            location: Location::none(),
962            annotations: vec!(),
963            attributes: vec!(),
964            alias: None,
965            patterns: vec!(),
966            parser: None
967        };
968
969        let vector_t = TypeTemplate {
970            id: 3,
971            name: "Vector".into(),
972            params: vec!("T".into()),
973            location: Location::none(),
974            annotations: vec!(),
975            attributes: vec!(),
976            alias: None,
977            patterns: vec!(),
978            parser: None
979        };
980
981        let map_t = TypeTemplate {
982            id: 3,
983            name: "Map".into(),
984            params: vec!("T".into(), "G".into()),
985            location: Location::none(),
986            annotations: vec!(),
987            attributes: vec!(),
988            alias: None,
989            patterns: vec!(),
990            parser: None
991        };
992
993        let number = Type::Basic(number_t.id);
994        let string = Type::Basic(string_t.id);
995        let boolean = Type::Basic(bool_t.id);
996
997        let template_1 = Type::TemplateParam(0, vec!());
998        let template_2 = Type::Ref(Box::new(Type::TemplateParam(0, vec!())));
999
1000        assert!(number.bindable_to(&template_1, &ctx));
1001        assert!(string.bindable_to(&template_1, &ctx));
1002        assert!(boolean.bindable_to(&template_1, &ctx));
1003        assert!(!number.bindable_to(&template_2, &ctx));
1004        assert!(!string.bindable_to(&template_2, &ctx));
1005        assert!(!boolean.bindable_to(&template_2, &ctx));
1006        assert!(!template_1.bindable_to(&template_2, &ctx));
1007        assert!(!template_2.bindable_to(&template_1, &ctx));
1008
1009        let template_1 = Type::Template(vector_t.id, vec!(Type::TemplateParam(0, vec!()))); 
1010        let template_2 = Type::Template(map_t.id, vec!(Type::TemplateParam(0, vec!()), Type::TemplateParam(1, vec!()))); 
1011
1012        let binding_1 = Type::Template(vector_t.id, vec!(number.clone()));
1013        let binding_2 = Type::Template(map_t.id, vec!(number.clone(), string.clone()));
1014
1015        assert!(binding_1.bindable_to(&template_1, &ctx));
1016        assert!(binding_2.bindable_to(&template_2, &ctx));
1017        assert!(!binding_2.bindable_to(&template_1, &ctx));
1018        assert!(!binding_1.bindable_to(&template_2, &ctx));
1019
1020        let template_1 = Type::Template(map_t.id, vec!(Type::TemplateParam(0, vec!()), Type::TemplateParam(0, vec!()))); 
1021
1022        let binding_1 = Type::Template(map_t.id, vec!(number.clone(), number.clone()));
1023        let binding_2 = Type::Template(map_t.id, vec!(boolean.clone(), boolean.clone()));
1024        let binding_3 = Type::Template(map_t.id, vec!(number.clone(), string.clone()));
1025        
1026        assert!(binding_1.bindable_to(&template_1, &ctx));
1027        assert!(binding_2.bindable_to(&template_1, &ctx));
1028        assert!(!binding_3.bindable_to(&template_1, &ctx));
1029
1030        let template_1 = Type::Template(map_t.id, vec!(Type::TemplateParam(0, vec!()), Type::Template(map_t.id, vec!(Type::TemplateParam(1, vec!()), Type::TemplateParam(0, vec!()))))); 
1031
1032        let binding_1 = Type::Template(map_t.id, vec!(number.clone(), Type::Template(map_t.id, vec!(number.clone(), number.clone()))));
1033        let binding_2 = Type::Template(map_t.id, vec!(string.clone(), Type::Template(map_t.id, vec!(string.clone(), string.clone()))));
1034        let binding_3 = Type::Template(map_t.id, vec!(number.clone(), Type::Template(map_t.id, vec!(string.clone(), number.clone()))));
1035        let binding_4 = Type::Template(map_t.id, vec!(number.clone(), Type::Template(map_t.id, vec!(string.clone(), string.clone()))));
1036        let binding_5 = Type::Template(map_t.id, vec!(string.clone(), Type::Template(map_t.id, vec!(string.clone(), number.clone()))));
1037        
1038        assert!(binding_1.bindable_to(&template_1, &ctx));
1039        assert!(binding_2.bindable_to(&template_1, &ctx));
1040        assert!(binding_3.bindable_to(&template_1, &ctx));
1041        assert!(!binding_4.bindable_to(&template_1, &ctx));
1042        assert!(!binding_5.bindable_to(&template_1, &ctx));
1043
1044        let template_1 = Type::Template(map_t.id, vec!(Type::TemplateParam(0, vec!()), Type::Template(map_t.id, vec!(Type::TemplateParam(0, vec!()), Type::Wildcard)))); 
1045
1046        let binding_1 = Type::Template(map_t.id, vec!(number.clone(), Type::Template(map_t.id, vec!(number.clone(), number.clone()))));
1047        let binding_2 = Type::Template(map_t.id, vec!(string.clone(), Type::Template(map_t.id, vec!(string.clone(), string.clone()))));
1048        let binding_3 = Type::Template(map_t.id, vec!(number.clone(), Type::Template(map_t.id, vec!(string.clone(), number.clone()))));
1049        let binding_4 = Type::Template(map_t.id, vec!(number.clone(), Type::Template(map_t.id, vec!(string.clone(), string.clone()))));
1050        let binding_5 = Type::Template(map_t.id, vec!(string.clone(), Type::Template(map_t.id, vec!(string.clone(), number.clone()))));
1051        let binding_6 = Type::Template(map_t.id, vec!(boolean.clone(), Type::Template(map_t.id, vec!(boolean.clone(), number.clone()))));
1052        
1053        assert!(binding_1.bindable_to(&template_1, &ctx));
1054        assert!(binding_2.bindable_to(&template_1, &ctx));
1055        assert!(!binding_3.bindable_to(&template_1, &ctx));
1056        assert!(!binding_4.bindable_to(&template_1, &ctx));
1057        assert!(binding_5.bindable_to(&template_1, &ctx));
1058        assert!(binding_6.bindable_to(&template_1, &ctx));
1059
1060        let template_1 = Type::Template(map_t.id, vec!(Type::TemplateParam(0, vec!()), Type::TemplateParam(1, vec!()))); 
1061        let template_2 = Type::Template(map_t.id, vec!(Type::TemplateParam(1, vec!()), Type::TemplateParam(0, vec!()))); 
1062
1063        assert!(template_1.bindable_to(&template_1, &ctx));
1064        assert!(template_2.bindable_to(&template_2, &ctx));
1065        assert!(!template_1.bindable_to(&template_2, &ctx));
1066        assert!(!template_2.bindable_to(&template_1, &ctx));
1067
1068        let template_1 = Type::Template(map_t.id, vec!(Type::TemplateParam(0, vec!()), Type::Template(map_t.id, vec!(Type::TemplateParam(1, vec!()), Type::TemplateParam(0, vec!()))))); 
1069        let template_2 = Type::Template(map_t.id, vec!(Type::TemplateParam(1, vec!()), Type::Template(map_t.id, vec!(Type::TemplateParam(1, vec!()), Type::TemplateParam(1, vec!()))))); 
1070
1071        assert!(template_1.bindable_to(&template_2, &ctx));
1072        assert!(template_2.bindable_to(&template_1, &ctx));
1073    }
1074
1075    #[test]
1076    fn alias_type_binding() {
1077        let mut ctx = standard_ctx();
1078        let number_id = ctx.type_templates.len();
1079        let number = Type::Basic(number_id);
1080
1081        ctx.define_type(Location::none(), vec!(), "Number".into(), vec!(), vec!(), Some(Type::Or(vec!(INT, FLOAT))), vec!(), None).unwrap();
1082
1083        assert!(INT.bindable_to(&number, &ctx));
1084        assert!(FLOAT.bindable_to(&number, &ctx));
1085        assert!(!STR.bindable_to(&number, &ctx));
1086    }
1087
1088    #[test]
1089    fn recursive_type_binding() {
1090        let mut ctx = standard_ctx();
1091        let list_id = ctx.type_templates.len();
1092        let list = Type::Basic(list_id);
1093
1094        ctx.define_type(Location::none(), vec!(), "List".into(), vec!(), vec!(), Some(Type::Or(vec!(
1095            INT,
1096            Type::And(vec!(INT, list.clone()))
1097        ))), vec!(), None).unwrap();
1098
1099        let tuple_1 = Type::And(vec!(INT, INT));
1100        let tuple_2 = Type::And(vec!(INT, tuple_1.clone()));
1101        let tuple_3 = Type::And(vec!(INT, tuple_2.clone()));
1102        let tuple_4 = Type::And(vec!(INT, FLOAT));
1103        let tuple_5 = Type::And(vec!(INT, tuple_4.clone()));
1104
1105        assert!(INT.bindable_to(&list, &ctx));
1106        assert!(tuple_1.bindable_to(&list, &ctx));
1107        assert!(tuple_2.bindable_to(&list, &ctx));
1108        assert!(tuple_3.bindable_to(&list, &ctx));
1109
1110        assert!(!FLOAT.bindable_to(&list, &ctx));
1111        assert!(!tuple_4.bindable_to(&list, &ctx));
1112        assert!(!tuple_5.bindable_to(&list, &ctx));
1113    }
1114
1115    #[test]
1116    fn parametric_recursive_type_binding() {
1117        let mut ctx = standard_ctx();
1118        let nil_id = ctx.type_templates.len();
1119        let list_id = nil_id + 1;
1120        let nil = Type::Basic(nil_id);
1121        let list = Type::Template(list_id, vec!(T_0));
1122
1123        ctx.define_type(Location::none(), vec!(), "Nil".into(), vec!(), vec!(), None, vec!(), None).unwrap();
1124        ctx.define_type(Location::none(), vec!(), "List".into(), vec!(), vec!(), Some(Type::Or(vec!(
1125            nil.clone(),
1126            Type::And(vec!(T_0, list.clone()))
1127        ))), vec!(), None).unwrap();
1128
1129        let tuple_1 = Type::And(vec!(INT, nil.clone()));
1130        let tuple_2 = Type::And(vec!(INT, tuple_1.clone()));
1131        let tuple_3 = Type::And(vec!(INT, tuple_2.clone()));
1132        let tuple_4 = Type::And(vec!(FLOAT, nil.clone()));
1133        let tuple_5 = Type::And(vec!(FLOAT, tuple_4.clone()));
1134        let tuple_6 = Type::And(vec!(INT, tuple_4.clone()));
1135        let tuple_7 = Type::And(vec!(INT, tuple_6.clone()));
1136
1137        assert!(nil.bindable_to(&list, &ctx));
1138        assert!(tuple_1.bindable_to(&list, &ctx));
1139        assert!(tuple_2.bindable_to(&list, &ctx));
1140        assert!(tuple_3.bindable_to(&list, &ctx));
1141        assert!(tuple_4.bindable_to(&list, &ctx));
1142        assert!(tuple_5.bindable_to(&list, &ctx));
1143        assert!(!tuple_6.bindable_to(&list, &ctx));
1144        assert!(!tuple_7.bindable_to(&list, &ctx));
1145    }
1146}