smt_lang/problem/
method.rs1use super::*;
2use crate::parser::Position;
3
4#[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#[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 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 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 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 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
99impl<T: Id> WithPosition for Method<T> {
102 fn position(&self) -> &Option<Position> {
103 &self.position
104 }
105}
106
107impl<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
123impl<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
149impl 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
203impl<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}