3 * Copyright (C) 2006-2007 Mathias Froehlich
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.
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.
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,
22 #ifndef _SG_EXPRESSION_HXX
23 #define _SG_EXPRESSION_HXX 1
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>
35 /// Expression tree implementation.
47 template<typename T> struct TypeTraits;
48 template<> struct TypeTraits<bool> {
49 static const Type typeTag = BOOL;
51 template<> struct TypeTraits<int> {
52 static const Type typeTag = INT;
54 template<> struct TypeTraits<float> {
55 static const Type typeTag = FLOAT;
57 template<> struct TypeTraits<double> {
58 static const Type typeTag = DOUBLE;
71 Value() : typeTag(DOUBLE)
76 Value(bool val_) : typeTag(BOOL)
81 Value(int val_) : typeTag(INT)
86 Value(float val_) : typeTag(FLOAT)
91 Value(double val_) : typeTag(DOUBLE)
101 class Expression : public SGReferenced
104 virtual ~Expression() {}
105 virtual expression::Type getType() const = 0;
108 const expression::Value eval(const Expression* exp,
109 const expression::Binding* binding = 0);
114 class SGExpression : public simgear::Expression {
116 virtual ~SGExpression() {}
117 typedef T result_type;
118 typedef T operand_type;
119 virtual void eval(T&, const simgear::expression::Binding*) const = 0;
121 T getValue(const simgear::expression::Binding* binding = 0) const
122 { T value; eval(value, binding); return value; }
124 virtual bool isConst() const { return false; }
125 virtual SGExpression* simplify();
126 virtual simgear::expression::Type getType() const
128 return simgear::expression::TypeTraits<T>::typeTag;
130 virtual simgear::expression::Type getOperandType() const
132 return simgear::expression::TypeTraits<T>::typeTag;
136 /// Constant value expression
138 class SGConstExpression : public SGExpression<T> {
140 SGConstExpression(const T& value = T()) : _value(value)
142 void setValue(const T& value)
144 const T& getValue(const simgear::expression::Binding* binding = 0) const
146 virtual void eval(T& value, const simgear::expression::Binding*) const
148 virtual bool isConst() const { return true; }
155 SGExpression<T>::simplify()
158 return new SGConstExpression<T>(getValue());
163 class SGUnaryExpression : public SGExpression<T> {
165 const SGExpression<T>* getOperand() const
166 { return _expression; }
167 SGExpression<T>* getOperand()
168 { return _expression; }
169 void setOperand(SGExpression<T>* expression)
172 expression = new SGConstExpression<T>(T());
173 _expression = expression;
175 virtual bool isConst() const
176 { return getOperand()->isConst(); }
177 virtual SGExpression<T>* simplify()
179 _expression = _expression->simplify();
180 return SGExpression<T>::simplify();
184 SGUnaryExpression(SGExpression<T>* expression = 0)
185 { setOperand(expression); }
188 SGSharedPtr<SGExpression<T> > _expression;
192 class SGBinaryExpression : public SGExpression<T> {
194 const SGExpression<T>* getOperand(unsigned i) const
195 { return _expressions[i]; }
196 SGExpression<T>* getOperand(unsigned i)
197 { return _expressions[i]; }
198 void setOperand(unsigned i, SGExpression<T>* expression)
201 expression = new SGConstExpression<T>(T());
204 _expressions[i] = expression;
207 virtual bool isConst() const
208 { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
209 virtual SGExpression<T>* simplify()
211 _expressions[0] = _expressions[0]->simplify();
212 _expressions[1] = _expressions[1]->simplify();
213 return SGExpression<T>::simplify();
217 SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
218 { setOperand(0, expr0); setOperand(1, expr1); }
221 SGSharedPtr<SGExpression<T> > _expressions[2];
225 class SGNaryExpression : public SGExpression<T> {
227 unsigned getNumOperands() const
228 { return _expressions.size(); }
229 const SGExpression<T>* getOperand(unsigned i) const
230 { return _expressions[i]; }
231 SGExpression<T>* getOperand(unsigned i)
232 { return _expressions[i]; }
233 unsigned addOperand(SGExpression<T>* expression)
237 _expressions.push_back(expression);
238 return _expressions.size() - 1;
241 template<typename Iter>
242 void addOperands(Iter begin, Iter end)
244 for (Iter iter = begin; iter != end; ++iter)
246 addOperand(static_cast< ::SGExpression<T>*>(*iter));
250 virtual bool isConst() const
252 for (unsigned i = 0; i < _expressions.size(); ++i)
253 if (!_expressions[i]->isConst())
257 virtual SGExpression<T>* simplify()
259 for (unsigned i = 0; i < _expressions.size(); ++i)
260 _expressions[i] = _expressions[i]->simplify();
261 return SGExpression<T>::simplify();
267 SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
268 { addOperand(expr0); addOperand(expr1); }
271 std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
278 class SGPropertyExpression : public SGExpression<T> {
280 SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
282 void setPropertyNode(const SGPropertyNode* prop)
284 virtual void eval(T& value, const simgear::expression::Binding*) const
287 void doEval(float& value) const
288 { if (_prop) value = _prop->getFloatValue(); }
289 void doEval(double& value) const
290 { if (_prop) value = _prop->getDoubleValue(); }
291 void doEval(int& value) const
292 { if (_prop) value = _prop->getIntValue(); }
293 void doEval(long& value) const
294 { if (_prop) value = _prop->getLongValue(); }
295 void doEval(bool& value) const
296 { if (_prop) value = _prop->getBoolValue(); }
297 SGSharedPtr<const SGPropertyNode> _prop;
301 class SGAbsExpression : public SGUnaryExpression<T> {
303 SGAbsExpression(SGExpression<T>* expr = 0)
304 : SGUnaryExpression<T>(expr)
307 virtual void eval(T& value, const simgear::expression::Binding* b) const
308 { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
310 using SGUnaryExpression<T>::getOperand;
314 class SGACosExpression : public SGUnaryExpression<T> {
316 SGACosExpression(SGExpression<T>* expr = 0)
317 : SGUnaryExpression<T>(expr)
320 virtual void eval(T& value, const simgear::expression::Binding* b) const
321 { value = acos(SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
323 using SGUnaryExpression<T>::getOperand;
327 class SGASinExpression : public SGUnaryExpression<T> {
329 SGASinExpression(SGExpression<T>* expr = 0)
330 : SGUnaryExpression<T>(expr)
333 virtual void eval(T& value, const simgear::expression::Binding* b) const
334 { value = asin(SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
336 using SGUnaryExpression<T>::getOperand;
340 class SGATanExpression : public SGUnaryExpression<T> {
342 SGATanExpression(SGExpression<T>* expr = 0)
343 : SGUnaryExpression<T>(expr)
346 virtual void eval(T& value, const simgear::expression::Binding* b) const
347 { value = atan(getOperand()->getValue(b)); }
349 using SGUnaryExpression<T>::getOperand;
353 class SGCeilExpression : public SGUnaryExpression<T> {
355 SGCeilExpression(SGExpression<T>* expr = 0)
356 : SGUnaryExpression<T>(expr)
359 virtual void eval(T& value, const simgear::expression::Binding* b) const
360 { value = ceil(getOperand()->getValue(b)); }
362 using SGUnaryExpression<T>::getOperand;
366 class SGCosExpression : public SGUnaryExpression<T> {
368 SGCosExpression(SGExpression<T>* expr = 0)
369 : SGUnaryExpression<T>(expr)
372 virtual void eval(T& value, const simgear::expression::Binding* b) const
373 { value = cos(getOperand()->getValue(b)); }
375 using SGUnaryExpression<T>::getOperand;
379 class SGCoshExpression : public SGUnaryExpression<T> {
381 SGCoshExpression(SGExpression<T>* expr = 0)
382 : SGUnaryExpression<T>(expr)
385 virtual void eval(T& value, const simgear::expression::Binding* b) const
386 { value = cosh(getOperand()->getValue(b)); }
388 using SGUnaryExpression<T>::getOperand;
392 class SGExpExpression : public SGUnaryExpression<T> {
394 SGExpExpression(SGExpression<T>* expr = 0)
395 : SGUnaryExpression<T>(expr)
398 virtual void eval(T& value, const simgear::expression::Binding* b) const
399 { value = exp(getOperand()->getValue(b)); }
401 using SGUnaryExpression<T>::getOperand;
405 class SGFloorExpression : public SGUnaryExpression<T> {
407 SGFloorExpression(SGExpression<T>* expr = 0)
408 : SGUnaryExpression<T>(expr)
411 virtual void eval(T& value, const simgear::expression::Binding* b) const
412 { value = floor(getOperand()->getValue(b)); }
414 using SGUnaryExpression<T>::getOperand;
418 class SGLogExpression : public SGUnaryExpression<T> {
420 SGLogExpression(SGExpression<T>* expr = 0)
421 : SGUnaryExpression<T>(expr)
424 virtual void eval(T& value, const simgear::expression::Binding* b) const
425 { value = log(getOperand()->getValue(b)); }
427 using SGUnaryExpression<T>::getOperand;
431 class SGLog10Expression : public SGUnaryExpression<T> {
433 SGLog10Expression(SGExpression<T>* expr = 0)
434 : SGUnaryExpression<T>(expr)
437 virtual void eval(T& value, const simgear::expression::Binding* b) const
438 { value = log10(getOperand()->getValue(b)); }
440 using SGUnaryExpression<T>::getOperand;
444 class SGSinExpression : public SGUnaryExpression<T> {
446 SGSinExpression(SGExpression<T>* expr = 0)
447 : SGUnaryExpression<T>(expr)
450 virtual void eval(T& value, const simgear::expression::Binding* b) const
451 { value = sin(getOperand()->getValue(b)); }
453 using SGUnaryExpression<T>::getOperand;
457 class SGSinhExpression : public SGUnaryExpression<T> {
459 SGSinhExpression(SGExpression<T>* expr = 0)
460 : SGUnaryExpression<T>(expr)
463 virtual void eval(T& value, const simgear::expression::Binding* b) const
464 { value = sinh(getOperand()->getValue(b)); }
466 using SGUnaryExpression<T>::getOperand;
470 class SGSqrExpression : public SGUnaryExpression<T> {
472 SGSqrExpression(SGExpression<T>* expr = 0)
473 : SGUnaryExpression<T>(expr)
476 virtual void eval(T& value, const simgear::expression::Binding* b) const
477 { value = getOperand()->getValue(b); value = value*value; }
479 using SGUnaryExpression<T>::getOperand;
483 class SGSqrtExpression : public SGUnaryExpression<T> {
485 SGSqrtExpression(SGExpression<T>* expr = 0)
486 : SGUnaryExpression<T>(expr)
489 virtual void eval(T& value, const simgear::expression::Binding* b) const
490 { value = sqrt(getOperand()->getValue(b)); }
492 using SGUnaryExpression<T>::getOperand;
496 class SGTanExpression : public SGUnaryExpression<T> {
498 SGTanExpression(SGExpression<T>* expr = 0)
499 : SGUnaryExpression<T>(expr)
502 virtual void eval(T& value, const simgear::expression::Binding* b) const
503 { value = tan(getOperand()->getValue(b)); }
505 using SGUnaryExpression<T>::getOperand;
509 class SGTanhExpression : public SGUnaryExpression<T> {
511 SGTanhExpression(SGExpression<T>* expr = 0)
512 : SGUnaryExpression<T>(expr)
515 virtual void eval(T& value, const simgear::expression::Binding* b) const
516 { value = tanh(getOperand()->getValue(b)); }
518 using SGUnaryExpression<T>::getOperand;
522 class SGScaleExpression : public SGUnaryExpression<T> {
524 SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
525 : SGUnaryExpression<T>(expr), _scale(scale)
527 void setScale(const T& scale)
529 const T& getScale() const
532 virtual void eval(T& value, const simgear::expression::Binding* b) const
533 { value = _scale * getOperand()->getValue(b); }
535 virtual SGExpression<T>* simplify()
538 return getOperand()->simplify();
539 return SGUnaryExpression<T>::simplify();
542 using SGUnaryExpression<T>::getOperand;
548 class SGBiasExpression : public SGUnaryExpression<T> {
550 SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
551 : SGUnaryExpression<T>(expr), _bias(bias)
554 void setBias(const T& bias)
556 const T& getBias() const
559 virtual void eval(T& value, const simgear::expression::Binding* b) const
560 { value = _bias + getOperand()->getValue(b); }
562 virtual SGExpression<T>* simplify()
565 return getOperand()->simplify();
566 return SGUnaryExpression<T>::simplify();
569 using SGUnaryExpression<T>::getOperand;
575 class SGInterpTableExpression : public SGUnaryExpression<T> {
577 SGInterpTableExpression(SGExpression<T>* expr,
578 const SGInterpTable* interpTable) :
579 SGUnaryExpression<T>(expr),
580 _interpTable(interpTable)
583 virtual void eval(T& value, const simgear::expression::Binding* b) const
586 value = _interpTable->interpolate(getOperand()->getValue(b));
589 using SGUnaryExpression<T>::getOperand;
591 SGSharedPtr<SGInterpTable const> _interpTable;
595 class SGClipExpression : public SGUnaryExpression<T> {
597 SGClipExpression(SGExpression<T>* expr)
598 : SGUnaryExpression<T>(expr),
599 _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
600 _clipMax(SGLimits<T>::max())
602 SGClipExpression(SGExpression<T>* expr,
603 const T& clipMin, const T& clipMax)
604 : SGUnaryExpression<T>(expr),
609 void setClipMin(const T& clipMin)
610 { _clipMin = clipMin; }
611 const T& getClipMin() const
614 void setClipMax(const T& clipMax)
615 { _clipMax = clipMax; }
616 const T& getClipMax() const
619 virtual void eval(T& value, const simgear::expression::Binding* b) const
621 value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
624 virtual SGExpression<T>* simplify()
626 if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
627 _clipMax >= SGLimits<T>::max())
628 return getOperand()->simplify();
629 return SGUnaryExpression<T>::simplify();
632 using SGUnaryExpression<T>::getOperand;
639 class SGStepExpression : public SGUnaryExpression<T> {
641 SGStepExpression(SGExpression<T>* expr = 0,
642 const T& step = T(1), const T& scroll = T(0))
643 : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
646 void setStep(const T& step)
648 const T& getStep() const
651 void setScroll(const T& scroll)
652 { _scroll = scroll; }
653 const T& getScroll() const
656 virtual void eval(T& value, const simgear::expression::Binding* b) const
657 { value = apply_mods(getOperand()->getValue(b)); }
659 using SGUnaryExpression<T>::getOperand;
662 T apply_mods(T property) const
668 // calculate scroll amount (for odometer like movement)
669 T remainder = _step - fmod(fabs(property), _step);
670 if (remainder < _scroll) {
671 scrollval = (_scroll - remainder) / _scroll * _step;
674 // apply stepping of input value
676 modprop = ((floor(property/_step) * _step) + scrollval);
678 modprop = ((ceil(property/_step) * _step) + scrollval);
690 class SGEnableExpression : public SGUnaryExpression<T> {
692 SGEnableExpression(SGExpression<T>* expr = 0,
693 SGCondition* enable = 0,
694 const T& disabledValue = T(0))
695 : SGUnaryExpression<T>(expr),
697 _disabledValue(disabledValue)
700 const T& getDisabledValue() const
701 { return _disabledValue; }
702 void setDisabledValue(const T& disabledValue)
703 { _disabledValue = disabledValue; }
705 virtual void eval(T& value, const simgear::expression::Binding* b) const
708 value = getOperand()->getValue(b);
710 value = _disabledValue;
713 virtual SGExpression<T>* simplify()
716 return getOperand()->simplify();
717 return SGUnaryExpression<T>::simplify();
720 using SGUnaryExpression<T>::getOperand;
722 SGSharedPtr<SGCondition> _enable;
727 class SGAtan2Expression : public SGBinaryExpression<T> {
729 SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
730 : SGBinaryExpression<T>(expr0, expr1)
732 virtual void eval(T& value, const simgear::expression::Binding* b) const
733 { value = atan2(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
734 using SGBinaryExpression<T>::getOperand;
738 class SGDivExpression : public SGBinaryExpression<T> {
740 SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
741 : SGBinaryExpression<T>(expr0, expr1)
743 virtual void eval(T& value, const simgear::expression::Binding* b) const
744 { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
745 using SGBinaryExpression<T>::getOperand;
749 class SGModExpression : public SGBinaryExpression<T> {
751 SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
752 : SGBinaryExpression<T>(expr0, expr1)
754 virtual void eval(T& value, const simgear::expression::Binding* b) const
755 { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
756 using SGBinaryExpression<T>::getOperand;
758 int mod(const int& v0, const int& v1) const
760 float mod(const float& v0, const float& v1) const
761 { return fmod(v0, v1); }
762 double mod(const double& v0, const double& v1) const
763 { return fmod(v0, v1); }
767 class SGPowExpression : public SGBinaryExpression<T> {
769 SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
770 : SGBinaryExpression<T>(expr0, expr1)
772 virtual void eval(T& value, const simgear::expression::Binding* b) const
773 { value = pow(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
774 using SGBinaryExpression<T>::getOperand;
778 class SGSumExpression : public SGNaryExpression<T> {
782 SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
783 : SGNaryExpression<T>(expr0, expr1)
785 virtual void eval(T& value, const simgear::expression::Binding* b) const
788 unsigned sz = SGNaryExpression<T>::getNumOperands();
789 for (unsigned i = 0; i < sz; ++i)
790 value += getOperand(i)->getValue(b);
792 using SGNaryExpression<T>::getValue;
793 using SGNaryExpression<T>::getOperand;
797 class SGProductExpression : public SGNaryExpression<T> {
799 SGProductExpression()
801 SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
802 : SGNaryExpression<T>(expr0, expr1)
804 virtual void eval(T& value, const simgear::expression::Binding* b) const
807 unsigned sz = SGNaryExpression<T>::getNumOperands();
808 for (unsigned i = 0; i < sz; ++i)
809 value *= getOperand(i)->getValue(b);
811 using SGNaryExpression<T>::getValue;
812 using SGNaryExpression<T>::getOperand;
816 class SGMinExpression : public SGNaryExpression<T> {
820 SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
821 : SGNaryExpression<T>(expr0, expr1)
823 virtual void eval(T& value, const simgear::expression::Binding* b) const
825 unsigned sz = SGNaryExpression<T>::getNumOperands();
829 value = getOperand(0)->getValue(b);
830 for (unsigned i = 1; i < sz; ++i)
831 value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
833 using SGNaryExpression<T>::getOperand;
837 class SGMaxExpression : public SGNaryExpression<T> {
841 SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
842 : SGNaryExpression<T>(expr0, expr1)
844 virtual void eval(T& value, const simgear::expression::Binding* b) const
846 unsigned sz = SGNaryExpression<T>::getNumOperands();
850 value = getOperand(0)->getValue(b);
851 for (unsigned i = 1; i < sz; ++i)
852 value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
854 using SGNaryExpression<T>::getOperand;
857 typedef SGExpression<int> SGExpressioni;
858 typedef SGExpression<float> SGExpressionf;
859 typedef SGExpression<double> SGExpressiond;
860 typedef SGExpression<bool> SGExpressionb;
863 * Global function to make an expression out of properties.
867 <clipMax>79</clipMax>
871 <property>sim/model/whatever-rad</property>
873 <property>sim/model/someother-deg</property>
879 will evaluate to an expression:
881 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
885 SGReadIntExpression(SGPropertyNode *inputRoot,
886 const SGPropertyNode *configNode);
889 SGReadFloatExpression(SGPropertyNode *inputRoot,
890 const SGPropertyNode *configNode);
892 SGExpression<double>*
893 SGReadDoubleExpression(SGPropertyNode *inputRoot,
894 const SGPropertyNode *configNode);
897 SGReadBoolExpression(SGPropertyNode *inputRoot,
898 const SGPropertyNode *configNode);
904 struct ParseError : public sg_exception
906 ParseError(const string& message = std::string())
907 : sg_exception(message) {}
910 // Support for binding variables around an expression.
914 virtual ~Binding() {}
915 const virtual Value* getBindings() const = 0;
916 virtual Value* getBindings() = 0;
919 class VariableLengthBinding : public Binding
922 const Value* getBindings() const
924 if (_bindings.empty())
927 return &_bindings[0];
931 if (_bindings.empty())
934 return &_bindings[0];
936 std::vector<Value> _bindings;
939 template<int Size> class FixedLengthBinding : public Binding
944 return &_bindings[0];
946 const Value* getBindings() const
948 return &_bindings[0];
950 Value _bindings[Size];
953 struct VariableBinding
955 VariableBinding() : type(expression::DOUBLE), location(-1) {}
957 VariableBinding(const std::string& name_, expression::Type type_,
959 : name(name_), type(type_), location(location_)
963 expression::Type type;
970 int addBinding(const std::string& name, expression::Type type);
971 bool findBinding(const string& name, VariableBinding& result) const;
972 std::vector<VariableBinding> bindings;
977 typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
979 void addParser(const std::string& name, exp_parser parser)
981 getParserMap().insert(std::make_pair(name, parser));
983 Expression* read(const SGPropertyNode* exp)
985 ParserMap& map = getParserMap();
986 ParserMap::iterator itr = map.find(exp->getName());
987 if (itr == map.end())
988 throw ParseError(string("unknown expression ") + exp->getName());
989 exp_parser parser = itr->second;
990 return (*parser)(exp, this);
992 // XXX vector of SGSharedPtr?
993 bool readChildren(const SGPropertyNode* exp,
994 std::vector<Expression*>& result);
996 * Function that parses a property tree, producing an expression.
998 typedef std::map<const std::string, exp_parser> ParserMap;
999 virtual ParserMap& getParserMap() = 0;
1001 * After an expression is parsed, the binding layout may contain
1002 * references that need to be bound during evaluation.
1004 BindingLayout& getBindingLayout() { return _bindingLayout; }
1006 BindingLayout _bindingLayout;
1009 class ExpressionParser : public Parser
1012 ParserMap& getParserMap() { return _parserTable; }
1013 static void addExpParser(const std::string&, exp_parser);
1015 static ParserMap _parserTable;
1019 * Constructor for registering parser functions.
1021 struct ExpParserRegistrar
1023 ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1025 ExpressionParser::addExpParser(token, parser);
1032 * Access a variable definition. Use a location from a BindingLayout.
1034 template<typename T>
1035 class VariableExpression : public ::SGExpression<T> {
1037 VariableExpression(int location) : _location(location) {}
1038 virtual ~VariableExpression() {}
1039 virtual void eval(T& value, const simgear::expression::Binding* b) const
1041 const expression::Value* values = b->getBindings();
1042 value = *reinterpret_cast<const T *>(&values[_location].val);
1050 * An n-ary expression where the types of the argument aren't the
1051 * same as the return type.
1053 template<typename T, typename OpType>
1054 class GeneralNaryExpression : public ::SGExpression<T> {
1056 typedef OpType operand_type;
1057 unsigned getNumOperands() const
1058 { return _expressions.size(); }
1059 const ::SGExpression<OpType>* getOperand(unsigned i) const
1060 { return _expressions[i]; }
1061 ::SGExpression<OpType>* getOperand(unsigned i)
1062 { return _expressions[i]; }
1063 unsigned addOperand(::SGExpression<OpType>* expression)
1066 return ~unsigned(0);
1067 _expressions.push_back(expression);
1068 return _expressions.size() - 1;
1071 template<typename Iter>
1072 void addOperands(Iter begin, Iter end)
1074 for (Iter iter = begin; iter != end; ++iter)
1076 addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1080 virtual bool isConst() const
1082 for (unsigned i = 0; i < _expressions.size(); ++i)
1083 if (!_expressions[i]->isConst())
1087 virtual ::SGExpression<T>* simplify()
1089 for (unsigned i = 0; i < _expressions.size(); ++i)
1090 _expressions[i] = _expressions[i]->simplify();
1091 return SGExpression<T>::simplify();
1094 simgear::expression::Type getOperandType() const
1096 return simgear::expression::TypeTraits<OpType>::typeTag;
1100 GeneralNaryExpression()
1102 GeneralNaryExpression(::SGExpression<OpType>* expr0,
1103 ::SGExpression<OpType>* expr1)
1104 { addOperand(expr0); addOperand(expr1); }
1106 std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1110 * A predicate that wraps, for example the STL template predicate
1111 * expressions like std::equal_to.
1113 template<typename OpType, template<typename PredOp> class Pred>
1114 class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1116 PredicateExpression()
1119 PredicateExpression(::SGExpression<OpType>* expr0,
1120 ::SGExpression<OpType>* expr1)
1121 : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1124 virtual void eval(bool& value, const simgear::expression::Binding* b) const
1126 unsigned sz = this->getNumOperands();
1129 value = _pred(this->getOperand(0)->getValue(b),
1130 this->getOperand(1)->getValue(b));
1136 template<template<typename OT> class Pred, typename OpType>
1137 PredicateExpression<OpType, Pred>*
1138 makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1140 return new PredicateExpression<OpType, Pred>(op1, op2);
1143 template<typename OpType>
1144 class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1147 EqualToExpression() {}
1148 EqualToExpression(::SGExpression<OpType>* expr0,
1149 ::SGExpression<OpType>* expr1)
1150 : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1155 template<typename OpType>
1156 class LessExpression : public PredicateExpression<OpType, std::less>
1160 LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1161 : PredicateExpression<OpType, std::less>(expr0, expr1)
1166 template<typename OpType>
1167 class LessEqualExpression
1168 : public PredicateExpression<OpType, std::less_equal>
1171 LessEqualExpression() {}
1172 LessEqualExpression(::SGExpression<OpType>* expr0,
1173 ::SGExpression<OpType>* expr1)
1174 : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1179 class NotExpression : public ::SGUnaryExpression<bool>
1182 NotExpression(::SGExpression<bool>* expr = 0)
1183 : ::SGUnaryExpression<bool>(expr)
1186 void eval(bool& value, const expression::Binding* b) const
1188 value = !getOperand()->getValue(b);
1192 class OrExpression : public ::SGNaryExpression<bool>
1195 void eval(bool& value, const expression::Binding* b) const
1198 for (int i = 0; i < getNumOperands(); ++i) {
1199 value = value || getOperand(i)->getValue(b);
1206 class AndExpression : public ::SGNaryExpression<bool>
1209 void eval(bool& value, const expression::Binding* b) const
1212 for (int i = 0; i < getNumOperands(); ++i) {
1213 value = value && getOperand(i)->getValue(b);
1221 * Convert an operand from OpType to T.
1223 template<typename T, typename OpType>
1224 class ConvertExpression : public GeneralNaryExpression<T, OpType>
1227 ConvertExpression() {}
1228 ConvertExpression(::SGExpression<OpType>* expr0)
1232 virtual void eval(T& value, const simgear::expression::Binding* b) const
1234 typename ConvertExpression::operand_type result;
1235 this->_expressions.at(0)->eval(result, b);
1240 #endif // _SG_EXPRESSION_HXX