smt_lang/problem/expression/
resolve_expr.rs

1use crate::problem::*;
2
3impl Expr {
4    pub fn resolve(&self, problem: &Problem, entries: &Entries) -> Result<Expr, Error> {
5        match self {
6            Expr::BoolValue(_, _) => Ok(self.clone()),
7            Expr::IntValue(_, _) => Ok(self.clone()),
8            Expr::RealValue(_, _) => Ok(self.clone()),
9            //
10            Expr::Unary(op, kid, position) => {
11                let kid = kid.resolve(problem, entries)?;
12                Ok(Self::Unary(*op, Box::new(kid), position.clone()))
13            }
14            Expr::Binary(left, op, right, position) => {
15                let left = left.resolve(problem, entries)?;
16                let right = right.resolve(problem, entries)?;
17                Ok(Self::Binary(
18                    Box::new(left),
19                    *op,
20                    Box::new(right),
21                    position.clone(),
22                ))
23            }
24            Expr::Nary(op, kids, position) => {
25                let mut v: Vec<Expr> = vec![];
26                for e in kids.iter() {
27                    v.push(e.resolve(problem, entries)?);
28                }
29                Ok(Self::Nary(*op, v, position.clone()))
30            }
31            //
32            Expr::FunctionCall(id, parameters, position) => {
33                let mut v: Vec<Expr> = vec![];
34                for p in parameters.iter() {
35                    v.push(p.resolve(problem, entries)?);
36                }
37                Ok(Self::FunctionCall(*id, v, position.clone()))
38            }
39            //
40            Expr::Variable(_, _) => Ok(self.clone()),
41            Expr::Parameter(_) => Ok(self.clone()),
42            Expr::Instance(_, _) => Ok(self.clone()),
43            Expr::StrucSelf(_, _) => Ok(self.clone()),
44            Expr::StrucAttribute(e, id, pos) => {
45                let e = e.resolve(problem, entries)?;
46                Ok(Expr::StrucAttribute(Box::new(e), *id, pos.clone()))
47            }
48            Expr::StrucMetCall(e, id, args, pos) => {
49                let e = e.resolve(problem, entries)?;
50                let mut v: Vec<Expr> = vec![];
51                for p in args.iter() {
52                    v.push(p.resolve(problem, entries)?);
53                }
54
55                Ok(Expr::StrucMetCall(Box::new(e), *id, v, pos.clone()))
56            }
57            //
58            Expr::ClassSelf(_, _) => Ok(self.clone()),
59            Expr::ClassAttribute(e, id, pos) => {
60                let e = e.resolve(problem, entries)?;
61                Ok(Expr::ClassAttribute(Box::new(e), *id, pos.clone()))
62            }
63            Expr::ClassMetCall(e, id, args, pos) => {
64                let e = e.resolve(problem, entries)?;
65                let mut v: Vec<Expr> = vec![];
66                for p in args.iter() {
67                    v.push(p.resolve(problem, entries)?);
68                }
69
70                Ok(Expr::ClassMetCall(Box::new(e), *id, v, pos.clone()))
71            }
72            Expr::AsClass(e, id) => {
73                let e = e.resolve(problem, entries)?;
74                Ok(Expr::AsClass(Box::new(e), *id))
75            }
76            Expr::AsInterval(e, min, max, pos) => {
77                let e = e.resolve(problem, entries)?;
78                Ok(Expr::AsInterval(Box::new(e), *min, *max, pos.clone()))
79            }
80            Expr::AsInt(e, pos) => {
81                let e = Box::new(e.resolve(problem, entries)?);
82                let pos = pos.clone();
83                Ok(Expr::AsInt(e, pos))
84            }
85            Expr::AsReal(e, pos) => {
86                let e = Box::new(e.resolve(problem, entries)?);
87                let pos = pos.clone();
88                Ok(Expr::AsReal(e, pos))
89            }
90            //
91            Expr::IfThenElse(c, t, l, e, pos) => {
92                let c = c.resolve(problem, entries)?;
93                let t = t.resolve(problem, entries)?;
94                let mut v = Vec::new();
95                for (x, y) in l.iter() {
96                    let x = x.resolve(problem, entries)?;
97                    let y = y.resolve(problem, entries)?;
98                    v.push((x, y));
99                }
100                let e = e.resolve(problem, entries)?;
101                Ok(Expr::IfThenElse(
102                    Box::new(c),
103                    Box::new(t),
104                    v,
105                    Box::new(e),
106                    pos.clone(),
107                ))
108            }
109            Expr::Quantifier(op, p, e, pos) => {
110                let mut entries = entries.clone();
111                for x in p.iter() {
112                    entries = entries.add(Entry::new_parameter(x));
113                }
114                //
115                let p = p.clone();
116                let e = Box::new(e.resolve(problem, &entries)?);
117                let pos = pos.clone();
118                Ok(Expr::Quantifier(*op, p, e, pos))
119            }
120            //
121            Expr::Unresolved(name, position) => match entries.get(&name) {
122                Some(entry) => match entry.typ() {
123                    EntryType::Variable(id) => Ok(Self::Variable(*id, position.clone())),
124                    EntryType::Parameter(p) => Ok(Self::Parameter(p.clone())),
125                    EntryType::Instance(id) => Ok(Expr::Instance(*id, position.clone())),
126                    EntryType::StrucSelf(id) => Ok(Expr::StrucSelf(*id, position.clone())),
127                    EntryType::ClassSelf(id) => Ok(Expr::ClassSelf(*id, position.clone())),
128                },
129                None => Err(Error::Resolve {
130                    category: "identifier".to_string(),
131                    name: name.clone(),
132                    position: position.clone(),
133                }),
134            },
135            Expr::UnresolvedFunCall(name, params, position) => {
136                let mut v: Vec<Expr> = vec![];
137                for p in params.iter() {
138                    v.push(p.resolve(problem, entries)?);
139                }
140                if let Some(function) = problem.find_function(name) {
141                    return Ok(Expr::FunctionCall(function.id(), v, position.clone()));
142                }
143                Err(Error::Resolve {
144                    category: "function".to_string(),
145                    name: name.clone(),
146                    position: position.clone(),
147                })
148            }
149            Expr::UnresolvedAttribute(e, name, pos) => {
150                let e = e.resolve(problem, entries)?;
151                let t = e.typ(problem);
152                if let Type::Structure(id) = t {
153                    if let Some(a) = problem.get(id).unwrap().find_attribute(name) {
154                        Ok(Expr::StrucAttribute(Box::new(e), a.id(), pos.clone()))
155                    } else {
156                        Err(Error::Resolve {
157                            category: format!(
158                                "attibute for type '{}'",
159                                e.typ(problem).to_lang(problem)
160                            ),
161                            name: name.clone(),
162                            position: pos.clone(),
163                        })
164                    }
165                } else if let Type::Class(id) = t {
166                    if let Some(a) = problem.get(id).unwrap().find_all_attribute(problem, name) {
167                        Ok(Expr::ClassAttribute(Box::new(e), a.id(), pos.clone()))
168                    } else {
169                        Err(Error::Resolve {
170                            category: format!(
171                                "attibute for type '{}'",
172                                e.typ(problem).to_lang(problem)
173                            ),
174                            name: name.clone(),
175                            position: pos.clone(),
176                        })
177                    }
178                } else {
179                    panic!("unresolved expr {}", self.to_lang(problem))
180                }
181            }
182            Expr::UnresolvedMethCall(e, name, args, pos) => {
183                let e = e.resolve(problem, entries)?;
184                let mut v: Vec<Expr> = vec![];
185                for p in args.iter() {
186                    v.push(p.resolve(problem, entries)?);
187                }
188                let t = e.typ(problem);
189                if let Type::Structure(id) = t {
190                    if let Some(a) = problem.get(id).unwrap().find_method(name) {
191                        Ok(Expr::StrucMetCall(Box::new(e), a.id(), v, pos.clone()))
192                    } else {
193                        Err(Error::Resolve {
194                            category: format!(
195                                "method for type '{}'",
196                                e.typ(problem).to_lang(problem)
197                            ),
198                            name: name.clone(),
199                            position: pos.clone(),
200                        })
201                    }
202                } else if let Type::Class(id) = t {
203                    if let Some(a) = problem.get(id).unwrap().find_all_method(problem, name) {
204                        Ok(Expr::ClassMetCall(Box::new(e), a.id(), v, pos.clone()))
205                    } else {
206                        Err(Error::Resolve {
207                            category: format!(
208                                "method for type '{}'",
209                                e.typ(problem).to_lang(problem)
210                            ),
211                            name: name.clone(),
212                            position: pos.clone(),
213                        })
214                    }
215                } else {
216                    panic!()
217                }
218            }
219        }
220    }
221}