Om
evaluator.cpp
Go to the documentation of this file.
1 
15 #ifndef Om_Language_Evaluator_
16 
17  #include "om/language/evaluator.hpp"
18 
19 #else
20 
23  #include "om/language/operator.hpp"
25 
26 // MARK: - Om::Language::Evaluator
27 
28  #define Type_ \
29  Om::Language::Evaluator
30 
31 // MARK: public (non-static)
32 
33 inline Type_::~Evaluator() {
34  try {
35  if (
36  !this->IsEmpty()
37  ) {
38  if (this->thisGaveElementToOutput) {
39  this->thisOutput.TakeElement(
40  Separator::GetLineSeparator()
41  );
42  }
43  this->GiveElements(this->thisOutput);
44  }
45  } catch (...) {}
46 }
47 
48 inline Type_::Evaluator(
49  Consumer & theOutput,
50  Translator const & theTranslator
51 ):
52 thisOutput(theOutput),
53 thisTranslator(theTranslator),
54 thisIncompleteOperationVector(),
55 thisGaveElementToOutput() {}
56 
57 inline void Type_::Clear() {
58  this->thisIncompleteOperationVector.clear();
59 }
60 
61 inline Om::Language::Translator const & Type_::GetTranslator() const {
62  return this->thisTranslator;
63 }
64 
65 inline void Type_::GiveElements(Consumer & theConsumer) {
66  this->GiveElements(
67  this->thisIncompleteOperationVector.begin(),
68  this->thisIncompleteOperationVector.end(),
69  theConsumer
70  );
71  this->Clear();
72 }
73 
74 inline void Type_::GiveElements(Consumer & theConsumer) const {
75  this->GiveElements(
76  this->thisIncompleteOperationVector.begin(),
77  this->thisIncompleteOperationVector.end(),
78  theConsumer
79  );
80 }
81 
82 inline std::auto_ptr<Om::Language::Program> Type_::GiveProgram() {
83  return this->GiveProgram(*this);
84 }
85 
86 inline std::auto_ptr<Om::Language::Program> Type_::GiveProgram() const {
87  return this->GiveProgram(*this);
88 }
89 
90 inline bool Type_::IsEmpty() const {
91  return this->thisIncompleteOperationVector.empty();
92 }
93 
94 inline void Type_::ParseElements(Reader & theReader) {
95  this->Parse<
96  Operator,
97  Null
98  >(theReader);
99 }
100 
101 inline void Type_::ParseQuotedElements(Reader & theReader) {
102  Evaluation theEvaluation(*this);
103  this->ParseQuotedElements(
104  theEvaluation,
105  theReader
106  );
107  this->Evaluate(theEvaluation);
108 }
109 
110 inline void Type_::ParseQuotedElements(
111  Evaluation & theEvaluation,
112  Reader & theReader
113 ) {
114  if (
115  this->thisIncompleteOperationVector.empty()
116  ) {
117  this->thisOutput.ParseQuotedElements(theReader);
118  this->thisGaveElementToOutput = true;
119  } else {
120  std::auto_ptr<Operation::IncompleteOperation> theOperation(
121  this->thisIncompleteOperationVector.pop_back().release()
122  );
123  assert(
124  theOperation.get()
125  );
126  if (
127  !theOperation->ParseQuotedElements(
128  theEvaluation,
129  theReader
130  )
131  ) {
132  this->thisIncompleteOperationVector.push_back(theOperation);
133  }
134  }
135 }
136 
137 template <typename TheOperand>
138 inline void Type_::TakeOperand(TheOperand & theOperand) {
139  assert(
140  !theOperand.IsEmpty()
141  );
142  Evaluation theEvaluation(*this);
143  this->TakeOperand(
144  theEvaluation,
145  theOperand
146  );
147  this->Evaluate(theEvaluation);
148 }
149 
150 template <typename TheOperand>
151 inline void Type_::TakeOperand(
152  Evaluation & theEvaluation,
153  TheOperand & theOperand
154 ) {
155  assert(
156  !theOperand.IsEmpty()
157  );
158  if (
159  this->thisIncompleteOperationVector.empty()
160  ) {
161  this->thisOutput.TakeElement(theOperand);
162  this->thisGaveElementToOutput = true;
163  } else {
164  std::auto_ptr<Operation::IncompleteOperation> theOperation(
165  this->thisIncompleteOperationVector.pop_back().release()
166  );
167  assert(
168  theOperation.get()
169  );
170  if (
171  !theOperation->TakeElement(
172  theEvaluation,
173  theOperand
174  )
175  ) {
176  this->thisIncompleteOperationVector.push_back(theOperation);
177  }
178  }
179 }
180 
181 template <typename TheOperation>
182 inline void Type_::TakeOperation(
183  std::auto_ptr<TheOperation> theOperation
184 ) {
185  this->thisIncompleteOperationVector.push_back(theOperation);
186 }
187 
188 template <typename TheOperator>
189 inline void Type_::TakeOperator(TheOperator & theOperator) {
190  Evaluation theEvaluation(*this);
191  this->TakeOperator(
192  theEvaluation,
193  theOperator
194  );
195  this->Evaluate(theEvaluation);
196 }
197 
198 template <typename TheOperator>
199 inline void Type_::TakeOperator(
200  Evaluation & theEvaluation,
201  TheOperator & theOperator
202 ) {
203  assert(
204  !theOperator.IsEmpty()
205  );
206  if (
207  !this->thisTranslator.Translate(
208  theEvaluation,
209  theOperator
210  ) &&
211  !this->thisTranslator.Translate(
212  theEvaluation,
213  Operator()
214  )
215  ) {
216  if (this->thisGaveElementToOutput) {
217  this->thisOutput.TakeElement(
218  Separator::GetLineSeparator()
219  );
220  }
221 
222  if (
223  !this->IsEmpty()
224  ) {
225  this->GiveElements(this->thisOutput);
226  this->thisOutput.TakeElement(
227  Separator::GetLineSeparator()
228  );
229  }
230 
231  this->thisOutput.TakeElement(theOperator);
232  this->thisGaveElementToOutput = true;
233  }
234 }
235 
236 template <typename TheProducer>
237 inline void Type_::TakeQuotedProducer(TheProducer & theProducer) {
238  Evaluation theEvaluation(*this);
239  this->TakeQuotedProducer(
240  theEvaluation,
241  theProducer
242  );
243  this->Evaluate(theEvaluation);
244 }
245 
246 template <typename TheProducer>
247 inline void Type_::TakeQuotedProducer(
248  Evaluation & theEvaluation,
249  TheProducer & theProducer
250 ) {
251  if (
252  this->thisIncompleteOperationVector.empty()
253  ) {
254  this->thisOutput.TakeQuotedElements(theProducer);
255  this->thisGaveElementToOutput = true;
256  } else {
257  std::auto_ptr<Operation::IncompleteOperation> theOperation(
258  this->thisIncompleteOperationVector.pop_back().release()
259  );
260  assert(
261  theOperation.get()
262  );
263  if (
264  !theOperation->TakeQuotedElements(
265  theEvaluation,
266  theProducer
267  )
268  ) {
269  this->thisIncompleteOperationVector.push_back(theOperation);
270  }
271  }
272 }
273 
274 template <typename TheSeparator>
275 inline void Type_::TakeSeparator(TheSeparator &) {}
276 
277 // MARK: private (static)
278 
279 template <typename TheIterator>
280 inline void Type_::GiveElements(
281  TheIterator theCurrent,
282  TheIterator const theEnd,
283  Consumer & theConsumer
284 ) {
285  if (theEnd != theCurrent) {
286  for (
287  ;
288  ;
289  theConsumer.TakeElement(
290  Separator::GetLineSeparator()
291  )
292  ) {
293  theCurrent->GiveElements(theConsumer);
294  if (theEnd == ++theCurrent) {
295  return;
296  }
297  }
298  }
299 }
300 
301 template <typename TheEvaluator>
302 inline std::auto_ptr<Om::Language::Program> Type_::GiveProgram(TheEvaluator & theEvaluator) {
303  std::auto_ptr<Program> theExpression(new Expression);
304  assert(
305  theExpression.get()
306  );
307  theEvaluator.GiveElements(*theExpression);
308  return theExpression;
309 }
310 
311 // MARK: private (non-static)
312 
313 inline void Type_::Evaluate(Evaluation & theEvaluation) {
314  while (
315  theEvaluation.GiveTerm(*this)
316  ) {}
317 }
318 
319  #undef Type_
320 
321 #endif
An Operator lookup for use by an Evaluator.
Definition: translator.hpp:62
Om header file.
Om header file.
Om header file.
Om header file.