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,
23 # include <simgear_config.h>
26 #include "SGExpression.hxx"
27 #include "Singleton.hxx"
35 #include <boost/bind.hpp>
36 #include <cstring> // for strcmp
38 #include <simgear/props/props.hxx>
45 const expression::Value evalValue(const Expression* exp,
46 const expression::Binding* b)
49 static_cast<const SGExpression<T>*>(exp)->eval(val, b);
50 return expression::Value(val);
53 const expression::Value eval(const Expression* exp,
54 const expression::Binding* b)
56 using namespace expression;
57 switch (exp->getType()) {
59 return evalValue<bool>(exp, b);
61 return evalValue<int>(exp, b);
63 return evalValue<float>(exp, b);
65 return evalValue<double>(exp, b);
67 throw "invalid type.";
74 SGReadValueFromString(const char* str, T& value)
77 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
81 s.str(std::string(str));
84 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
92 SGReadValueFromString(const char* str, bool& value)
95 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
99 s.str(std::string(str));
105 if (!SGReadValueFromString(str, stdstr))
108 if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
112 if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
121 SGReadValueFromContent(const SGPropertyNode *node, T& value)
125 return SGReadValueFromString(node->getStringValue(), value);
129 static SGExpression<T>*
130 SGReadExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
134 SGReadNaryOperands(SGNaryExpression<T>* nary,
135 SGPropertyNode *inputRoot, const SGPropertyNode *expression)
137 for (int i = 0; i < expression->nChildren(); ++i) {
138 SGExpression<T>* inputExpression;
139 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(i));
140 if (!inputExpression)
142 nary->addOperand(inputExpression);
147 // template<typename T>
148 // static SGExpression<T>*
149 // SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
154 // std::string name = expression->getName();
155 // if (name == "value") {
157 // if (!SGReadValueFromContent(expression, value)) {
158 // SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
161 // return new SGConstExpression<T>(value);
168 static SGExpression<T>*
169 SGReadExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
174 std::string name = expression->getName();
176 if (name == "value") {
178 if (!SGReadValueFromContent(expression, value)) {
179 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
182 return new SGConstExpression<T>(value);
185 if (name == "property") {
187 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
188 "No inputRoot argument given!");
191 if (!expression->getStringValue()) {
192 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
195 SGPropertyNode* inputNode;
196 inputNode = inputRoot->getNode(expression->getStringValue(), true);
197 return new SGPropertyExpression<T>(inputNode);
200 if (name == "abs" || name == "fabs") {
201 if (expression->nChildren() != 1) {
202 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
205 SGSharedPtr<SGExpression<T> > inputExpression;
206 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
207 if (!inputExpression) {
208 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
211 return new SGAbsExpression<T>(inputExpression);
215 if (expression->nChildren() != 1) {
216 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
219 SGSharedPtr<SGExpression<T> > inputExpression;
220 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
221 if (!inputExpression) {
222 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
225 return new SGSqrExpression<T>(inputExpression);
228 if (name == "clip") {
229 if (expression->nChildren() != 3) {
230 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
233 const SGPropertyNode* minProperty = expression->getChild("clipMin");
235 if (!SGReadValueFromContent(minProperty, clipMin))
236 clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
238 const SGPropertyNode* maxProperty = expression->getChild("clipMax");
240 if (!SGReadValueFromContent(maxProperty, clipMax))
241 clipMin = SGLimits<T>::max();
243 SGSharedPtr<SGExpression<T> > inputExpression;
244 for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
245 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(i));
246 if (!inputExpression) {
247 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
250 return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
254 if (expression->nChildren() != 2) {
255 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
258 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
259 SGReadExpression<T>(inputRoot, expression->getChild(0)),
260 SGReadExpression<T>(inputRoot, expression->getChild(1))
262 if (!inputExpressions[0] || !inputExpressions[1]) {
263 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
266 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
269 if (expression->nChildren() != 2) {
270 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
273 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
274 SGReadExpression<T>(inputRoot, expression->getChild(0)),
275 SGReadExpression<T>(inputRoot, expression->getChild(1))
277 if (!inputExpressions[0] || !inputExpressions[1]) {
278 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
281 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
285 if (expression->nChildren() < 1) {
286 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
289 SGSumExpression<T>* output = new SGSumExpression<T>;
290 if (!SGReadNaryOperands(output, inputRoot, expression)) {
292 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
298 if (name == "difference" || name == "dif" ) {
299 if (expression->nChildren() < 1) {
300 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
303 SGDifferenceExpression<T>* output = new SGDifferenceExpression<T>;
304 if (!SGReadNaryOperands(output, inputRoot, expression)) {
306 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
312 if (name == "prod" || name == "product") {
313 if (expression->nChildren() < 1) {
314 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
317 SGProductExpression<T>* output = new SGProductExpression<T>;
318 if (!SGReadNaryOperands(output, inputRoot, expression)) {
320 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
326 if (expression->nChildren() < 1) {
327 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
330 SGMinExpression<T>* output = new SGMinExpression<T>;
331 if (!SGReadNaryOperands(output, inputRoot, expression)) {
333 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
339 if (expression->nChildren() < 1) {
340 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
343 SGMaxExpression<T>* output = new SGMaxExpression<T>;
344 if (!SGReadNaryOperands(output, inputRoot, expression)) {
346 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
352 if (name == "table") {
353 SGInterpTable* tab = new SGInterpTable(expression);
355 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression: malformed table");
359 // find input expression - i.e a child not named 'entry'
360 const SGPropertyNode* inputNode = NULL;
361 for (int i=0; (i<expression->nChildren()) && !inputNode; ++i) {
362 if (strcmp(expression->getChild(i)->getName(), "entry") == 0) {
366 inputNode = expression->getChild(i);
370 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression: no input found");
374 SGSharedPtr<SGExpression<T> > inputExpression;
375 inputExpression = SGReadExpression<T>(inputRoot, inputNode);
376 if (!inputExpression) {
377 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
381 return new SGInterpTableExpression<T>(inputExpression, tab);
384 if (name == "acos") {
385 if (expression->nChildren() != 1) {
386 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
389 SGSharedPtr<SGExpression<T> > inputExpression;
390 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
391 if (!inputExpression) {
392 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
395 return new SGACosExpression<T>(inputExpression);
398 if (name == "asin") {
399 if (expression->nChildren() != 1) {
400 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
403 SGSharedPtr<SGExpression<T> > inputExpression;
404 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
405 if (!inputExpression) {
406 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
409 return new SGASinExpression<T>(inputExpression);
412 if (name == "atan") {
413 if (expression->nChildren() != 1) {
414 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
417 SGSharedPtr<SGExpression<T> > inputExpression;
418 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
419 if (!inputExpression) {
420 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
423 return new SGATanExpression<T>(inputExpression);
426 if (name == "ceil") {
427 if (expression->nChildren() != 1) {
428 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
431 SGSharedPtr<SGExpression<T> > inputExpression;
432 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
433 if (!inputExpression) {
434 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
437 return new SGCeilExpression<T>(inputExpression);
441 if (expression->nChildren() != 1) {
442 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
445 SGSharedPtr<SGExpression<T> > inputExpression;
446 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
447 if (!inputExpression) {
448 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
451 return new SGCosExpression<T>(inputExpression);
454 if (name == "cosh") {
455 if (expression->nChildren() != 1) {
456 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
459 SGSharedPtr<SGExpression<T> > inputExpression;
460 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
461 if (!inputExpression) {
462 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
465 return new SGCoshExpression<T>(inputExpression);
468 if (name == "deg2rad") {
469 if (expression->nChildren() != 1) {
470 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
473 SGSharedPtr<SGExpression<T> > inputExpression;
474 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
475 if (!inputExpression) {
476 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
479 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
483 if (expression->nChildren() != 1) {
484 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
487 SGSharedPtr<SGExpression<T> > inputExpression;
488 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
489 if (!inputExpression) {
490 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
493 return new SGExpExpression<T>(inputExpression);
496 if (name == "floor") {
497 if (expression->nChildren() != 1) {
498 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
501 SGSharedPtr<SGExpression<T> > inputExpression;
502 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
503 if (!inputExpression) {
504 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
507 return new SGFloorExpression<T>(inputExpression);
511 if (expression->nChildren() != 1) {
512 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
515 SGSharedPtr<SGExpression<T> > inputExpression;
516 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
517 if (!inputExpression) {
518 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
521 return new SGLogExpression<T>(inputExpression);
524 if (name == "log10") {
525 if (expression->nChildren() != 1) {
526 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
529 SGSharedPtr<SGExpression<T> > inputExpression;
530 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
531 if (!inputExpression) {
532 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
535 return new SGLog10Expression<T>(inputExpression);
538 if (name == "rad2deg") {
539 if (expression->nChildren() != 1) {
540 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
543 SGSharedPtr<SGExpression<T> > inputExpression;
544 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
545 if (!inputExpression) {
546 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
549 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
553 if (expression->nChildren() != 1) {
554 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
557 SGSharedPtr<SGExpression<T> > inputExpression;
558 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
559 if (!inputExpression) {
560 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
563 return new SGSinExpression<T>(inputExpression);
566 if (name == "sinh") {
567 if (expression->nChildren() != 1) {
568 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
571 SGSharedPtr<SGExpression<T> > inputExpression;
572 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
573 if (!inputExpression) {
574 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
577 return new SGSinhExpression<T>(inputExpression);
580 if (name == "sqrt") {
581 if (expression->nChildren() != 1) {
582 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
585 SGSharedPtr<SGExpression<T> > inputExpression;
586 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
587 if (!inputExpression) {
588 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
591 return new SGSqrtExpression<T>(inputExpression);
595 if (expression->nChildren() != 1) {
596 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
599 SGSharedPtr<SGExpression<T> > inputExpression;
600 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
601 if (!inputExpression) {
602 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
605 return new SGTanExpression<T>(inputExpression);
608 if (name == "tanh") {
609 if (expression->nChildren() != 1) {
610 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
613 SGSharedPtr<SGExpression<T> > inputExpression;
614 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
615 if (!inputExpression) {
616 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
619 return new SGTanhExpression<T>(inputExpression);
622 // if (name == "step") {
624 // if (name == "condition") {
627 if (name == "atan2") {
628 if (expression->nChildren() != 2) {
629 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
632 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
633 SGReadExpression<T>(inputRoot, expression->getChild(0)),
634 SGReadExpression<T>(inputRoot, expression->getChild(1))
636 if (!inputExpressions[0] || !inputExpressions[1]) {
637 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
640 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
643 if (expression->nChildren() != 2) {
644 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
647 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
648 SGReadExpression<T>(inputRoot, expression->getChild(0)),
649 SGReadExpression<T>(inputRoot, expression->getChild(1))
651 if (!inputExpressions[0] || !inputExpressions[1]) {
652 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
655 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
658 if (expression->nChildren() != 2) {
659 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
662 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
663 SGReadExpression<T>(inputRoot, expression->getChild(0)),
664 SGReadExpression<T>(inputRoot, expression->getChild(1))
666 if (!inputExpressions[0] || !inputExpressions[1]) {
667 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
670 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
673 if (expression->nChildren() != 2) {
674 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
677 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
678 SGReadExpression<T>(inputRoot, expression->getChild(0)),
679 SGReadExpression<T>(inputRoot, expression->getChild(1))
681 if (!inputExpressions[0] || !inputExpressions[1]) {
682 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
685 return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
692 SGReadIntExpression(SGPropertyNode *inputRoot,
693 const SGPropertyNode *configNode)
694 { return SGReadExpression<int>(inputRoot, configNode); }
697 SGReadFloatExpression(SGPropertyNode *inputRoot,
698 const SGPropertyNode *configNode)
699 { return SGReadExpression<float>(inputRoot, configNode); }
701 SGExpression<double>*
702 SGReadDoubleExpression(SGPropertyNode *inputRoot,
703 const SGPropertyNode *configNode)
704 { return SGReadExpression<double>(inputRoot, configNode); }
706 // SGExpression<bool>*
707 // SGReadBoolExpression(SGPropertyNode *inputRoot,
708 // const SGPropertyNode *configNode)
709 // { return SGReadBExpression<bool>(inputRoot, configNode); }
716 bool Parser::readChildren(const SGPropertyNode* exp,
717 vector<Expression*>& result)
719 for (int i = 0; i < exp->nChildren(); ++i)
720 result.push_back(read(exp->getChild(i)));
724 void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
726 ParserMapSingleton::instance()
727 ->_parserTable.insert(std::make_pair(token, parsefn));
730 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
732 switch (exp->getType()) {
734 return new SGConstExpression<bool>(getValue<bool>(exp));
736 return new SGConstExpression<int>(getValue<int>(exp));
738 return new SGConstExpression<float>(getValue<float>(exp));
740 return new SGConstExpression<double>(getValue<double>(exp));
746 ExpParserRegistrar valueRegistrar("value", valueParser);
748 template<typename T, typename OpType>
749 inline Expression* makeConvert(Expression* e)
751 return new ConvertExpression<T,
752 OpType>(static_cast<SGExpression<OpType>*>(e));
755 Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
757 vector<Expression*>::iterator maxElem
758 = max_element(exps.begin(), exps.end());
759 Type maxType = (*maxElem)->getType();
760 Type resultType = minType < maxType ? maxType : minType;
761 for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
764 if ((*itr)->getType() != resultType) {
765 switch ((*itr)->getType()) {
767 switch (resultType) {
769 *itr = makeConvert<int, bool>(*itr);
772 *itr = makeConvert<float, bool>(*itr);
775 *itr = makeConvert<double, bool>(*itr);
782 switch (resultType) {
784 *itr = makeConvert<float, int>(*itr);
787 *itr = makeConvert<double, int>(*itr);
794 *itr = makeConvert<double, float>(*itr);
804 template<template<typename OpType> class Expr>
805 Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
807 switch (operandType) {
810 Expr<bool> *expr = new Expr<bool>();
811 expr->addOperands(children.begin(), children.end());
816 Expr<int> *expr = new Expr<int>();
817 expr->addOperands(children.begin(), children.end());
822 Expr<float> *expr = new Expr<float>();
823 expr->addOperands(children.begin(), children.end());
828 Expr<double> *expr = new Expr<double>();
829 expr->addOperands(children.begin(), children.end());
837 template<template<typename OpType> class PredExp>
838 Expression* predParser(const SGPropertyNode* exp, Parser* parser)
840 vector<Expression*> children;
841 parser->readChildren(exp, children);
842 Type operandType = promoteAndConvert(children);
843 return makeTypedOperandExp<PredExp>(operandType, children);
846 ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
847 ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
848 ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
850 template<typename Logicop>
851 Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
853 using namespace boost;
854 vector<Expression*> children;
855 parser->readChildren(exp, children);
856 vector<Expression*>::iterator notBool =
857 find_if(children.begin(), children.end(),
858 boost::bind(&Expression::getType, _1) != BOOL);
859 if (notBool != children.end())
860 throw("non boolean operand to logical expression");
861 Logicop *expr = new Logicop;
862 expr->addOperands(children.begin(), children.end());
866 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
867 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
869 int BindingLayout::addBinding(const string& name, Type type)
872 vector<VariableBinding>::iterator itr
873 = find_if(bindings.begin(), bindings.end(),
874 boost::bind(&VariableBinding::name, _1) == name);
875 if (itr != bindings.end())
876 return itr->location;
877 int result = bindings.size();
878 bindings.push_back(VariableBinding(name, type, bindings.size()));
882 bool BindingLayout::findBinding(const std::string& name,
883 VariableBinding& result) const
886 using namespace boost;
887 vector<VariableBinding>::const_iterator itr
888 = find_if(bindings.begin(), bindings.end(),
889 boost::bind(&VariableBinding::name, _1) == name);
890 if (itr != bindings.end()) {