ryna/
interfaces.rs

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                "{}&lt;{}&gt;", 
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
87/*
88                                                  ╒═══════════════════════╕
89    ============================================= │  STANDARD INTERFACES  │ =============================================
90                                                  ╘══════════════════════=╛
91*/
92
93// Constants for common interfaces
94pub 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
102// Standard context
103pub fn standard_interfaces(ctx: &mut RynaContext) {
104    
105    // Definitions
106    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    // Implementations
121    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}