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