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>
37 #include <simgear/props/props.hxx>
44 const expression::Value evalValue(const Expression* exp,
45 const expression::Binding* b)
48 static_cast<const SGExpression<T>*>(exp)->eval(val, b);
49 return expression::Value(val);
52 const expression::Value eval(const Expression* exp,
53 const expression::Binding* b)
55 using namespace expression;
56 switch (exp->getType()) {
58 return evalValue<bool>(exp, b);
60 return evalValue<int>(exp, b);
62 return evalValue<float>(exp, b);
64 return evalValue<double>(exp, b);
66 throw "invalid type.";
73 SGReadValueFromString(const char* str, T& value)
76 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
80 s.str(std::string(str));
83 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
91 SGReadValueFromString(const char* str, bool& value)
94 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
98 s.str(std::string(str));
104 if (!SGReadValueFromString(str, stdstr))
107 if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
111 if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
120 SGReadValueFromContent(const SGPropertyNode *node, T& value)
124 return SGReadValueFromString(node->getStringValue(), value);
128 static SGExpression<T>*
129 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
133 SGReadNaryOperands(SGNaryExpression<T>* nary,
134 SGPropertyNode *inputRoot, const SGPropertyNode *expression)
136 for (int i = 0; i < expression->nChildren(); ++i) {
137 SGExpression<T>* inputExpression;
138 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
139 if (!inputExpression)
141 nary->addOperand(inputExpression);
146 // template<typename T>
147 // static SGExpression<T>*
148 // SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
153 // std::string name = expression->getName();
154 // if (name == "value") {
156 // if (!SGReadValueFromContent(expression, value)) {
157 // SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
160 // return new SGConstExpression<T>(value);
167 static SGExpression<T>*
168 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
173 std::string name = expression->getName();
174 if (name == "value") {
176 if (!SGReadValueFromContent(expression, value)) {
177 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
180 return new SGConstExpression<T>(value);
183 if (name == "property") {
185 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
186 "No inputRoot argument given!");
189 if (!expression->getStringValue()) {
190 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
193 SGPropertyNode* inputNode;
194 inputNode = inputRoot->getNode(expression->getStringValue(), true);
195 return new SGPropertyExpression<T>(inputNode);
198 if (name == "abs" || name == "fabs") {
199 if (expression->nChildren() != 1) {
200 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
203 SGSharedPtr<SGExpression<T> > inputExpression;
204 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
205 if (!inputExpression) {
206 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
209 return new SGAbsExpression<T>(inputExpression);
213 if (expression->nChildren() != 1) {
214 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
217 SGSharedPtr<SGExpression<T> > inputExpression;
218 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
219 if (!inputExpression) {
220 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
223 return new SGSqrExpression<T>(inputExpression);
226 if (name == "clip") {
227 if (expression->nChildren() != 3) {
228 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
231 const SGPropertyNode* minProperty = expression->getChild("clipMin");
233 if (!SGReadValueFromContent(minProperty, clipMin))
234 clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
236 const SGPropertyNode* maxProperty = expression->getChild("clipMax");
238 if (!SGReadValueFromContent(maxProperty, clipMax))
239 clipMin = SGLimits<T>::max();
241 SGSharedPtr<SGExpression<T> > inputExpression;
242 for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
243 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
244 if (!inputExpression) {
245 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
248 return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
252 if (expression->nChildren() != 2) {
253 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
256 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
257 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
258 SGReadIExpression<T>(inputRoot, expression->getChild(1))
260 if (!inputExpressions[0] || !inputExpressions[1]) {
261 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
264 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
267 if (expression->nChildren() != 2) {
268 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
271 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
272 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
273 SGReadIExpression<T>(inputRoot, expression->getChild(1))
275 if (!inputExpressions[0] || !inputExpressions[1]) {
276 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
279 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
283 if (expression->nChildren() < 1) {
284 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
287 SGSumExpression<T>* output = new SGSumExpression<T>;
288 if (!SGReadNaryOperands(output, inputRoot, expression)) {
290 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
295 if (name == "prod" || name == "product") {
296 if (expression->nChildren() < 1) {
297 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
300 SGProductExpression<T>* output = new SGProductExpression<T>;
301 if (!SGReadNaryOperands(output, inputRoot, expression)) {
303 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
309 if (expression->nChildren() < 1) {
310 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
313 SGMinExpression<T>* output = new SGMinExpression<T>;
314 if (!SGReadNaryOperands(output, inputRoot, expression)) {
316 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
322 if (expression->nChildren() < 1) {
323 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
326 SGMaxExpression<T>* output = new SGMaxExpression<T>;
327 if (!SGReadNaryOperands(output, inputRoot, expression)) {
329 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
335 if (name == "table") {
336 SGInterpTable* tab = new SGInterpTable(expression);
338 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression: malformed table");
342 // find input expression - i.e a child not named 'entry'
343 const SGPropertyNode* inputNode = NULL;
344 for (int i=0; (i<expression->nChildren()) && !inputNode; ++i) {
345 if (strcmp(expression->getChild(i)->getName(), "entry") == 0) {
349 inputNode = expression->getChild(i);
353 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression: no input found");
357 SGSharedPtr<SGExpression<T> > inputExpression;
358 inputExpression = SGReadIExpression<T>(inputRoot, inputNode);
359 if (!inputExpression) {
360 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
364 return new SGInterpTableExpression<T>(inputExpression, tab);
372 static SGExpression<T>*
373 SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
375 SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
382 std::string name = expression->getName();
383 if (name == "acos") {
384 if (expression->nChildren() != 1) {
385 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
388 SGSharedPtr<SGExpression<T> > inputExpression;
389 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
390 if (!inputExpression) {
391 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
394 return new SGACosExpression<T>(inputExpression);
397 if (name == "asin") {
398 if (expression->nChildren() != 1) {
399 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
402 SGSharedPtr<SGExpression<T> > inputExpression;
403 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
404 if (!inputExpression) {
405 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
408 return new SGASinExpression<T>(inputExpression);
411 if (name == "atan") {
412 if (expression->nChildren() != 1) {
413 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
416 SGSharedPtr<SGExpression<T> > inputExpression;
417 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
418 if (!inputExpression) {
419 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
422 return new SGATanExpression<T>(inputExpression);
425 if (name == "ceil") {
426 if (expression->nChildren() != 1) {
427 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
430 SGSharedPtr<SGExpression<T> > inputExpression;
431 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
432 if (!inputExpression) {
433 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
436 return new SGCeilExpression<T>(inputExpression);
440 if (expression->nChildren() != 1) {
441 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
444 SGSharedPtr<SGExpression<T> > inputExpression;
445 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
446 if (!inputExpression) {
447 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
450 return new SGCosExpression<T>(inputExpression);
453 if (name == "cosh") {
454 if (expression->nChildren() != 1) {
455 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
458 SGSharedPtr<SGExpression<T> > inputExpression;
459 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
460 if (!inputExpression) {
461 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
464 return new SGCoshExpression<T>(inputExpression);
467 if (name == "deg2rad") {
468 if (expression->nChildren() != 1) {
469 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
472 SGSharedPtr<SGExpression<T> > inputExpression;
473 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
474 if (!inputExpression) {
475 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
478 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
482 if (expression->nChildren() != 1) {
483 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
486 SGSharedPtr<SGExpression<T> > inputExpression;
487 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
488 if (!inputExpression) {
489 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
492 return new SGExpExpression<T>(inputExpression);
495 if (name == "floor") {
496 if (expression->nChildren() != 1) {
497 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
500 SGSharedPtr<SGExpression<T> > inputExpression;
501 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
502 if (!inputExpression) {
503 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
506 return new SGFloorExpression<T>(inputExpression);
510 if (expression->nChildren() != 1) {
511 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
514 SGSharedPtr<SGExpression<T> > inputExpression;
515 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
516 if (!inputExpression) {
517 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
520 return new SGLogExpression<T>(inputExpression);
523 if (name == "log10") {
524 if (expression->nChildren() != 1) {
525 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
528 SGSharedPtr<SGExpression<T> > inputExpression;
529 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
530 if (!inputExpression) {
531 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
534 return new SGLog10Expression<T>(inputExpression);
537 if (name == "rad2deg") {
538 if (expression->nChildren() != 1) {
539 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
542 SGSharedPtr<SGExpression<T> > inputExpression;
543 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
544 if (!inputExpression) {
545 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
548 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
552 if (expression->nChildren() != 1) {
553 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
556 SGSharedPtr<SGExpression<T> > inputExpression;
557 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
558 if (!inputExpression) {
559 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
562 return new SGSinExpression<T>(inputExpression);
565 if (name == "sinh") {
566 if (expression->nChildren() != 1) {
567 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
570 SGSharedPtr<SGExpression<T> > inputExpression;
571 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
572 if (!inputExpression) {
573 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
576 return new SGSinhExpression<T>(inputExpression);
579 if (name == "sqrt") {
580 if (expression->nChildren() != 1) {
581 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
584 SGSharedPtr<SGExpression<T> > inputExpression;
585 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
586 if (!inputExpression) {
587 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
590 return new SGSqrtExpression<T>(inputExpression);
594 if (expression->nChildren() != 1) {
595 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
598 SGSharedPtr<SGExpression<T> > inputExpression;
599 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
600 if (!inputExpression) {
601 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
604 return new SGTanExpression<T>(inputExpression);
607 if (name == "tanh") {
608 if (expression->nChildren() != 1) {
609 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
612 SGSharedPtr<SGExpression<T> > inputExpression;
613 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
614 if (!inputExpression) {
615 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
618 return new SGTanhExpression<T>(inputExpression);
621 // if (name == "step") {
623 // if (name == "condition") {
626 if (name == "atan2") {
627 if (expression->nChildren() != 2) {
628 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
631 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
632 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
633 SGReadFExpression<T>(inputRoot, expression->getChild(1))
635 if (!inputExpressions[0] || !inputExpressions[1]) {
636 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
639 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
642 if (expression->nChildren() != 2) {
643 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
646 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
647 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
648 SGReadFExpression<T>(inputRoot, expression->getChild(1))
650 if (!inputExpressions[0] || !inputExpressions[1]) {
651 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
654 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
657 if (expression->nChildren() != 2) {
658 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
661 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
662 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
663 SGReadFExpression<T>(inputRoot, expression->getChild(1))
665 if (!inputExpressions[0] || !inputExpressions[1]) {
666 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
669 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
672 if (expression->nChildren() != 2) {
673 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
676 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
677 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
678 SGReadIExpression<T>(inputRoot, expression->getChild(1))
680 if (!inputExpressions[0] || !inputExpressions[1]) {
681 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
684 return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
691 SGReadIntExpression(SGPropertyNode *inputRoot,
692 const SGPropertyNode *configNode)
693 { return SGReadIExpression<int>(inputRoot, configNode); }
696 SGReadFloatExpression(SGPropertyNode *inputRoot,
697 const SGPropertyNode *configNode)
698 { return SGReadFExpression<float>(inputRoot, configNode); }
700 SGExpression<double>*
701 SGReadDoubleExpression(SGPropertyNode *inputRoot,
702 const SGPropertyNode *configNode)
703 { return SGReadFExpression<double>(inputRoot, configNode); }
705 // SGExpression<bool>*
706 // SGReadBoolExpression(SGPropertyNode *inputRoot,
707 // const SGPropertyNode *configNode)
708 // { return SGReadBExpression<bool>(inputRoot, configNode); }
715 bool Parser::readChildren(const SGPropertyNode* exp,
716 vector<Expression*>& result)
718 for (int i = 0; i < exp->nChildren(); ++i)
719 result.push_back(read(exp->getChild(i)));
723 void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
725 ParserMapSingleton::instance()
726 ->_parserTable.insert(std::make_pair(token, parsefn));
729 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
731 switch (exp->getType()) {
733 return new SGConstExpression<bool>(getValue<bool>(exp));
735 return new SGConstExpression<int>(getValue<int>(exp));
737 return new SGConstExpression<float>(getValue<float>(exp));
739 return new SGConstExpression<double>(getValue<double>(exp));
745 ExpParserRegistrar valueRegistrar("value", valueParser);
747 template<typename T, typename OpType>
748 inline Expression* makeConvert(Expression* e)
750 return new ConvertExpression<T,
751 OpType>(static_cast<SGExpression<OpType>*>(e));
754 Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
756 vector<Expression*>::iterator maxElem
757 = max_element(exps.begin(), exps.end());
758 Type maxType = (*maxElem)->getType();
759 Type resultType = minType < maxType ? maxType : minType;
760 for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
763 if ((*itr)->getType() != resultType) {
764 switch ((*itr)->getType()) {
766 switch (resultType) {
768 *itr = makeConvert<int, bool>(*itr);
771 *itr = makeConvert<float, bool>(*itr);
774 *itr = makeConvert<double, bool>(*itr);
781 switch (resultType) {
783 *itr = makeConvert<float, int>(*itr);
786 *itr = makeConvert<double, int>(*itr);
793 *itr = makeConvert<double, float>(*itr);
803 template<template<typename OpType> class Expr>
804 Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
806 switch (operandType) {
809 Expr<bool> *expr = new Expr<bool>();
810 expr->addOperands(children.begin(), children.end());
815 Expr<int> *expr = new Expr<int>();
816 expr->addOperands(children.begin(), children.end());
821 Expr<float> *expr = new Expr<float>();
822 expr->addOperands(children.begin(), children.end());
827 Expr<double> *expr = new Expr<double>();
828 expr->addOperands(children.begin(), children.end());
836 template<template<typename OpType> class PredExp>
837 Expression* predParser(const SGPropertyNode* exp, Parser* parser)
839 vector<Expression*> children;
840 parser->readChildren(exp, children);
841 Type operandType = promoteAndConvert(children);
842 return makeTypedOperandExp<PredExp>(operandType, children);
845 ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
846 ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
847 ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
849 template<typename Logicop>
850 Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
852 using namespace boost;
853 vector<Expression*> children;
854 parser->readChildren(exp, children);
855 vector<Expression*>::iterator notBool =
856 find_if(children.begin(), children.end(),
857 boost::bind(&Expression::getType, _1) != BOOL);
858 if (notBool != children.end())
859 throw("non boolean operand to logical expression");
860 Logicop *expr = new Logicop;
861 expr->addOperands(children.begin(), children.end());
865 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
866 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
868 int BindingLayout::addBinding(const string& name, Type type)
871 vector<VariableBinding>::iterator itr
872 = find_if(bindings.begin(), bindings.end(),
873 boost::bind(&VariableBinding::name, _1) == name);
874 if (itr != bindings.end())
875 return itr->location;
876 int result = bindings.size();
877 bindings.push_back(VariableBinding(name, type, bindings.size()));
881 bool BindingLayout::findBinding(const std::string& name,
882 VariableBinding& result) const
885 using namespace boost;
886 vector<VariableBinding>::const_iterator itr
887 = find_if(bindings.begin(), bindings.end(),
888 boost::bind(&VariableBinding::name, _1) == name);
889 if (itr != bindings.end()) {