]> git.mxchange.org Git - simgear.git/blob - simgear/structure/SGExpression.hxx
444d40cdc9e676940abf4bcd9b8c45a8606283d0
[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 SGDifferenceExpression : public SGNaryExpression<T> {
799 public:
800   SGDifferenceExpression()
801   { }
802   SGDifferenceExpression(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(0);
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 SGProductExpression : public SGNaryExpression<T> {
818 public:
819   SGProductExpression()
820   { }
821   SGProductExpression(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     value = T(1);
827     unsigned sz = SGNaryExpression<T>::getNumOperands();
828     for (unsigned i = 0; i < sz; ++i)
829       value *= getOperand(i)->getValue(b);
830   }
831   using SGNaryExpression<T>::getValue;
832   using SGNaryExpression<T>::getOperand;
833 };
834
835 template<typename T>
836 class SGMinExpression : public SGNaryExpression<T> {
837 public:
838   SGMinExpression()
839   { }
840   SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
841     : SGNaryExpression<T>(expr0, expr1)
842   { }
843   virtual void eval(T& value, const simgear::expression::Binding* b) const
844   {
845     unsigned sz = SGNaryExpression<T>::getNumOperands();
846     if (sz < 1)
847       return;
848     
849     value = getOperand(0)->getValue(b);
850     for (unsigned i = 1; i < sz; ++i)
851       value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
852   }
853   using SGNaryExpression<T>::getOperand;
854 };
855
856 template<typename T>
857 class SGMaxExpression : public SGNaryExpression<T> {
858 public:
859   SGMaxExpression()
860   { }
861   SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
862     : SGNaryExpression<T>(expr0, expr1)
863   { }
864   virtual void eval(T& value, const simgear::expression::Binding* b) const
865   {
866     unsigned sz = SGNaryExpression<T>::getNumOperands();
867     if (sz < 1)
868       return;
869     
870     value = getOperand(0)->getValue(b);
871     for (unsigned i = 1; i < sz; ++i)
872       value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
873   }
874   using SGNaryExpression<T>::getOperand;
875 };
876
877 typedef SGExpression<int> SGExpressioni;
878 typedef SGExpression<float> SGExpressionf;
879 typedef SGExpression<double> SGExpressiond;
880 typedef SGExpression<bool> SGExpressionb;
881
882 /**
883  * Global function to make an expression out of properties.
884
885   <clip>
886     <clipMin>0</clipMin>
887     <clipMax>79</clipMax>
888     <abs>
889       <sum>
890         <rad2deg>
891           <property>sim/model/whatever-rad</property>
892         </rad2deg>
893         <property>sim/model/someother-deg</property>
894         <value>-90</value>
895       </sum>
896     </abs>
897   <clip>
898
899 will evaluate to an expression:
900
901 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
902
903  */
904 SGExpression<int>*
905 SGReadIntExpression(SGPropertyNode *inputRoot,
906                     const SGPropertyNode *configNode);
907
908 SGExpression<float>*
909 SGReadFloatExpression(SGPropertyNode *inputRoot,
910                       const SGPropertyNode *configNode);
911
912 SGExpression<double>*
913 SGReadDoubleExpression(SGPropertyNode *inputRoot,
914                        const SGPropertyNode *configNode);
915
916 SGExpression<bool>*
917 SGReadBoolExpression(SGPropertyNode *inputRoot,
918                      const SGPropertyNode *configNode);
919
920 namespace simgear
921 {
922   namespace expression
923   {
924   struct ParseError : public sg_exception
925   {
926       ParseError(const string& message = std::string())
927           : sg_exception(message) {}
928   };
929     
930   // Support for binding variables around an expression.
931   class Binding
932   {
933   public:
934       virtual ~Binding() {}
935       const virtual Value* getBindings() const = 0;
936       virtual Value* getBindings() = 0;
937   };
938
939   class VariableLengthBinding : public Binding
940   {
941   public:
942       const Value* getBindings() const
943       {
944           if (_bindings.empty())
945               return 0;
946           else
947               return &_bindings[0];
948       }
949       Value* getBindings()
950       {
951           if (_bindings.empty())
952               return 0;
953           else
954               return &_bindings[0];
955       }
956       std::vector<Value> _bindings;
957   };
958
959   template<int Size> class FixedLengthBinding : public Binding
960   {
961   public:
962       Value* getBindings()
963       {
964           return &_bindings[0];
965       }
966       const Value* getBindings() const
967       {
968           return &_bindings[0];
969       }
970       Value _bindings[Size];
971   };
972
973   struct VariableBinding
974   {
975       VariableBinding() : type(expression::DOUBLE), location(-1) {}
976
977       VariableBinding(const std::string& name_, expression::Type type_,
978                       int location_)
979           : name(name_), type(type_), location(location_)
980       {
981       }
982       std::string name;
983       expression::Type type;
984       int location;
985   };
986
987   class BindingLayout
988   {
989   public:
990       int addBinding(const std::string& name, expression::Type type);
991       bool findBinding(const string& name, VariableBinding& result) const;
992       std::vector<VariableBinding> bindings;
993   };
994
995   class Parser {
996   public:
997       typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
998                                         Parser* parser);
999       void addParser(const std::string& name, exp_parser parser)
1000       {
1001           getParserMap().insert(std::make_pair(name, parser));
1002       }
1003       Expression* read(const SGPropertyNode* exp)
1004       {
1005           ParserMap& map = getParserMap();
1006           ParserMap::iterator itr = map.find(exp->getName());
1007           if (itr == map.end())
1008               throw ParseError(string("unknown expression ") + exp->getName());
1009           exp_parser parser = itr->second;
1010           return (*parser)(exp, this);
1011       }
1012       // XXX vector of SGSharedPtr?
1013       bool readChildren(const SGPropertyNode* exp,
1014                         std::vector<Expression*>& result);
1015       /**
1016        * Function that parses a property tree, producing an expression.
1017        */
1018       typedef std::map<const std::string, exp_parser> ParserMap;
1019       virtual ParserMap& getParserMap() = 0;
1020       /**
1021        * After an expression is parsed, the binding layout may contain
1022        * references that need to be bound during evaluation.
1023        */
1024       BindingLayout& getBindingLayout() { return _bindingLayout; }
1025   protected:
1026       BindingLayout _bindingLayout;
1027   };
1028
1029   class ExpressionParser : public Parser
1030   {
1031   public:
1032       ParserMap& getParserMap()
1033       {
1034           return ParserMapSingleton::instance()->_parserTable;
1035       }
1036       static void addExpParser(const std::string&, exp_parser);
1037   protected:
1038       struct ParserMapSingleton : public simgear::Singleton<ParserMapSingleton>
1039       {
1040           ParserMap _parserTable;
1041       };
1042   };
1043
1044   /**
1045    * Constructor for registering parser functions.
1046    */
1047   struct ExpParserRegistrar
1048   {
1049       ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1050       {
1051           ExpressionParser::addExpParser(token, parser);
1052       }
1053   };
1054
1055   }
1056
1057   /**
1058    * Access a variable definition. Use a location from a BindingLayout.
1059    */
1060   template<typename T>
1061   class VariableExpression : public ::SGExpression<T> {
1062   public:
1063     VariableExpression(int location) : _location(location) {}
1064     virtual ~VariableExpression() {}
1065     virtual void eval(T& value, const simgear::expression::Binding* b) const
1066     {
1067       const expression::Value* values = b->getBindings();
1068       value = *reinterpret_cast<const T *>(&values[_location].val);
1069     }
1070   protected:
1071     int _location;
1072
1073   };
1074
1075   /**
1076    * An n-ary expression where the types of the argument aren't the
1077    * same as the return type.
1078    */
1079   template<typename T, typename OpType>
1080   class GeneralNaryExpression : public ::SGExpression<T> {
1081   public:
1082     typedef OpType operand_type;
1083     unsigned getNumOperands() const
1084     { return _expressions.size(); }
1085     const ::SGExpression<OpType>* getOperand(unsigned i) const
1086     { return _expressions[i]; }
1087     ::SGExpression<OpType>* getOperand(unsigned i)
1088     { return _expressions[i]; }
1089     unsigned addOperand(::SGExpression<OpType>* expression)
1090     {
1091       if (!expression)
1092         return ~unsigned(0);
1093       _expressions.push_back(expression);
1094       return _expressions.size() - 1;
1095     }
1096     
1097     template<typename Iter>
1098     void addOperands(Iter begin, Iter end)
1099     {
1100       for (Iter iter = begin; iter != end; ++iter)
1101         {
1102           addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1103         }
1104     }
1105     
1106     virtual bool isConst() const
1107     {
1108       for (unsigned i = 0; i < _expressions.size(); ++i)
1109         if (!_expressions[i]->isConst())
1110           return false;
1111       return true;
1112     }
1113     virtual ::SGExpression<T>* simplify()
1114     {
1115       for (unsigned i = 0; i < _expressions.size(); ++i)
1116         _expressions[i] = _expressions[i]->simplify();
1117       return SGExpression<T>::simplify();
1118     }
1119
1120     simgear::expression::Type getOperandType() const
1121     {
1122       return simgear::expression::TypeTraits<OpType>::typeTag;
1123     }
1124     
1125   protected:
1126     GeneralNaryExpression()
1127     { }
1128     GeneralNaryExpression(::SGExpression<OpType>* expr0,
1129                           ::SGExpression<OpType>* expr1)
1130     { addOperand(expr0); addOperand(expr1); }
1131
1132     std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1133   };
1134
1135   /**
1136    * A predicate that wraps, for example the STL template predicate
1137    * expressions like std::equal_to.
1138    */
1139   template<typename OpType, template<typename PredOp> class Pred>
1140   class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1141   public:
1142     PredicateExpression()
1143     {
1144     }
1145     PredicateExpression(::SGExpression<OpType>* expr0,
1146                         ::SGExpression<OpType>* expr1)
1147       : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1148     {
1149     }
1150     virtual void eval(bool& value, const simgear::expression::Binding* b) const
1151     {
1152       unsigned sz = this->getNumOperands();
1153       if (sz != 2)
1154         return;
1155       value = _pred(this->getOperand(0)->getValue(b),
1156                     this->getOperand(1)->getValue(b));
1157     }
1158   protected:
1159     Pred<OpType> _pred;
1160   };
1161
1162   template<template<typename OT> class Pred, typename OpType>
1163   PredicateExpression<OpType, Pred>*
1164   makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1165   {
1166     return new PredicateExpression<OpType, Pred>(op1, op2);
1167   }
1168   
1169   template<typename OpType>
1170   class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1171   {
1172   public:
1173     EqualToExpression() {}
1174     EqualToExpression(::SGExpression<OpType>* expr0,
1175                       ::SGExpression<OpType>* expr1)
1176       : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1177     {
1178     }
1179   };
1180
1181   template<typename OpType>
1182   class LessExpression : public PredicateExpression<OpType, std::less>
1183   {
1184   public:
1185     LessExpression() {}
1186     LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1187       : PredicateExpression<OpType, std::less>(expr0, expr1)
1188     {
1189     }
1190   };
1191
1192   template<typename OpType>
1193   class LessEqualExpression
1194     : public PredicateExpression<OpType, std::less_equal>
1195   {
1196   public:
1197     LessEqualExpression() {}
1198     LessEqualExpression(::SGExpression<OpType>* expr0,
1199                         ::SGExpression<OpType>* expr1)
1200       : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1201     {
1202     }
1203   };
1204
1205   class NotExpression : public ::SGUnaryExpression<bool>
1206   {
1207   public:
1208     NotExpression(::SGExpression<bool>* expr = 0)
1209       : ::SGUnaryExpression<bool>(expr)
1210     {
1211     }
1212     void eval(bool& value, const expression::Binding* b) const
1213     {
1214       value = !getOperand()->getValue(b);
1215     }
1216   };
1217
1218   class OrExpression : public ::SGNaryExpression<bool>
1219   {
1220   public:
1221     void eval(bool& value, const expression::Binding* b) const
1222     {
1223       value = false;
1224       for (int i = 0; i < (int)getNumOperands(); ++i) {
1225         value = value || getOperand(i)->getValue(b);
1226         if (value)
1227           return;
1228       }
1229     }
1230   };
1231
1232   class AndExpression : public ::SGNaryExpression<bool>
1233   {
1234   public:
1235     void eval(bool& value, const expression::Binding* b) const
1236     {
1237       value = true;
1238       for (int i = 0; i < (int)getNumOperands(); ++i) {
1239         value = value && getOperand(i)->getValue(b);
1240         if (!value)
1241           return;
1242       }
1243     }
1244   };
1245
1246   /**
1247    * Convert an operand from OpType to T.
1248    */
1249   template<typename T, typename OpType>
1250   class ConvertExpression : public GeneralNaryExpression<T, OpType>
1251   {
1252   public:
1253     ConvertExpression() {}
1254     ConvertExpression(::SGExpression<OpType>* expr0)
1255     {
1256       addOperand(expr0);
1257     }
1258     virtual void eval(T& value, const simgear::expression::Binding* b) const
1259     {
1260       typename ConvertExpression::operand_type result;
1261       this->_expressions.at(0)->eval(result, b);
1262       value = result;
1263     }
1264   };
1265 }
1266 #endif // _SG_EXPRESSION_HXX