1use colored::Colorize;
2use serde::{Serialize, Deserialize};
3
4use crate::{annotations::Annotation, context::RynaContext, html_ext::HTMLColorable, parser::Location, types::{Type, BOOL, FLOAT, INT, STR, T_0, T_1, T_2}, ARR_IT_OF, ARR_OF};
5
6pub type InterfaceFunctionHeader = (Vec<Annotation>, String, Option<Vec<String>>, Vec<(String, Type)>, Type);
7pub type InterfaceUnaryOpHeader = (Vec<Annotation>, usize, Vec<String>, String, Type, Type);
8pub type InterfaceBinaryOpHeader = (Vec<Annotation>, usize, Vec<String>, (String, Type), (String, Type), Type);
9pub type InterfaceNaryOpHeader = (Vec<Annotation>, usize, Vec<String>, (String, Type), Vec<(String, Type)>, Type);
10
11#[derive(Clone, Serialize, Deserialize)]
12pub struct Interface {
13 pub id: usize,
14 pub name: String,
15 pub params: Vec<String>,
16 pub location: Location,
17 pub annotations: Vec<Annotation>,
18 pub fns: Vec<InterfaceFunctionHeader>,
19 pub uns: Vec<InterfaceUnaryOpHeader>,
20 pub bin: Vec<InterfaceBinaryOpHeader>,
21 pub nary: Vec<InterfaceNaryOpHeader>
22}
23
24#[derive(Clone, Serialize, Deserialize)]
25pub struct InterfaceImpl {
26 pub interface_id: usize,
27 pub args: Vec<Type>,
28 pub interface_type: Type
29}
30
31#[derive(Clone, Hash, Debug, PartialEq, Serialize, Deserialize)]
32pub struct InterfaceConstraint {
33 pub id: usize,
34 pub args: Vec<Type>
35}
36
37impl InterfaceConstraint {
38 pub fn new(id: usize, args: Vec<Type>) -> InterfaceConstraint {
39 InterfaceConstraint {
40 id,
41 args
42 }
43 }
44}
45
46impl InterfaceConstraint {
47 pub fn get_name(&self, ctx: &RynaContext) -> String {
48 if !self.args.is_empty() {
49 format!(
50 "{}<{}>",
51 ctx.interfaces[self.id].name.green(),
52 self.args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
53 )
54
55 } else {
56 format!("{}", ctx.interfaces[self.id].name.green())
57 }
58 }
59
60 pub fn get_name_html(&self, ctx: &RynaContext) -> String {
61 if !self.args.is_empty() {
62 format!(
63 "{}<{}>",
64 ctx.interfaces[self.id].name.html_green(),
65 self.args.iter().map(|i| i.get_name_html(ctx)).collect::<Vec<_>>().join(", ")
66 )
67
68 } else {
69 format!("{}", ctx.interfaces[self.id].name.green())
70 }
71 }
72
73 pub fn get_name_plain(&self, ctx: &RynaContext) -> String {
74 if !self.args.is_empty() {
75 format!(
76 "{}<{}>",
77 ctx.interfaces[self.id].name,
78 self.args.iter().map(|i| i.get_name_plain(ctx)).collect::<Vec<_>>().join(", ")
79 )
80
81 } else {
82 ctx.interfaces[self.id].name.to_string()
83 }
84 }
85}
86
87pub const ITERABLE_ID: usize = 0;
95pub const PRINTABLE_ID: usize = 1;
96
97pub const PRINTABLE: InterfaceConstraint = InterfaceConstraint { id: PRINTABLE_ID, args: vec!() };
98
99#[macro_export]
100macro_rules! ITERABLE_OF { ($t: expr) => { InterfaceConstraint::new($t) }; }
101
102pub fn standard_interfaces(ctx: &mut RynaContext) {
104
105 ctx.define_interface(Location::none(), vec!(), "Iterable".into(), vec!("Iter".into(), "Elem".into()), vec!(
107 (vec!(), "iterator".into(), None, vec!(("".into(), Type::SelfType)), T_0),
108 (vec!(), "next".into(), None, vec!(("".into(), T_0.to_mut())), T_1),
109 (vec!(), "is_consumed".into(), None, vec!(("".into(), T_0.to_mut())), BOOL)
110 ), vec!(), vec!(), vec!()).unwrap();
111
112 ctx.define_interface(Location::none(), vec!(), "Printable".into(), vec!(), vec!(
113 (vec!(), "print".into(), None, vec!(("".into(), Type::SelfType)), Type::Empty)
114 ), vec!(), vec!(), vec!()).unwrap();
115
116 ctx.define_interface(Location::none(), vec!(), "Destroyable".into(), vec!(), vec!(
117 (vec!(), "destroy".into(), None, vec!(("".into(), Type::SelfType.to_ref())), Type::Empty)
118 ), vec!(), vec!(), vec!()).unwrap();
119
120 ctx.define_interface_impl("Iterable".into(), vec!("T".into()), ARR_OF!(T_2), vec!(ARR_IT_OF!(T_2, T_2.to_mut()), T_2.to_mut())).unwrap();
122 ctx.define_interface_impl("Iterable".into(), vec!("T".into()), ARR_OF!(T_2).to_ref(), vec!(ARR_IT_OF!(T_2, T_2.to_ref()), T_2.to_ref())).unwrap();
123 ctx.define_interface_impl("Iterable".into(), vec!("T".into()), ARR_OF!(T_2).to_mut(), vec!(ARR_IT_OF!(T_2, T_2.to_mut()), T_2.to_mut())).unwrap();
124
125 ctx.define_interface_impl("Iterable".into(), vec!("T".into()), ARR_IT_OF!(T_2, T_2.to_mut()), vec!(ARR_IT_OF!(T_2, T_2.to_mut()), T_2.to_mut())).unwrap();
126 ctx.define_interface_impl("Iterable".into(), vec!("T".into()), ARR_IT_OF!(T_2, T_2.to_ref()), vec!(ARR_IT_OF!(T_2, T_2.to_ref()), T_2.to_ref())).unwrap();
127
128 ctx.define_interface_impl("Printable".into(), vec!(), BOOL, vec!()).unwrap();
129 ctx.define_interface_impl("Printable".into(), vec!(), INT, vec!()).unwrap();
130 ctx.define_interface_impl("Printable".into(), vec!(), FLOAT, vec!()).unwrap();
131 ctx.define_interface_impl("Printable".into(), vec!(), STR, vec!()).unwrap();
132 ctx.define_interface_impl("Printable".into(), vec!(), BOOL.to_ref().or(BOOL.to_mut()), vec!()).unwrap();
133 ctx.define_interface_impl("Printable".into(), vec!(), INT.to_ref().or(INT.to_mut()), vec!()).unwrap();
134 ctx.define_interface_impl("Printable".into(), vec!(), FLOAT.to_ref().or(FLOAT.to_mut()), vec!()).unwrap();
135 ctx.define_interface_impl("Printable".into(), vec!(), STR.to_ref().or(STR.to_mut()), vec!()).unwrap();
136}