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