]> git.mxchange.org Git - simgear.git/blob - simgear/structure/SGExpression.hxx
2dac8efb1863c105bfd78b045af4289180df6c06
[simgear.git] / simgear / structure / SGExpression.hxx
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 #ifndef _SG_EXPRESSION_HXX
23 #define _SG_EXPRESSION_HXX 1
24
25 #include <string>
26 #include <vector>
27
28 #include <simgear/props/condition.hxx>
29 #include <simgear/props/props.hxx>
30 #include <simgear/math/interpolater.hxx>
31 #include <simgear/math/SGMath.hxx>
32 #include <simgear/scene/model/persparam.hxx>
33 #include <simgear/structure/exception.hxx>
34
35 /// Expression tree implementation.
36
37 namespace simgear
38 {
39   namespace expression
40   {
41     enum Type {
42       BOOL = 0,
43       INT,
44       FLOAT,
45       DOUBLE
46     };
47     template<typename T> struct TypeTraits;
48     template<> struct TypeTraits<bool> {
49       static const Type typeTag = BOOL;
50     };
51     template<> struct TypeTraits<int> {
52       static const Type typeTag = INT;
53     };
54     template<> struct TypeTraits<float> {
55       static const Type typeTag = FLOAT;
56     };
57     template<> struct TypeTraits<double> {
58       static const Type typeTag = DOUBLE;
59     };
60
61     struct Value
62     {
63       Type typeTag;
64       union {
65         bool boolVal;
66         int intVal;
67         float floatVal;
68         double doubleVal;
69       } val;
70
71       Value() : typeTag(DOUBLE)
72       {
73         val.doubleVal = 0.0;
74       }
75
76       Value(bool val_) : typeTag(BOOL)
77       {
78         val.boolVal = val_;
79       }
80
81       Value(int val_) : typeTag(INT)
82       {
83         val.intVal = val_;
84       }
85
86       Value(float val_) : typeTag(FLOAT)
87       {
88         val.floatVal = val_;
89       }
90
91       Value(double val_) : typeTag(DOUBLE)
92       {
93         val.doubleVal = val_;
94       }
95
96     };
97
98     class Binding;
99   }
100
101   class Expression : public SGReferenced
102   {
103   public:
104     virtual ~Expression() {}
105     virtual expression::Type getType() const = 0;
106   };
107
108   const expression::Value eval(const Expression* exp,
109                                const expression::Binding* binding = 0);
110
111 }
112
113 template<typename T>
114 class SGExpression : public simgear::Expression {
115 public:
116   virtual ~SGExpression() {}
117   typedef T result_type;
118   typedef T operand_type;
119   virtual void eval(T&, const simgear::expression::Binding*) const = 0;
120
121   T getValue(const simgear::expression::Binding* binding = 0) const
122   { T value; eval(value, binding); return value; }
123
124   virtual bool isConst() const { return false; }
125   virtual SGExpression* simplify();
126   virtual simgear::expression::Type getType() const
127   {
128     return simgear::expression::TypeTraits<T>::typeTag;
129   }
130   virtual simgear::expression::Type getOperandType() const
131   {
132     return simgear::expression::TypeTraits<T>::typeTag;
133   }
134 };
135
136 /// Constant value expression
137 template<typename T>
138 class SGConstExpression : public SGExpression<T> {
139 public:
140   SGConstExpression(const T& value = T()) : _value(value)
141   { }
142   void setValue(const T& value)
143   { _value = value; }
144   const T& getValue(const simgear::expression::Binding* binding = 0) const
145   { return _value; }
146   virtual void eval(T& value, const simgear::expression::Binding*) const
147   { value = _value; }
148   virtual bool isConst() const { return true; }
149 private:
150   T _value;
151 };
152
153 template<typename T>
154 SGExpression<T>*
155 SGExpression<T>::simplify()
156 {
157   if (isConst())
158     return new SGConstExpression<T>(getValue());
159   return this;
160 }
161
162 template<typename T>
163 class SGUnaryExpression : public SGExpression<T> {
164 public:
165   const SGExpression<T>* getOperand() const
166   { return _expression; }
167   SGExpression<T>* getOperand()
168   { return _expression; }
169   void setOperand(SGExpression<T>* expression)
170   {
171     if (!expression)
172       expression = new SGConstExpression<T>(T());
173     _expression = expression;
174   }
175   virtual bool isConst() const
176   { return getOperand()->isConst(); }
177   virtual SGExpression<T>* simplify()
178   {
179     _expression = _expression->simplify();
180     return SGExpression<T>::simplify();
181   }
182
183 protected:
184   SGUnaryExpression(SGExpression<T>* expression = 0)
185   { setOperand(expression); }
186
187 private:
188   SGSharedPtr<SGExpression<T> > _expression;
189 };
190
191 template<typename T>
192 class SGBinaryExpression : public SGExpression<T> {
193 public:
194   const SGExpression<T>* getOperand(unsigned i) const
195   { return _expressions[i]; }
196   SGExpression<T>* getOperand(unsigned i)
197   { return _expressions[i]; }
198   void setOperand(unsigned i, SGExpression<T>* expression)
199   {
200     if (!expression)
201       expression = new SGConstExpression<T>(T());
202     if (2 <= i)
203       i = 0;
204     _expressions[i] = expression;
205   }
206
207   virtual bool isConst() const
208   { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
209   virtual SGExpression<T>* simplify()
210   {
211     _expressions[0] = _expressions[0]->simplify();
212     _expressions[1] = _expressions[1]->simplify();
213     return SGExpression<T>::simplify();
214   }
215
216 protected:
217   SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
218   { setOperand(0, expr0); setOperand(1, expr1); }
219   
220 private:
221   SGSharedPtr<SGExpression<T> > _expressions[2];
222 };
223
224 template<typename T>
225 class SGNaryExpression : public SGExpression<T> {
226 public:
227   unsigned getNumOperands() const
228   { return _expressions.size(); }
229   const SGExpression<T>* getOperand(unsigned i) const
230   { return _expressions[i]; }
231   SGExpression<T>* getOperand(unsigned i)
232   { return _expressions[i]; }
233   unsigned addOperand(SGExpression<T>* expression)
234   {
235     if (!expression)
236       return ~unsigned(0);
237     _expressions.push_back(expression);
238     return _expressions.size() - 1;
239   }
240
241   template<typename Iter>
242   void addOperands(Iter begin, Iter end)
243   {
244     for (Iter iter = begin; iter != end; ++iter)
245       {
246         addOperand(static_cast< ::SGExpression<T>*>(*iter));
247       }
248   }
249
250   virtual bool isConst() const
251   {
252     for (unsigned i = 0; i < _expressions.size(); ++i)
253       if (!_expressions[i]->isConst())
254         return false;
255     return true;
256   }
257   virtual SGExpression<T>* simplify()
258   {
259     for (unsigned i = 0; i < _expressions.size(); ++i)
260       _expressions[i] = _expressions[i]->simplify();
261     return SGExpression<T>::simplify();
262   }
263
264 protected:
265   SGNaryExpression()
266   { }
267   SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
268   { addOperand(expr0); addOperand(expr1); }
269   
270 private:
271   std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
272 };
273
274
275
276
277 template<typename T>
278 class SGPropertyExpression : public SGExpression<T> {
279 public:
280   SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
281   { }
282   void setPropertyNode(const SGPropertyNode* prop)
283   { _prop = prop; }
284   virtual void eval(T& value, const simgear::expression::Binding*) const
285   { doEval(value); }
286 private:
287   void doEval(float& value) const
288   { if (_prop) value = _prop->getFloatValue(); }
289   void doEval(double& value) const
290   { if (_prop) value = _prop->getDoubleValue(); }
291   void doEval(int& value) const
292   { if (_prop) value = _prop->getIntValue(); }
293   void doEval(long& value) const
294   { if (_prop) value = _prop->getLongValue(); }
295   void doEval(bool& value) const
296   { if (_prop) value = _prop->getBoolValue(); }
297   SGSharedPtr<const SGPropertyNode> _prop;
298 };
299
300 template<typename T>
301 class SGAbsExpression : public SGUnaryExpression<T> {
302 public:
303   SGAbsExpression(SGExpression<T>* expr = 0)
304     : SGUnaryExpression<T>(expr)
305   { }
306
307   virtual void eval(T& value, const simgear::expression::Binding* b) const
308   { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
309
310   using SGUnaryExpression<T>::getOperand;
311 };
312
313 template<typename T>
314 class SGACosExpression : public SGUnaryExpression<T> {
315 public:
316   SGACosExpression(SGExpression<T>* expr = 0)
317     : SGUnaryExpression<T>(expr)
318   { }
319
320   virtual void eval(T& value, const simgear::expression::Binding* b) const
321   { value = acos(SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
322
323   using SGUnaryExpression<T>::getOperand;
324 };
325
326 template<typename T>
327 class SGASinExpression : public SGUnaryExpression<T> {
328 public:
329   SGASinExpression(SGExpression<T>* expr = 0)
330     : SGUnaryExpression<T>(expr)
331   { }
332
333   virtual void eval(T& value, const simgear::expression::Binding* b) const
334   { value = asin(SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
335
336   using SGUnaryExpression<T>::getOperand;
337 };
338
339 template<typename T>
340 class SGATanExpression : public SGUnaryExpression<T> {
341 public:
342   SGATanExpression(SGExpression<T>* expr = 0)
343     : SGUnaryExpression<T>(expr)
344   { }
345
346   virtual void eval(T& value, const simgear::expression::Binding* b) const
347   { value = atan(getOperand()->getValue(b)); }
348
349   using SGUnaryExpression<T>::getOperand;
350 };
351
352 template<typename T>
353 class SGCeilExpression : public SGUnaryExpression<T> {
354 public:
355   SGCeilExpression(SGExpression<T>* expr = 0)
356     : SGUnaryExpression<T>(expr)
357   { }
358
359   virtual void eval(T& value, const simgear::expression::Binding* b) const
360   { value = ceil(getOperand()->getValue(b)); }
361
362   using SGUnaryExpression<T>::getOperand;
363 };
364
365 template<typename T>
366 class SGCosExpression : public SGUnaryExpression<T> {
367 public:
368   SGCosExpression(SGExpression<T>* expr = 0)
369     : SGUnaryExpression<T>(expr)
370   { }
371
372   virtual void eval(T& value, const simgear::expression::Binding* b) const
373   { value = cos(getOperand()->getValue(b)); }
374
375   using SGUnaryExpression<T>::getOperand;
376 };
377
378 template<typename T>
379 class SGCoshExpression : public SGUnaryExpression<T> {
380 public:
381   SGCoshExpression(SGExpression<T>* expr = 0)
382     : SGUnaryExpression<T>(expr)
383   { }
384
385   virtual void eval(T& value, const simgear::expression::Binding* b) const
386   { value = cosh(getOperand()->getValue(b)); }
387
388   using SGUnaryExpression<T>::getOperand;
389 };
390
391 template<typename T>
392 class SGExpExpression : public SGUnaryExpression<T> {
393 public:
394   SGExpExpression(SGExpression<T>* expr = 0)
395     : SGUnaryExpression<T>(expr)
396   { }
397
398   virtual void eval(T& value, const simgear::expression::Binding* b) const
399   { value = exp(getOperand()->getValue(b)); }
400
401   using SGUnaryExpression<T>::getOperand;
402 };
403
404 template<typename T>
405 class SGFloorExpression : public SGUnaryExpression<T> {
406 public:
407   SGFloorExpression(SGExpression<T>* expr = 0)
408     : SGUnaryExpression<T>(expr)
409   { }
410
411   virtual void eval(T& value, const simgear::expression::Binding* b) const
412   { value = floor(getOperand()->getValue(b)); }
413
414   using SGUnaryExpression<T>::getOperand;
415 };
416
417 template<typename T>
418 class SGLogExpression : public SGUnaryExpression<T> {
419 public:
420   SGLogExpression(SGExpression<T>* expr = 0)
421     : SGUnaryExpression<T>(expr)
422   { }
423
424   virtual void eval(T& value, const simgear::expression::Binding* b) const
425   { value = log(getOperand()->getValue(b)); }
426
427   using SGUnaryExpression<T>::getOperand;
428 };
429
430 template<typename T>
431 class SGLog10Expression : public SGUnaryExpression<T> {
432 public:
433   SGLog10Expression(SGExpression<T>* expr = 0)
434     : SGUnaryExpression<T>(expr)
435   { }
436
437   virtual void eval(T& value, const simgear::expression::Binding* b) const
438   { value = log10(getOperand()->getValue(b)); }
439
440   using SGUnaryExpression<T>::getOperand;
441 };
442
443 template<typename T>
444 class SGSinExpression : public SGUnaryExpression<T> {
445 public:
446   SGSinExpression(SGExpression<T>* expr = 0)
447     : SGUnaryExpression<T>(expr)
448   { }
449
450   virtual void eval(T& value, const simgear::expression::Binding* b) const
451   { value = sin(getOperand()->getValue(b)); }
452
453   using SGUnaryExpression<T>::getOperand;
454 };
455
456 template<typename T>
457 class SGSinhExpression : public SGUnaryExpression<T> {
458 public:
459   SGSinhExpression(SGExpression<T>* expr = 0)
460     : SGUnaryExpression<T>(expr)
461   { }
462
463   virtual void eval(T& value, const simgear::expression::Binding* b) const
464   { value = sinh(getOperand()->getValue(b)); }
465
466   using SGUnaryExpression<T>::getOperand;
467 };
468
469 template<typename T>
470 class SGSqrExpression : public SGUnaryExpression<T> {
471 public:
472   SGSqrExpression(SGExpression<T>* expr = 0)
473     : SGUnaryExpression<T>(expr)
474   { }
475
476   virtual void eval(T& value, const simgear::expression::Binding* b) const
477   { value = getOperand()->getValue(b); value = value*value; }
478
479   using SGUnaryExpression<T>::getOperand;
480 };
481
482 template<typename T>
483 class SGSqrtExpression : public SGUnaryExpression<T> {
484 public:
485   SGSqrtExpression(SGExpression<T>* expr = 0)
486     : SGUnaryExpression<T>(expr)
487   { }
488
489   virtual void eval(T& value, const simgear::expression::Binding* b) const
490   { value = sqrt(getOperand()->getValue(b)); }
491
492   using SGUnaryExpression<T>::getOperand;
493 };
494
495 template<typename T>
496 class SGTanExpression : public SGUnaryExpression<T> {
497 public:
498   SGTanExpression(SGExpression<T>* expr = 0)
499     : SGUnaryExpression<T>(expr)
500   { }
501
502   virtual void eval(T& value, const simgear::expression::Binding* b) const
503   { value = tan(getOperand()->getValue(b)); }
504
505   using SGUnaryExpression<T>::getOperand;
506 };
507
508 template<typename T>
509 class SGTanhExpression : public SGUnaryExpression<T> {
510 public:
511   SGTanhExpression(SGExpression<T>* expr = 0)
512     : SGUnaryExpression<T>(expr)
513   { }
514
515   virtual void eval(T& value, const simgear::expression::Binding* b) const
516   { value = tanh(getOperand()->getValue(b)); }
517
518   using SGUnaryExpression<T>::getOperand;
519 };
520
521 template<typename T>
522 class SGScaleExpression : public SGUnaryExpression<T> {
523 public:
524   SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
525     : SGUnaryExpression<T>(expr), _scale(scale)
526   { }
527   void setScale(const T& scale)
528   { _scale = scale; }
529   const T& getScale() const
530   { return _scale; }
531
532   virtual void eval(T& value, const simgear::expression::Binding* b) const
533   { value = _scale * getOperand()->getValue(b); }
534
535   virtual SGExpression<T>* simplify()
536   {
537     if (_scale == 1)
538       return getOperand()->simplify();
539     return SGUnaryExpression<T>::simplify();
540   }
541
542   using SGUnaryExpression<T>::getOperand;
543 private:
544   T _scale;
545 };
546
547 template<typename T>
548 class SGBiasExpression : public SGUnaryExpression<T> {
549 public:
550   SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
551     : SGUnaryExpression<T>(expr), _bias(bias)
552   { }
553
554   void setBias(const T& bias)
555   { _bias = bias; }
556   const T& getBias() const
557   { return _bias; }
558
559   virtual void eval(T& value, const simgear::expression::Binding* b) const
560   { value = _bias + getOperand()->getValue(b); }
561
562   virtual SGExpression<T>* simplify()
563   {
564     if (_bias == 0)
565       return getOperand()->simplify();
566     return SGUnaryExpression<T>::simplify();
567   }
568
569   using SGUnaryExpression<T>::getOperand;
570 private:
571   T _bias;
572 };
573
574 template<typename T>
575 class SGInterpTableExpression : public SGUnaryExpression<T> {
576 public:
577   SGInterpTableExpression(SGExpression<T>* expr,
578                           const SGInterpTable* interpTable) :
579     SGUnaryExpression<T>(expr),
580     _interpTable(interpTable)
581   { }
582
583   virtual void eval(T& value, const simgear::expression::Binding* b) const
584   {
585     if (_interpTable)
586       value = _interpTable->interpolate(getOperand()->getValue(b));
587   }
588
589   using SGUnaryExpression<T>::getOperand;
590 private:
591   SGSharedPtr<SGInterpTable const> _interpTable;
592 };
593
594 template<typename T>
595 class SGClipExpression : public SGUnaryExpression<T> {
596 public:
597   SGClipExpression(SGExpression<T>* expr)
598     : SGUnaryExpression<T>(expr),
599       _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
600       _clipMax(SGLimits<T>::max())
601   { }
602   SGClipExpression(SGExpression<T>* expr,
603                    const T& clipMin, const T& clipMax)
604     : SGUnaryExpression<T>(expr),
605       _clipMin(clipMin),
606       _clipMax(clipMax)
607   { }
608
609   void setClipMin(const T& clipMin)
610   { _clipMin = clipMin; }
611   const T& getClipMin() const
612   { return _clipMin; }
613
614   void setClipMax(const T& clipMax)
615   { _clipMax = clipMax; }
616   const T& getClipMax() const
617   { return _clipMax; }
618
619   virtual void eval(T& value, const simgear::expression::Binding* b) const
620   {
621     value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
622   }
623
624   virtual SGExpression<T>* simplify()
625   {
626     if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
627         _clipMax >= SGLimits<T>::max())
628       return getOperand()->simplify();
629     return SGUnaryExpression<T>::simplify();
630   }
631
632   using SGUnaryExpression<T>::getOperand;
633 private:
634   T _clipMin;
635   T _clipMax;
636 };
637
638 template<typename T>
639 class SGStepExpression : public SGUnaryExpression<T> {
640 public:
641   SGStepExpression(SGExpression<T>* expr = 0,
642                    const T& step = T(1), const T& scroll = T(0))
643     : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
644   { }
645
646   void setStep(const T& step)
647   { _step = step; }
648   const T& getStep() const
649   { return _step; }
650
651   void setScroll(const T& scroll)
652   { _scroll = scroll; }
653   const T& getScroll() const
654   { return _scroll; }
655
656   virtual void eval(T& value, const simgear::expression::Binding* b) const
657   { value = apply_mods(getOperand()->getValue(b)); }
658
659   using SGUnaryExpression<T>::getOperand;
660
661 private:
662   T apply_mods(T property) const
663   {
664     T modprop;
665     if (_step > 0) {
666       T scrollval = 0;
667       if(_scroll > 0) {
668         // calculate scroll amount (for odometer like movement)
669         T remainder  =  _step - fmod(fabs(property), _step);
670         if (remainder < _scroll) {
671           scrollval = (_scroll - remainder) / _scroll * _step;
672         }
673       }
674       // apply stepping of input value
675       if(property > 0)
676         modprop = ((floor(property/_step) * _step) + scrollval);
677       else
678         modprop = ((ceil(property/_step) * _step) + scrollval);
679     } else {
680       modprop = property;
681     }
682     return modprop;
683   }
684
685   T _step;
686   T _scroll;
687 };
688
689 template<typename T>
690 class SGEnableExpression : public SGUnaryExpression<T> {
691 public:
692   SGEnableExpression(SGExpression<T>* expr = 0,
693                      SGCondition* enable = 0,
694                      const T& disabledValue = T(0))
695     : SGUnaryExpression<T>(expr),
696       _enable(enable),
697       _disabledValue(disabledValue)
698   { }
699
700   const T& getDisabledValue() const
701   { return _disabledValue; }
702   void setDisabledValue(const T& disabledValue)
703   { _disabledValue = disabledValue; }
704
705   virtual void eval(T& value, const simgear::expression::Binding* b) const
706   {
707     if (_enable->test())
708       value = getOperand()->getValue(b);
709     else
710       value = _disabledValue;
711   }
712
713   virtual SGExpression<T>* simplify()
714   {
715     if (!_enable)
716       return getOperand()->simplify();
717     return SGUnaryExpression<T>::simplify();
718   }
719
720   using SGUnaryExpression<T>::getOperand;
721 private:
722   SGSharedPtr<SGCondition> _enable;
723   T _disabledValue;
724 };
725
726 template<typename T>
727 class SGAtan2Expression : public SGBinaryExpression<T> {
728 public:
729   SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
730     : SGBinaryExpression<T>(expr0, expr1)
731   { }
732   virtual void eval(T& value, const simgear::expression::Binding* b) const
733   { value = atan2(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
734   using SGBinaryExpression<T>::getOperand;
735 };
736
737 template<typename T>
738 class SGDivExpression : public SGBinaryExpression<T> {
739 public:
740   SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
741     : SGBinaryExpression<T>(expr0, expr1)
742   { }
743   virtual void eval(T& value, const simgear::expression::Binding* b) const
744   { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
745   using SGBinaryExpression<T>::getOperand;
746 };
747
748 template<typename T>
749 class SGModExpression : public SGBinaryExpression<T> {
750 public:
751   SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
752     : SGBinaryExpression<T>(expr0, expr1)
753   { }
754   virtual void eval(T& value, const simgear::expression::Binding* b) const
755   { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
756   using SGBinaryExpression<T>::getOperand;
757 private:
758   int mod(const int& v0, const int& v1) const
759   { return v0 % v1; }
760   float mod(const float& v0, const float& v1) const
761   { return fmod(v0, v1); }
762   double mod(const double& v0, const double& v1) const
763   { return fmod(v0, v1); }
764 };
765
766 template<typename T>
767 class SGPowExpression : public SGBinaryExpression<T> {
768 public:
769   SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
770     : SGBinaryExpression<T>(expr0, expr1)
771   { }
772   virtual void eval(T& value, const simgear::expression::Binding* b) const
773   { value = pow(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
774   using SGBinaryExpression<T>::getOperand;
775 };
776
777 template<typename T>
778 class SGSumExpression : public SGNaryExpression<T> {
779 public:
780   SGSumExpression()
781   { }
782   SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
783     : SGNaryExpression<T>(expr0, expr1)
784   { }
785   virtual void eval(T& value, const simgear::expression::Binding* b) const
786   {
787     value = T(0);
788     unsigned sz = SGNaryExpression<T>::getNumOperands();
789     for (unsigned i = 0; i < sz; ++i)
790       value += getOperand(i)->getValue(b);
791   }
792   using SGNaryExpression<T>::getValue;
793   using SGNaryExpression<T>::getOperand;
794 };
795
796 template<typename T>
797 class SGProductExpression : public SGNaryExpression<T> {
798 public:
799   SGProductExpression()
800   { }
801   SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
802     : SGNaryExpression<T>(expr0, expr1)
803   { }
804   virtual void eval(T& value, const simgear::expression::Binding* b) const
805   {
806     value = T(1);
807     unsigned sz = SGNaryExpression<T>::getNumOperands();
808     for (unsigned i = 0; i < sz; ++i)
809       value *= getOperand(i)->getValue(b);
810   }
811   using SGNaryExpression<T>::getValue;
812   using SGNaryExpression<T>::getOperand;
813 };
814
815 template<typename T>
816 class SGMinExpression : public SGNaryExpression<T> {
817 public:
818   SGMinExpression()
819   { }
820   SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
821     : SGNaryExpression<T>(expr0, expr1)
822   { }
823   virtual void eval(T& value, const simgear::expression::Binding* b) const
824   {
825     unsigned sz = SGNaryExpression<T>::getNumOperands();
826     if (sz < 1)
827       return;
828     
829     value = getOperand(0)->getValue(b);
830     for (unsigned i = 1; i < sz; ++i)
831       value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
832   }
833   using SGNaryExpression<T>::getOperand;
834 };
835
836 template<typename T>
837 class SGMaxExpression : public SGNaryExpression<T> {
838 public:
839   SGMaxExpression()
840   { }
841   SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
842     : SGNaryExpression<T>(expr0, expr1)
843   { }
844   virtual void eval(T& value, const simgear::expression::Binding* b) const
845   {
846     unsigned sz = SGNaryExpression<T>::getNumOperands();
847     if (sz < 1)
848       return;
849     
850     value = getOperand(0)->getValue(b);
851     for (unsigned i = 1; i < sz; ++i)
852       value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
853   }
854   using SGNaryExpression<T>::getOperand;
855 };
856
857 typedef SGExpression<int> SGExpressioni;
858 typedef SGExpression<float> SGExpressionf;
859 typedef SGExpression<double> SGExpressiond;
860 typedef SGExpression<bool> SGExpressionb;
861
862 /**
863  * Global function to make an expression out of properties.
864
865   <clip>
866     <clipMin>0</clipMin>
867     <clipMax>79</clipMax>
868     <abs>
869       <sum>
870         <rad2deg>
871           <property>sim/model/whatever-rad</property>
872         </rad2deg>
873         <property>sim/model/someother-deg</property>
874         <value>-90</value>
875       </sum>
876     </abs>
877   <clip>
878
879 will evaluate to an expression:
880
881 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
882
883  */
884 SGExpression<int>*
885 SGReadIntExpression(SGPropertyNode *inputRoot,
886                     const SGPropertyNode *configNode);
887
888 SGExpression<float>*
889 SGReadFloatExpression(SGPropertyNode *inputRoot,
890                       const SGPropertyNode *configNode);
891
892 SGExpression<double>*
893 SGReadDoubleExpression(SGPropertyNode *inputRoot,
894                        const SGPropertyNode *configNode);
895
896 SGExpression<bool>*
897 SGReadBoolExpression(SGPropertyNode *inputRoot,
898                      const SGPropertyNode *configNode);
899
900 namespace simgear
901 {
902   namespace expression
903   {
904   struct ParseError : public sg_exception
905   {
906       ParseError(const string& message = std::string())
907           : sg_exception(message) {}
908   };
909     
910   // Support for binding variables around an expression.
911   class Binding
912   {
913   public:
914       virtual ~Binding() {}
915       const virtual Value* getBindings() const = 0;
916       virtual Value* getBindings() = 0;
917   };
918
919   class VariableLengthBinding : public Binding
920   {
921   public:
922       const Value* getBindings() const
923       {
924           if (_bindings.empty())
925               return 0;
926           else
927               return &_bindings[0];
928       }
929       Value* getBindings()
930       {
931           if (_bindings.empty())
932               return 0;
933           else
934               return &_bindings[0];
935       }
936       std::vector<Value> _bindings;
937   };
938
939   template<int Size> class FixedLengthBinding : public Binding
940   {
941   public:
942       Value* getBindings()
943       {
944           return &_bindings[0];
945       }
946       const Value* getBindings() const
947       {
948           return &_bindings[0];
949       }
950       Value _bindings[Size];
951   };
952
953   struct VariableBinding
954   {
955       VariableBinding() : type(expression::DOUBLE), location(-1) {}
956
957       VariableBinding(const std::string& name_, expression::Type type_,
958                       int location_)
959           : name(name_), type(type_), location(location_)
960       {
961       }
962       std::string name;
963       expression::Type type;
964       int location;
965   };
966
967   class BindingLayout
968   {
969   public:
970       int addBinding(const std::string& name, expression::Type type);
971       bool findBinding(const string& name, VariableBinding& result) const;
972       std::vector<VariableBinding> bindings;
973   };
974
975   class Parser {
976   public:
977       typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
978                                         Parser* parser);
979       void addParser(const std::string& name, exp_parser parser)
980       {
981           getParserMap().insert(std::make_pair(name, parser));
982       }
983       Expression* read(const SGPropertyNode* exp)
984       {
985           ParserMap& map = getParserMap();
986           ParserMap::iterator itr = map.find(exp->getName());
987           if (itr == map.end())
988               throw ParseError(string("unknown expression ") + exp->getName());
989           exp_parser parser = itr->second;
990           return (*parser)(exp, this);
991       }
992       // XXX vector of SGSharedPtr?
993       bool readChildren(const SGPropertyNode* exp,
994                         std::vector<Expression*>& result);
995       /**
996        * Function that parses a property tree, producing an expression.
997        */
998       typedef std::map<const std::string, exp_parser> ParserMap;
999       virtual ParserMap& getParserMap() = 0;
1000       /**
1001        * After an expression is parsed, the binding layout may contain
1002        * references that need to be bound during evaluation.
1003        */
1004       BindingLayout& getBindingLayout() { return _bindingLayout; }
1005   protected:
1006       BindingLayout _bindingLayout;
1007   };
1008
1009   class ExpressionParser : public Parser
1010   {
1011   public:
1012       ParserMap& getParserMap() { return _parserTable; }
1013       static void addExpParser(const std::string&, exp_parser);
1014   protected:
1015       static ParserMap _parserTable;
1016   };
1017
1018   /**
1019    * Constructor for registering parser functions.
1020    */
1021   struct ExpParserRegistrar
1022   {
1023       ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1024       {
1025           ExpressionParser::addExpParser(token, parser);
1026       }
1027   };
1028
1029   }
1030
1031   /**
1032    * Access a variable definition. Use a location from a BindingLayout.
1033    */
1034   template<typename T>
1035   class VariableExpression : public ::SGExpression<T> {
1036   public:
1037     VariableExpression(int location) : _location(location) {}
1038     virtual ~VariableExpression() {}
1039     virtual void eval(T& value, const simgear::expression::Binding* b) const
1040     {
1041       const expression::Value* values = b->getBindings();
1042       value = *reinterpret_cast<const T *>(&values[_location].val);
1043     }
1044   protected:
1045     int _location;
1046
1047   };
1048
1049   /**
1050    * An n-ary expression where the types of the argument aren't the
1051    * same as the return type.
1052    */
1053   template<typename T, typename OpType>
1054   class GeneralNaryExpression : public ::SGExpression<T> {
1055   public:
1056     typedef OpType operand_type;
1057     unsigned getNumOperands() const
1058     { return _expressions.size(); }
1059     const ::SGExpression<OpType>* getOperand(unsigned i) const
1060     { return _expressions[i]; }
1061     ::SGExpression<OpType>* getOperand(unsigned i)
1062     { return _expressions[i]; }
1063     unsigned addOperand(::SGExpression<OpType>* expression)
1064     {
1065       if (!expression)
1066         return ~unsigned(0);
1067       _expressions.push_back(expression);
1068       return _expressions.size() - 1;
1069     }
1070     
1071     template<typename Iter>
1072     void addOperands(Iter begin, Iter end)
1073     {
1074       for (Iter iter = begin; iter != end; ++iter)
1075         {
1076           addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1077         }
1078     }
1079     
1080     virtual bool isConst() const
1081     {
1082       for (unsigned i = 0; i < _expressions.size(); ++i)
1083         if (!_expressions[i]->isConst())
1084           return false;
1085       return true;
1086     }
1087     virtual ::SGExpression<T>* simplify()
1088     {
1089       for (unsigned i = 0; i < _expressions.size(); ++i)
1090         _expressions[i] = _expressions[i]->simplify();
1091       return SGExpression<T>::simplify();
1092     }
1093
1094     simgear::expression::Type getOperandType() const
1095     {
1096       return simgear::expression::TypeTraits<OpType>::typeTag;
1097     }
1098     
1099   protected:
1100     GeneralNaryExpression()
1101     { }
1102     GeneralNaryExpression(::SGExpression<OpType>* expr0,
1103                           ::SGExpression<OpType>* expr1)
1104     { addOperand(expr0); addOperand(expr1); }
1105
1106     std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1107   };
1108
1109   /**
1110    * A predicate that wraps, for example the STL template predicate
1111    * expressions like std::equal_to.
1112    */
1113   template<typename OpType, template<typename PredOp> class Pred>
1114   class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1115   public:
1116     PredicateExpression()
1117     {
1118     }
1119     PredicateExpression(::SGExpression<OpType>* expr0,
1120                         ::SGExpression<OpType>* expr1)
1121       : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1122     {
1123     }
1124     virtual void eval(bool& value, const simgear::expression::Binding* b) const
1125     {
1126       unsigned sz = this->getNumOperands();
1127       if (sz != 2)
1128         return;
1129       value = _pred(this->getOperand(0)->getValue(b),
1130                     this->getOperand(1)->getValue(b));
1131     }
1132   protected:
1133     Pred<OpType> _pred;
1134   };
1135
1136   template<template<typename OT> class Pred, typename OpType>
1137   PredicateExpression<OpType, Pred>*
1138   makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1139   {
1140     return new PredicateExpression<OpType, Pred>(op1, op2);
1141   }
1142   
1143   template<typename OpType>
1144   class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1145   {
1146   public:
1147     EqualToExpression() {}
1148     EqualToExpression(::SGExpression<OpType>* expr0,
1149                       ::SGExpression<OpType>* expr1)
1150       : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1151     {
1152     }
1153   };
1154
1155   template<typename OpType>
1156   class LessExpression : public PredicateExpression<OpType, std::less>
1157   {
1158   public:
1159     LessExpression() {}
1160     LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1161       : PredicateExpression<OpType, std::less>(expr0, expr1)
1162     {
1163     }
1164   };
1165
1166   template<typename OpType>
1167   class LessEqualExpression
1168     : public PredicateExpression<OpType, std::less_equal>
1169   {
1170   public:
1171     LessEqualExpression() {}
1172     LessEqualExpression(::SGExpression<OpType>* expr0,
1173                         ::SGExpression<OpType>* expr1)
1174       : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1175     {
1176     }
1177   };
1178
1179   class NotExpression : public ::SGUnaryExpression<bool>
1180   {
1181   public:
1182     NotExpression(::SGExpression<bool>* expr = 0)
1183       : ::SGUnaryExpression<bool>(expr)
1184     {
1185     }
1186     void eval(bool& value, const expression::Binding* b) const
1187     {
1188       value = !getOperand()->getValue(b);
1189     }
1190   };
1191
1192   class OrExpression : public ::SGNaryExpression<bool>
1193   {
1194   public:
1195     void eval(bool& value, const expression::Binding* b) const
1196     {
1197       value = false;
1198       for (int i = 0; i < getNumOperands(); ++i) {
1199         value = value || getOperand(i)->getValue(b);
1200         if (value)
1201           return;
1202       }
1203     }
1204   };
1205
1206   class AndExpression : public ::SGNaryExpression<bool>
1207   {
1208   public:
1209     void eval(bool& value, const expression::Binding* b) const
1210     {
1211       value = true;
1212       for (int i = 0; i < getNumOperands(); ++i) {
1213         value = value && getOperand(i)->getValue(b);
1214         if (!value)
1215           return;
1216       }
1217     }
1218   };
1219
1220   /**
1221    * Convert an operand from OpType to T.
1222    */
1223   template<typename T, typename OpType>
1224   class ConvertExpression : public GeneralNaryExpression<T, OpType>
1225   {
1226   public:
1227     ConvertExpression() {}
1228     ConvertExpression(::SGExpression<OpType>* expr0)
1229     {
1230       addOperand(expr0);
1231     }
1232     virtual void eval(T& value, const simgear::expression::Binding* b) const
1233     {
1234       typename ConvertExpression::operand_type result;
1235       this->_expressions.at(0)->eval(result, b);
1236       value = result;
1237     }
1238   };
1239 }
1240 #endif // _SG_EXPRESSION_HXX