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.");
340 static SGExpression<T>*
341 SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
343 SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
350 std::string name = expression->getName();
351 if (name == "acos") {
352 if (expression->nChildren() != 1) {
353 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
356 SGSharedPtr<SGExpression<T> > inputExpression;
357 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
358 if (!inputExpression) {
359 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
362 return new SGACosExpression<T>(inputExpression);
365 if (name == "asin") {
366 if (expression->nChildren() != 1) {
367 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
370 SGSharedPtr<SGExpression<T> > inputExpression;
371 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
372 if (!inputExpression) {
373 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
376 return new SGASinExpression<T>(inputExpression);
379 if (name == "atan") {
380 if (expression->nChildren() != 1) {
381 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
384 SGSharedPtr<SGExpression<T> > inputExpression;
385 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
386 if (!inputExpression) {
387 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
390 return new SGATanExpression<T>(inputExpression);
393 if (name == "ceil") {
394 if (expression->nChildren() != 1) {
395 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
398 SGSharedPtr<SGExpression<T> > inputExpression;
399 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
400 if (!inputExpression) {
401 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
404 return new SGCeilExpression<T>(inputExpression);
408 if (expression->nChildren() != 1) {
409 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
412 SGSharedPtr<SGExpression<T> > inputExpression;
413 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
414 if (!inputExpression) {
415 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
418 return new SGCosExpression<T>(inputExpression);
421 if (name == "cosh") {
422 if (expression->nChildren() != 1) {
423 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
426 SGSharedPtr<SGExpression<T> > inputExpression;
427 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
428 if (!inputExpression) {
429 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
432 return new SGCoshExpression<T>(inputExpression);
435 if (name == "deg2rad") {
436 if (expression->nChildren() != 1) {
437 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
440 SGSharedPtr<SGExpression<T> > inputExpression;
441 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
442 if (!inputExpression) {
443 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
446 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
450 if (expression->nChildren() != 1) {
451 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
454 SGSharedPtr<SGExpression<T> > inputExpression;
455 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
456 if (!inputExpression) {
457 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
460 return new SGExpExpression<T>(inputExpression);
463 if (name == "floor") {
464 if (expression->nChildren() != 1) {
465 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
468 SGSharedPtr<SGExpression<T> > inputExpression;
469 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
470 if (!inputExpression) {
471 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
474 return new SGFloorExpression<T>(inputExpression);
478 if (expression->nChildren() != 1) {
479 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
482 SGSharedPtr<SGExpression<T> > inputExpression;
483 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
484 if (!inputExpression) {
485 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
488 return new SGLogExpression<T>(inputExpression);
491 if (name == "log10") {
492 if (expression->nChildren() != 1) {
493 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
496 SGSharedPtr<SGExpression<T> > inputExpression;
497 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
498 if (!inputExpression) {
499 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
502 return new SGLog10Expression<T>(inputExpression);
505 if (name == "rad2deg") {
506 if (expression->nChildren() != 1) {
507 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
510 SGSharedPtr<SGExpression<T> > inputExpression;
511 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
512 if (!inputExpression) {
513 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
516 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
520 if (expression->nChildren() != 1) {
521 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
524 SGSharedPtr<SGExpression<T> > inputExpression;
525 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
526 if (!inputExpression) {
527 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
530 return new SGSinExpression<T>(inputExpression);
533 if (name == "sinh") {
534 if (expression->nChildren() != 1) {
535 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
538 SGSharedPtr<SGExpression<T> > inputExpression;
539 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
540 if (!inputExpression) {
541 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
544 return new SGSinhExpression<T>(inputExpression);
547 if (name == "sqrt") {
548 if (expression->nChildren() != 1) {
549 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
552 SGSharedPtr<SGExpression<T> > inputExpression;
553 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
554 if (!inputExpression) {
555 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
558 return new SGSqrtExpression<T>(inputExpression);
562 if (expression->nChildren() != 1) {
563 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
566 SGSharedPtr<SGExpression<T> > inputExpression;
567 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
568 if (!inputExpression) {
569 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
572 return new SGTanExpression<T>(inputExpression);
575 if (name == "tanh") {
576 if (expression->nChildren() != 1) {
577 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
580 SGSharedPtr<SGExpression<T> > inputExpression;
581 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
582 if (!inputExpression) {
583 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
586 return new SGTanhExpression<T>(inputExpression);
589 // if (name == "table") {
591 // if (name == "step") {
593 // if (name == "condition") {
596 if (name == "atan2") {
597 if (expression->nChildren() != 2) {
598 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
601 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
602 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
603 SGReadFExpression<T>(inputRoot, expression->getChild(1))
605 if (!inputExpressions[0] || !inputExpressions[1]) {
606 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
609 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
612 if (expression->nChildren() != 2) {
613 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
616 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
617 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
618 SGReadFExpression<T>(inputRoot, expression->getChild(1))
620 if (!inputExpressions[0] || !inputExpressions[1]) {
621 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
624 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
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 SGModExpression<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 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
648 SGReadIExpression<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 SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
661 SGReadIntExpression(SGPropertyNode *inputRoot,
662 const SGPropertyNode *configNode)
663 { return SGReadIExpression<int>(inputRoot, configNode); }
666 SGReadFloatExpression(SGPropertyNode *inputRoot,
667 const SGPropertyNode *configNode)
668 { return SGReadFExpression<float>(inputRoot, configNode); }
670 SGExpression<double>*
671 SGReadDoubleExpression(SGPropertyNode *inputRoot,
672 const SGPropertyNode *configNode)
673 { return SGReadFExpression<double>(inputRoot, configNode); }
675 // SGExpression<bool>*
676 // SGReadBoolExpression(SGPropertyNode *inputRoot,
677 // const SGPropertyNode *configNode)
678 // { return SGReadBExpression<bool>(inputRoot, configNode); }
685 bool Parser::readChildren(const SGPropertyNode* exp,
686 vector<Expression*>& result)
688 for (int i = 0; i < exp->nChildren(); ++i)
689 result.push_back(read(exp->getChild(i)));
693 Parser::ParserMap ExpressionParser::_parserTable;
695 void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
697 _parserTable.insert(std::make_pair(token, parsefn));
700 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
702 switch (exp->getType()) {
704 return new SGConstExpression<bool>(getValue<bool>(exp));
706 return new SGConstExpression<int>(getValue<int>(exp));
708 return new SGConstExpression<float>(getValue<float>(exp));
710 return new SGConstExpression<double>(getValue<double>(exp));
716 ExpParserRegistrar valueRegistrar("value", valueParser);
718 template<typename T, typename OpType>
719 inline Expression* makeConvert(Expression* e)
721 return new ConvertExpression<T,
722 OpType>(static_cast<SGExpression<OpType>*>(e));
725 Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
727 vector<Expression*>::iterator maxElem
728 = max_element(exps.begin(), exps.end());
729 Type maxType = (*maxElem)->getType();
730 Type resultType = minType < maxType ? maxType : minType;
731 for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
734 if ((*itr)->getType() != resultType) {
735 switch ((*itr)->getType()) {
737 switch (resultType) {
739 *itr = makeConvert<int, bool>(*itr);
742 *itr = makeConvert<float, bool>(*itr);
745 *itr = makeConvert<double, bool>(*itr);
752 switch (resultType) {
754 *itr = makeConvert<float, int>(*itr);
757 *itr = makeConvert<double, int>(*itr);
764 *itr = makeConvert<double, float>(*itr);
774 template<template<typename OpType> class Expr>
775 Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
777 switch (operandType) {
780 Expr<bool> *expr = new Expr<bool>();
781 expr->addOperands(children.begin(), children.end());
786 Expr<int> *expr = new Expr<int>();
787 expr->addOperands(children.begin(), children.end());
792 Expr<float> *expr = new Expr<float>();
793 expr->addOperands(children.begin(), children.end());
798 Expr<double> *expr = new Expr<double>();
799 expr->addOperands(children.begin(), children.end());
807 template<template<typename OpType> class PredExp>
808 Expression* predParser(const SGPropertyNode* exp, Parser* parser)
810 vector<Expression*> children;
811 parser->readChildren(exp, children);
812 Type operandType = promoteAndConvert(children);
813 return makeTypedOperandExp<PredExp>(operandType, children);
816 ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
817 ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
818 ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
820 template<typename Logicop>
821 Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
823 using namespace boost;
824 vector<Expression*> children;
825 parser->readChildren(exp, children);
826 vector<Expression*>::iterator notBool =
827 find_if(children.begin(), children.end(),
828 bind(&Expression::getType, _1) != BOOL);
829 if (notBool != children.end())
830 throw("non boolean operand to logical expression");
831 Logicop *expr = new Logicop;
832 expr->addOperands(children.begin(), children.end());
836 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
837 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
839 int BindingLayout::addBinding(const string& name, Type type)
842 vector<VariableBinding>::iterator itr
843 = find_if(bindings.begin(), bindings.end(),
844 bind(&VariableBinding::name, _1) == name);
845 if (itr != bindings.end())
846 return itr->location;
847 int result = bindings.size();
848 bindings.push_back(VariableBinding(name, type, bindings.size()));
852 bool BindingLayout::findBinding(const std::string& name,
853 VariableBinding& result) const
856 using namespace boost;
857 vector<VariableBinding>::const_iterator itr
858 = find_if(bindings.begin(), bindings.end(),
859 bind(&VariableBinding::name, _1) == name);
860 if (itr != bindings.end()) {