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