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