ryna/
interfaces.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use colored::Colorize;
use serde::{Serialize, Deserialize};

use 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};

pub type InterfaceFunctionHeader = (Vec<Annotation>, String, Option<Vec<String>>, Vec<(String, Type)>, Type);
pub type InterfaceUnaryOpHeader = (Vec<Annotation>, usize, Vec<String>, String, Type, Type);
pub type InterfaceBinaryOpHeader = (Vec<Annotation>, usize, Vec<String>, (String, Type), (String, Type), Type);
pub type InterfaceNaryOpHeader = (Vec<Annotation>, usize, Vec<String>, (String, Type), Vec<(String, Type)>, Type);

#[derive(Clone, Serialize, Deserialize)]
pub struct Interface {
    pub id: usize,
    pub name: String,
    pub params: Vec<String>,
    pub location: Location,
    pub annotations: Vec<Annotation>,
    pub fns: Vec<InterfaceFunctionHeader>,
    pub uns: Vec<InterfaceUnaryOpHeader>,
    pub bin: Vec<InterfaceBinaryOpHeader>,
    pub nary: Vec<InterfaceNaryOpHeader>
}

#[derive(Clone, Serialize, Deserialize)]
pub struct InterfaceImpl {
    pub interface_id: usize,
    pub args: Vec<Type>,
    pub interface_type: Type
}

#[derive(Clone, Hash, Debug, PartialEq, Serialize, Deserialize)]
pub struct InterfaceConstraint {
    pub id: usize,
    pub args: Vec<Type>
}

impl InterfaceConstraint {
    pub fn new(id: usize, args: Vec<Type>) -> InterfaceConstraint {
        InterfaceConstraint {
            id,
            args
        }
    }
}

impl InterfaceConstraint {
    pub fn get_name(&self, ctx: &RynaContext) -> String {
        if !self.args.is_empty() {
            format!(
                "{}<{}>", 
                ctx.interfaces[self.id].name.green(),
                self.args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
            )

        } else {
            format!("{}", ctx.interfaces[self.id].name.green())
        }
    }

    pub fn get_name_html(&self, ctx: &RynaContext) -> String {
        if !self.args.is_empty() {
            format!(
                "{}&lt;{}&gt;", 
                ctx.interfaces[self.id].name.html_green(),
                self.args.iter().map(|i| i.get_name_html(ctx)).collect::<Vec<_>>().join(", ")
            )

        } else {
            format!("{}", ctx.interfaces[self.id].name.green())
        }
    }

    pub fn get_name_plain(&self, ctx: &RynaContext) -> String {
        if !self.args.is_empty() {
            format!(
                "{}<{}>", 
                ctx.interfaces[self.id].name,
                self.args.iter().map(|i| i.get_name_plain(ctx)).collect::<Vec<_>>().join(", ")
            )

        } else {
            ctx.interfaces[self.id].name.to_string()
        }
    }
}

/*
                                                  ╒═══════════════════════╕
    ============================================= │  STANDARD INTERFACES  │ =============================================
                                                  ╘══════════════════════=╛
*/

// Constants for common interfaces
pub const ITERABLE_ID: usize = 0;
pub const PRINTABLE_ID: usize = 1;

pub const PRINTABLE: InterfaceConstraint = InterfaceConstraint { id: PRINTABLE_ID, args: vec!() };

#[macro_export]
macro_rules! ITERABLE_OF { ($t: expr) => { InterfaceConstraint::new($t) }; }

// Standard context
pub fn standard_interfaces(ctx: &mut RynaContext) {
    
    // Definitions
    ctx.define_interface(Location::none(), vec!(), "Iterable".into(), vec!("Iter".into(), "Elem".into()), vec!(
        (vec!(), "iterator".into(), None, vec!(("".into(), Type::SelfType)), T_0),
        (vec!(), "next".into(), None, vec!(("".into(), T_0.to_mut())), T_1),
        (vec!(), "is_consumed".into(), None, vec!(("".into(), T_0.to_mut())), BOOL)        
    ), vec!(), vec!(), vec!()).unwrap();

    ctx.define_interface(Location::none(), vec!(), "Printable".into(), vec!(), vec!(
        (vec!(), "print".into(), None, vec!(("".into(), Type::SelfType)), Type::Empty)
    ), vec!(), vec!(), vec!()).unwrap();

    ctx.define_interface(Location::none(), vec!(), "Destroyable".into(), vec!(), vec!(
        (vec!(), "destroy".into(), None, vec!(("".into(), Type::SelfType.to_ref())), Type::Empty)
    ), vec!(), vec!(), vec!()).unwrap();

    // Implementations
    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();
    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();
    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();

    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();
    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();

    ctx.define_interface_impl("Printable".into(), vec!(), BOOL, vec!()).unwrap();
    ctx.define_interface_impl("Printable".into(), vec!(), INT, vec!()).unwrap();
    ctx.define_interface_impl("Printable".into(), vec!(), FLOAT, vec!()).unwrap();
    ctx.define_interface_impl("Printable".into(), vec!(), STR, vec!()).unwrap();
    ctx.define_interface_impl("Printable".into(), vec!(), BOOL.to_ref().or(BOOL.to_mut()), vec!()).unwrap();
    ctx.define_interface_impl("Printable".into(), vec!(), INT.to_ref().or(INT.to_mut()), vec!()).unwrap();
    ctx.define_interface_impl("Printable".into(), vec!(), FLOAT.to_ref().or(FLOAT.to_mut()), vec!()).unwrap();
    ctx.define_interface_impl("Printable".into(), vec!(), STR.to_ref().or(STR.to_mut()), vec!()).unwrap();
}