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