smt_lang/problem/
method.rs

1use super::*;
2use crate::parser::Position;
3
4//------------------------- Id -------------------------
5
6#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
7pub struct MethodId<T: Id>(pub T, pub usize);
8
9impl<T: Id> Id for MethodId<T> {
10    fn empty() -> Self {
11        Self(T::empty(), 0)
12    }
13}
14
15//------------------------- Method -------------------------
16
17#[derive(Clone)]
18pub struct Method<T: Id> {
19    id: MethodId<T>,
20    name: String,
21    parameters: Vec<Parameter>,
22    typ: Type,
23    expr: Option<Expr>,
24    position: Option<Position>,
25}
26
27impl<T: Id> Method<T> {
28    pub fn new<S: Into<String>>(
29        name: S,
30        typ: Type,
31        expr: Option<Expr>,
32        position: Option<Position>,
33    ) -> Self {
34        let id = MethodId::empty();
35        let name = name.into();
36        Self {
37            id,
38            name,
39            parameters: vec![],
40            typ,
41            expr,
42            position,
43        }
44    }
45
46    //---------- Parameter ----------
47
48    pub fn add_parameter(&mut self, parameter: Parameter) {
49        self.parameters.push(parameter);
50    }
51
52    pub fn parameters(&self) -> &Vec<Parameter> {
53        &self.parameters
54    }
55
56    pub fn parameters_type(&self) -> Vec<Type> {
57        self.parameters.iter().map(|p| p.typ().clone()).collect()
58    }
59
60    //---------- Duplicate ----------
61
62    pub fn duplicate(&self) -> Result<(), Error> {
63        for i in 0..self.parameters.len() - 1 {
64            let x = &self.parameters[i];
65            for j in i + 1..self.parameters.len() {
66                let y = &self.parameters[j];
67                if x.name() == y.name() {
68                    return Err(Error::Duplicate {
69                        name: x.name().to_string(),
70                        first: x.position().clone(),
71                        second: y.position().clone(),
72                    });
73                }
74            }
75        }
76        Ok(())
77    }
78
79    //---------- Bounded ----------
80
81    pub fn check_bounded(&self, problem: &Problem) -> Result<(), Error> {
82        for p in self.parameters.iter() {
83            p.check_bounded(problem)?;
84        }
85        Ok(())
86    }
87
88    //---------- Resolve ----------
89
90    pub fn resolve_type_expr(&mut self, entries: &TypeEntries) -> Result<(), Error> {
91        if let Some(expr) = &self.expr {
92            let e = expr.resolve_type(entries)?;
93            self.expr = Some(e);
94        }
95        Ok(())
96    }
97}
98
99//------------------------- Postion -------------------------
100
101impl<T: Id> WithPosition for Method<T> {
102    fn position(&self) -> &Option<Position> {
103        &self.position
104    }
105}
106
107//------------------------- Named -------------------------
108
109impl<T: Id> Named<MethodId<T>> for Method<T> {
110    fn id(&self) -> MethodId<T> {
111        self.id
112    }
113
114    fn set_id(&mut self, id: MethodId<T>) {
115        self.id = id;
116    }
117
118    fn name(&self) -> &str {
119        &self.name
120    }
121}
122
123//------------------------- With Type -------------------------
124
125impl<T: Id> WithType for Method<T> {
126    fn typ(&self) -> &Type {
127        &self.typ
128    }
129
130    fn set_type(&mut self, typ: Type) {
131        self.typ = typ;
132    }
133
134    fn resolve_type_children(&mut self, entries: &TypeEntries) -> Result<(), Error> {
135        for p in self.parameters.iter_mut() {
136            p.resolve_type(entries)?;
137        }
138        Ok(())
139    }
140
141    fn check_interval_children(&self, problem: &Problem) -> Result<(), Error> {
142        for p in self.parameters.iter() {
143            p.check_interval(problem)?;
144        }
145        Ok(())
146    }
147}
148
149//------------------------- With Expr -------------------------
150
151impl WithExpr for Method<StructureId> {
152    fn expr(&self) -> &Option<Expr> {
153        &self.expr
154    }
155
156    fn set_expr(&mut self, expr: Option<Expr>) {
157        self.expr = expr;
158    }
159
160    fn entries(&self) -> Entries {
161        let mut v = Vec::new();
162        for p in self.parameters.iter() {
163            v.push(Entry::new(
164                p.name().to_string(),
165                EntryType::Parameter(p.clone()),
166            ));
167        }
168        let MethodId(structure_id, _) = self.id();
169        v.push(Entry::new(
170            "self".to_string(),
171            EntryType::StrucSelf(structure_id),
172        ));
173        Entries::new(v)
174    }
175}
176
177impl WithExpr for Method<ClassId> {
178    fn expr(&self) -> &Option<Expr> {
179        &self.expr
180    }
181
182    fn set_expr(&mut self, expr: Option<Expr>) {
183        self.expr = expr;
184    }
185
186    fn entries(&self) -> Entries {
187        let mut v = Vec::new();
188        for p in self.parameters.iter() {
189            v.push(Entry::new(
190                p.name().to_string(),
191                EntryType::Parameter(p.clone()),
192            ));
193        }
194        let MethodId(class_id, _) = self.id();
195        v.push(Entry::new(
196            "self".to_string(),
197            EntryType::ClassSelf(class_id),
198        ));
199        Entries::new(v)
200    }
201}
202
203//------------------------- ToLang -------------------------
204
205impl<T: Id> ToLang for Method<T> {
206    fn to_lang(&self, problem: &Problem) -> String {
207        let mut s = format!("    {}(", self.name());
208        if !self.parameters.is_empty() {
209            s.push_str(&format!(
210                "{}",
211                self.parameters.first().unwrap().to_lang(problem)
212            ));
213            for p in self.parameters[1..].iter() {
214                s.push_str(&format!(", {}", p.to_lang(problem)));
215            }
216        }
217        s.push_str(&format!("): {}", self.typ.to_lang(problem)));
218        if let Some(e) = &self.expr {
219            s.push_str(&format!(" = {}", e.to_lang(problem)));
220        }
221        s
222    }
223}