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
18pub 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,
65
66 InferenceMarker,
68
69 SelfType,
71
72 Basic(usize),
74
75 Ref(Box<Type>),
77 MutRef(Box<Type>),
78
79 Or(Vec<Type>),
81 And(Vec<Type>),
82
83 Wildcard,
85 TemplateParam(usize, Vec<InterfaceConstraint>),
86 TemplateParamStr(String, Vec<InterfaceConstraint>),
87 Template(usize, Vec<Type>),
88
89 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!("{}<{}>", 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 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) { 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)"); }
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
743pub 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
774pub 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#[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}