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