]> git.mxchange.org Git - simgear.git/blob - simgear/structure/SGExpression.cxx
Merge branch 'ehofman/framebuffer'
[simgear.git] / simgear / structure / SGExpression.cxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2006-2007 Mathias Froehlich 
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include <simgear_config.h>
24 #endif
25
26 #include "SGExpression.hxx"
27 #include "Singleton.hxx"
28
29 #include <algorithm>
30 #include <functional>
31 #include <map>
32 #include <utility>
33 #include <string>
34 #include <sstream>
35 #include <boost/bind.hpp>
36
37 #include <simgear/props/props.hxx>
38
39 using namespace std;
40
41 namespace simgear
42 {
43 template<typename T>
44 const expression::Value evalValue(const Expression* exp,
45                                   const expression::Binding* b)
46 {
47     T val;
48     static_cast<const SGExpression<T>*>(exp)->eval(val, b);
49     return expression::Value(val);
50 }
51
52 const expression::Value eval(const Expression* exp,
53                              const expression::Binding* b)
54 {
55     using namespace expression;
56     switch (exp->getType()) {
57     case BOOL:
58         return evalValue<bool>(exp, b);
59     case INT:
60         return evalValue<int>(exp, b);
61     case FLOAT:
62         return evalValue<float>(exp, b);
63     case DOUBLE:
64         return evalValue<double>(exp, b);
65     default:
66         throw "invalid type.";
67     }
68 }
69 }
70
71 template<typename T>
72 static bool
73 SGReadValueFromString(const char* str, T& value)
74 {
75     if (!str) {
76         SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
77         return false;
78     }
79     std::stringstream s;
80     s.str(std::string(str));
81     s >> value;
82     if (s.fail()) {
83         SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
84         return false;
85     }
86     return true;
87 }
88
89 template<>
90 bool
91 SGReadValueFromString(const char* str, bool& value)
92 {
93     if (!str) {
94         SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
95         return false;
96     }
97     std::stringstream s;
98     s.str(std::string(str));
99     s >> value;
100     if (!s.fail())
101         return true;
102
103     std::string stdstr;
104     if (!SGReadValueFromString(str, stdstr))
105         return false;
106
107     if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
108         value = true;
109         return true;
110     }
111     if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
112         value = true;
113         return true;
114     }
115     return false;
116 }
117
118 template<typename T>
119 static bool
120 SGReadValueFromContent(const SGPropertyNode *node, T& value)
121 {
122     if (!node)
123         return false;
124     return SGReadValueFromString(node->getStringValue(), value);
125 }
126
127 template<typename T>
128 static SGExpression<T>*
129 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
130
131 template<typename T>
132 static bool
133 SGReadNaryOperands(SGNaryExpression<T>* nary,
134                    SGPropertyNode *inputRoot, const SGPropertyNode *expression)
135 {
136     for (int i = 0; i < expression->nChildren(); ++i) {
137         SGExpression<T>* inputExpression;
138         inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
139         if (!inputExpression)
140             return false;
141         nary->addOperand(inputExpression);
142     }
143     return true;
144 }
145
146 // template<typename T>
147 // static SGExpression<T>*
148 // SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
149 // {
150 //   if (!expression)
151 //     return 0;
152
153 //   std::string name = expression->getName();
154 //   if (name == "value") {
155 //     T value;
156 //     if (!SGReadValueFromContent(expression, value)) {
157 //       SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
158 //       return 0;
159 //     }
160 //     return new SGConstExpression<T>(value);
161 //   }
162
163 //   return 0;
164 // }
165
166 template<typename T>
167 static SGExpression<T>*
168 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
169 {
170     if (!expression)
171         return 0;
172
173     std::string name = expression->getName();
174     if (name == "value") {
175         T value;
176         if (!SGReadValueFromContent(expression, value)) {
177             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
178             return 0;
179         }
180         return new SGConstExpression<T>(value);
181     }
182
183     if (name == "property") {
184         if (!inputRoot) {
185             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
186                    "No inputRoot argument given!");
187             return 0;
188         }
189         if (!expression->getStringValue()) {
190             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
191             return 0;
192         }
193         SGPropertyNode* inputNode;
194         inputNode = inputRoot->getNode(expression->getStringValue(), true);
195         return new SGPropertyExpression<T>(inputNode);
196     }
197
198     if (name == "abs" || name == "fabs") {
199         if (expression->nChildren() != 1) {
200             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
201             return 0;
202         }
203         SGSharedPtr<SGExpression<T> > inputExpression;
204         inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
205         if (!inputExpression) {
206             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
207             return 0;
208         }
209         return new SGAbsExpression<T>(inputExpression);
210     }
211
212     if (name == "sqr") {
213         if (expression->nChildren() != 1) {
214             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
215             return 0;
216         }
217         SGSharedPtr<SGExpression<T> > inputExpression;
218         inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
219         if (!inputExpression) {
220             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
221             return 0;
222         }
223         return new SGSqrExpression<T>(inputExpression);
224     }
225
226     if (name == "clip") {
227         if (expression->nChildren() != 3) {
228             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
229             return 0;
230         }
231         const SGPropertyNode* minProperty = expression->getChild("clipMin");
232         T clipMin;
233         if (!SGReadValueFromContent(minProperty, clipMin))
234             clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
235
236         const SGPropertyNode* maxProperty = expression->getChild("clipMax");
237         T clipMax;
238         if (!SGReadValueFromContent(maxProperty, clipMax))
239             clipMin = SGLimits<T>::max();
240
241         SGSharedPtr<SGExpression<T> > inputExpression;
242         for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
243             inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
244         if (!inputExpression) {
245             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
246             return 0;
247         }
248         return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
249     }
250
251     if (name == "div") {
252         if (expression->nChildren() != 2) {
253             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
254             return 0;
255         }
256         SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
257             SGReadIExpression<T>(inputRoot, expression->getChild(0)),
258             SGReadIExpression<T>(inputRoot, expression->getChild(1))
259         };
260         if (!inputExpressions[0] || !inputExpressions[1]) {
261             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
262             return 0;
263         }
264         return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
265     }
266     if (name == "mod") {
267         if (expression->nChildren() != 2) {
268             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
269             return 0;
270         }
271         SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
272             SGReadIExpression<T>(inputRoot, expression->getChild(0)),
273             SGReadIExpression<T>(inputRoot, expression->getChild(1))
274         };
275         if (!inputExpressions[0] || !inputExpressions[1]) {
276             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
277             return 0;
278         }
279         return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
280     }
281
282     if (name == "sum") {
283         if (expression->nChildren() < 1) {
284             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
285             return 0;
286         }
287         SGSumExpression<T>* output = new SGSumExpression<T>;
288         if (!SGReadNaryOperands(output, inputRoot, expression)) {
289             delete output;
290             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
291             return 0;
292         }
293         return output;
294     }
295     if (name == "prod" || name == "product") {
296         if (expression->nChildren() < 1) {
297             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
298             return 0;
299         }
300         SGProductExpression<T>* output = new SGProductExpression<T>;
301         if (!SGReadNaryOperands(output, inputRoot, expression)) {
302             delete output;
303             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
304             return 0;
305         }
306         return output;
307     }
308     if (name == "min") {
309         if (expression->nChildren() < 1) {
310             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
311             return 0;
312         }
313         SGMinExpression<T>* output = new SGMinExpression<T>;
314         if (!SGReadNaryOperands(output, inputRoot, expression)) {
315             delete output;
316             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
317             return 0;
318         }
319         return output;
320     }
321     if (name == "max") {
322         if (expression->nChildren() < 1) {
323             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
324             return 0;
325         }
326         SGMaxExpression<T>* output = new SGMaxExpression<T>;
327         if (!SGReadNaryOperands(output, inputRoot, expression)) {
328             delete output;
329             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
330             return 0;
331         }
332         return output;
333     }
334
335     return 0;
336 }
337
338
339 template<typename T>
340 static SGExpression<T>*
341 SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
342 {
343     SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
344     if (r)
345         return r;
346
347     if (!expression)
348         return 0;
349
350     std::string name = expression->getName();
351     if (name == "acos") {
352         if (expression->nChildren() != 1) {
353             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
354             return 0;
355         }
356         SGSharedPtr<SGExpression<T> > inputExpression;
357         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
358         if (!inputExpression) {
359             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
360             return 0;
361         }
362         return new SGACosExpression<T>(inputExpression);
363     }
364
365     if (name == "asin") {
366         if (expression->nChildren() != 1) {
367             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
368             return 0;
369         }
370         SGSharedPtr<SGExpression<T> > inputExpression;
371         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
372         if (!inputExpression) {
373             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
374             return 0;
375         }
376         return new SGASinExpression<T>(inputExpression);
377     }
378
379     if (name == "atan") {
380         if (expression->nChildren() != 1) {
381             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
382             return 0;
383         }
384         SGSharedPtr<SGExpression<T> > inputExpression;
385         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
386         if (!inputExpression) {
387             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
388             return 0;
389         }
390         return new SGATanExpression<T>(inputExpression);
391     }
392
393     if (name == "ceil") {
394         if (expression->nChildren() != 1) {
395             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
396             return 0;
397         }
398         SGSharedPtr<SGExpression<T> > inputExpression;
399         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
400         if (!inputExpression) {
401             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
402             return 0;
403         }
404         return new SGCeilExpression<T>(inputExpression);
405     }
406
407     if (name == "cos") {
408         if (expression->nChildren() != 1) {
409             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
410             return 0;
411         }
412         SGSharedPtr<SGExpression<T> > inputExpression;
413         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
414         if (!inputExpression) {
415             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
416             return 0;
417         }
418         return new SGCosExpression<T>(inputExpression);
419     }
420
421     if (name == "cosh") {
422         if (expression->nChildren() != 1) {
423             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
424             return 0;
425         }
426         SGSharedPtr<SGExpression<T> > inputExpression;
427         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
428         if (!inputExpression) {
429             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
430             return 0;
431         }
432         return new SGCoshExpression<T>(inputExpression);
433     }
434
435     if (name == "deg2rad") {
436         if (expression->nChildren() != 1) {
437             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
438             return 0;
439         }
440         SGSharedPtr<SGExpression<T> > inputExpression;
441         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
442         if (!inputExpression) {
443             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
444             return 0;
445         }
446         return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
447     }
448
449     if (name == "exp") {
450         if (expression->nChildren() != 1) {
451             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
452             return 0;
453         }
454         SGSharedPtr<SGExpression<T> > inputExpression;
455         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
456         if (!inputExpression) {
457             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
458             return 0;
459         }
460         return new SGExpExpression<T>(inputExpression);
461     }
462
463     if (name == "floor") {
464         if (expression->nChildren() != 1) {
465             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
466             return 0;
467         }
468         SGSharedPtr<SGExpression<T> > inputExpression;
469         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
470         if (!inputExpression) {
471             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
472             return 0;
473         }
474         return new SGFloorExpression<T>(inputExpression);
475     }
476
477     if (name == "log") {
478         if (expression->nChildren() != 1) {
479             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
480             return 0;
481         }
482         SGSharedPtr<SGExpression<T> > inputExpression;
483         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
484         if (!inputExpression) {
485             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
486             return 0;
487         }
488         return new SGLogExpression<T>(inputExpression);
489     }
490
491     if (name == "log10") {
492         if (expression->nChildren() != 1) {
493             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
494             return 0;
495         }
496         SGSharedPtr<SGExpression<T> > inputExpression;
497         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
498         if (!inputExpression) {
499             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
500             return 0;
501         }
502         return new SGLog10Expression<T>(inputExpression);
503     }
504
505     if (name == "rad2deg") {
506         if (expression->nChildren() != 1) {
507             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
508             return 0;
509         }
510         SGSharedPtr<SGExpression<T> > inputExpression;
511         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
512         if (!inputExpression) {
513             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
514             return 0;
515         }
516         return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
517     }
518
519     if (name == "sin") {
520         if (expression->nChildren() != 1) {
521             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
522             return 0;
523         }
524         SGSharedPtr<SGExpression<T> > inputExpression;
525         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
526         if (!inputExpression) {
527             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
528             return 0;
529         }
530         return new SGSinExpression<T>(inputExpression);
531     }
532
533     if (name == "sinh") {
534         if (expression->nChildren() != 1) {
535             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
536             return 0;
537         }
538         SGSharedPtr<SGExpression<T> > inputExpression;
539         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
540         if (!inputExpression) {
541             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
542             return 0;
543         }
544         return new SGSinhExpression<T>(inputExpression);
545     }
546
547     if (name == "sqrt") {
548         if (expression->nChildren() != 1) {
549             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
550             return 0;
551         }
552         SGSharedPtr<SGExpression<T> > inputExpression;
553         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
554         if (!inputExpression) {
555             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
556             return 0;
557         }
558         return new SGSqrtExpression<T>(inputExpression);
559     }
560
561     if (name == "tan") {
562         if (expression->nChildren() != 1) {
563             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
564             return 0;
565         }
566         SGSharedPtr<SGExpression<T> > inputExpression;
567         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
568         if (!inputExpression) {
569             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
570             return 0;
571         }
572         return new SGTanExpression<T>(inputExpression);
573     }
574
575     if (name == "tanh") {
576         if (expression->nChildren() != 1) {
577             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
578             return 0;
579         }
580         SGSharedPtr<SGExpression<T> > inputExpression;
581         inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
582         if (!inputExpression) {
583             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
584             return 0;
585         }
586         return new SGTanhExpression<T>(inputExpression);
587     }
588
589 // if (name == "table") {
590 // }
591 // if (name == "step") {
592 // }
593 // if (name == "condition") {
594 // }
595
596     if (name == "atan2") {
597         if (expression->nChildren() != 2) {
598             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
599             return 0;
600         }
601         SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
602             SGReadFExpression<T>(inputRoot, expression->getChild(0)),
603             SGReadFExpression<T>(inputRoot, expression->getChild(1))
604         };
605         if (!inputExpressions[0] || !inputExpressions[1]) {
606             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
607             return 0;
608         }
609         return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
610     }
611     if (name == "div") {
612         if (expression->nChildren() != 2) {
613             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
614             return 0;
615         }
616         SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
617             SGReadFExpression<T>(inputRoot, expression->getChild(0)),
618             SGReadFExpression<T>(inputRoot, expression->getChild(1))
619         };
620         if (!inputExpressions[0] || !inputExpressions[1]) {
621             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
622             return 0;
623         }
624         return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
625     }
626     if (name == "mod") {
627         if (expression->nChildren() != 2) {
628             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
629             return 0;
630         }
631         SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
632             SGReadFExpression<T>(inputRoot, expression->getChild(0)),
633             SGReadFExpression<T>(inputRoot, expression->getChild(1))
634         };
635         if (!inputExpressions[0] || !inputExpressions[1]) {
636             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
637             return 0;
638         }
639         return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
640     }
641     if (name == "pow") {
642         if (expression->nChildren() != 2) {
643             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
644             return 0;
645         }
646         SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
647             SGReadIExpression<T>(inputRoot, expression->getChild(0)),
648             SGReadIExpression<T>(inputRoot, expression->getChild(1))
649         };
650         if (!inputExpressions[0] || !inputExpressions[1]) {
651             SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
652             return 0;
653         }
654         return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
655     }
656
657     return 0;
658 }
659
660 SGExpression<int>*
661 SGReadIntExpression(SGPropertyNode *inputRoot,
662                     const SGPropertyNode *configNode)
663 { return SGReadIExpression<int>(inputRoot, configNode); }
664
665 SGExpression<float>*
666 SGReadFloatExpression(SGPropertyNode *inputRoot,
667                       const SGPropertyNode *configNode)
668 { return SGReadFExpression<float>(inputRoot, configNode); }
669
670 SGExpression<double>*
671 SGReadDoubleExpression(SGPropertyNode *inputRoot,
672                        const SGPropertyNode *configNode)
673 { return SGReadFExpression<double>(inputRoot, configNode); }
674
675 // SGExpression<bool>*
676 // SGReadBoolExpression(SGPropertyNode *inputRoot,
677 //                      const SGPropertyNode *configNode)
678 // { return SGReadBExpression<bool>(inputRoot, configNode); }
679
680 namespace simgear
681 {
682 namespace expression
683 {
684
685 bool Parser::readChildren(const SGPropertyNode* exp,
686                           vector<Expression*>& result)
687 {
688     for (int i = 0; i < exp->nChildren(); ++i)
689         result.push_back(read(exp->getChild(i)));
690     return true;
691 }
692
693 void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
694 {
695     ParserMapSingleton::instance()
696         ->_parserTable.insert(std::make_pair(token, parsefn));
697 }
698
699 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
700 {
701     switch (exp->getType()) {
702     case props::BOOL:
703         return new SGConstExpression<bool>(getValue<bool>(exp));        
704     case props::INT:
705         return new SGConstExpression<int>(getValue<int>(exp));        
706     case props::FLOAT:
707         return new SGConstExpression<float>(getValue<float>(exp));
708     case props::DOUBLE:
709         return new SGConstExpression<double>(getValue<double>(exp));
710     default:
711         return 0;
712     }
713 }
714
715 ExpParserRegistrar valueRegistrar("value", valueParser);
716
717 template<typename T, typename OpType>
718 inline Expression* makeConvert(Expression* e)
719 {
720     return new ConvertExpression<T,
721         OpType>(static_cast<SGExpression<OpType>*>(e));
722 }
723
724 Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
725 {
726     vector<Expression*>::iterator maxElem
727         = max_element(exps.begin(), exps.end());
728     Type maxType = (*maxElem)->getType();
729     Type resultType = minType < maxType ? maxType : minType;
730     for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
731          itr != end;
732          ++itr) {
733         if ((*itr)->getType() != resultType) {
734             switch ((*itr)->getType()) {
735             case BOOL:
736                 switch (resultType) {
737                 case INT:
738                     *itr = makeConvert<int, bool>(*itr);
739                     break;
740                 case FLOAT:
741                     *itr = makeConvert<float, bool>(*itr);
742                     break;
743                 case DOUBLE:
744                     *itr = makeConvert<double, bool>(*itr);
745                     break;
746                 default:
747                     break;
748                 }
749                 break;
750             case INT:
751                 switch (resultType) {
752                 case FLOAT:
753                     *itr = makeConvert<float, int>(*itr);
754                     break;
755                 case DOUBLE:
756                     *itr = makeConvert<double, int>(*itr);
757                     break;
758                 default:
759                     break;
760                 }
761                 break;
762             case FLOAT:
763                 *itr = makeConvert<double, float>(*itr);
764                 break;
765             default:
766                 break;
767             }
768         }
769     }
770     return resultType;
771 }
772
773 template<template<typename OpType> class Expr>
774 Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
775 {
776     switch (operandType) {
777     case BOOL:
778     {
779         Expr<bool> *expr = new Expr<bool>();
780         expr->addOperands(children.begin(), children.end());
781         return expr;
782     }
783     case INT:
784     {
785         Expr<int> *expr = new Expr<int>();
786         expr->addOperands(children.begin(), children.end());
787         return expr;
788     }
789     case FLOAT:
790     {
791         Expr<float> *expr = new Expr<float>();
792         expr->addOperands(children.begin(), children.end());
793         return expr;
794     }
795     case DOUBLE:
796     {
797         Expr<double> *expr = new Expr<double>();
798         expr->addOperands(children.begin(), children.end());
799         return expr;
800     }
801     default:
802         return 0;
803     }
804 }
805
806 template<template<typename OpType> class PredExp>
807 Expression* predParser(const SGPropertyNode* exp, Parser* parser)
808 {
809     vector<Expression*> children;
810     parser->readChildren(exp, children);
811     Type operandType = promoteAndConvert(children);
812     return makeTypedOperandExp<PredExp>(operandType, children);
813 }
814
815 ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
816 ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
817 ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
818
819 template<typename Logicop>
820 Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
821 {
822     using namespace boost;
823     vector<Expression*> children;
824     parser->readChildren(exp, children);
825     vector<Expression*>::iterator notBool =
826         find_if(children.begin(), children.end(),
827                 bind(&Expression::getType, _1) != BOOL);
828     if (notBool != children.end())
829         throw("non boolean operand to logical expression");
830     Logicop *expr = new Logicop;
831     expr->addOperands(children.begin(), children.end());
832     return expr;
833 }
834
835 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
836 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
837
838 int BindingLayout::addBinding(const string& name, Type type)
839 {
840     //XXX error checkint
841     vector<VariableBinding>::iterator itr
842         = find_if(bindings.begin(), bindings.end(),
843                   bind(&VariableBinding::name, _1) == name);
844     if (itr != bindings.end())
845         return itr->location;
846     int result = bindings.size();
847     bindings.push_back(VariableBinding(name, type, bindings.size()));
848     return result;
849 }
850
851 bool BindingLayout::findBinding(const std::string& name,
852                                 VariableBinding& result) const
853 {
854     using namespace std;
855     using namespace boost;
856     vector<VariableBinding>::const_iterator itr
857         = find_if(bindings.begin(), bindings.end(),
858                   bind(&VariableBinding::name, _1) == name);
859     if (itr != bindings.end()) {
860         result = *itr;
861         return true;
862     } else {
863         return false;
864     }
865 }
866 }
867 }