00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 # include <simgear_config.h>
00024 #endif
00025
00026 #include "SGExpression.hxx"
00027 #include "Singleton.hxx"
00028
00029 #include <algorithm>
00030 #include <functional>
00031 #include <map>
00032 #include <utility>
00033 #include <string>
00034 #include <sstream>
00035 #include <boost/bind.hpp>
00036
00037 #include <simgear/props/props.hxx>
00038
00039 using namespace std;
00040
00041 namespace simgear
00042 {
00043 template<typename T>
00044 const expression::Value evalValue(const Expression* exp,
00045 const expression::Binding* b)
00046 {
00047 T val;
00048 static_cast<const SGExpression<T>*>(exp)->eval(val, b);
00049 return expression::Value(val);
00050 }
00051
00052 const expression::Value eval(const Expression* exp,
00053 const expression::Binding* b)
00054 {
00055 using namespace expression;
00056 switch (exp->getType()) {
00057 case BOOL:
00058 return evalValue<bool>(exp, b);
00059 case INT:
00060 return evalValue<int>(exp, b);
00061 case FLOAT:
00062 return evalValue<float>(exp, b);
00063 case DOUBLE:
00064 return evalValue<double>(exp, b);
00065 default:
00066 throw "invalid type.";
00067 }
00068 }
00069 }
00070
00071 template<typename T>
00072 static bool
00073 SGReadValueFromString(const char* str, T& value)
00074 {
00075 if (!str) {
00076 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
00077 return false;
00078 }
00079 std::stringstream s;
00080 s.str(std::string(str));
00081 s >> value;
00082 if (s.fail()) {
00083 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
00084 return false;
00085 }
00086 return true;
00087 }
00088
00089 template<>
00090 bool
00091 SGReadValueFromString(const char* str, bool& value)
00092 {
00093 if (!str) {
00094 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
00095 return false;
00096 }
00097 std::stringstream s;
00098 s.str(std::string(str));
00099 s >> value;
00100 if (!s.fail())
00101 return true;
00102
00103 std::string stdstr;
00104 if (!SGReadValueFromString(str, stdstr))
00105 return false;
00106
00107 if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
00108 value = true;
00109 return true;
00110 }
00111 if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
00112 value = true;
00113 return true;
00114 }
00115 return false;
00116 }
00117
00118 template<typename T>
00119 static bool
00120 SGReadValueFromContent(const SGPropertyNode *node, T& value)
00121 {
00122 if (!node)
00123 return false;
00124 return SGReadValueFromString(node->getStringValue(), value);
00125 }
00126
00127 template<typename T>
00128 static SGExpression<T>*
00129 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
00130
00131 template<typename T>
00132 static bool
00133 SGReadNaryOperands(SGNaryExpression<T>* nary,
00134 SGPropertyNode *inputRoot, const SGPropertyNode *expression)
00135 {
00136 for (int i = 0; i < expression->nChildren(); ++i) {
00137 SGExpression<T>* inputExpression;
00138 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
00139 if (!inputExpression)
00140 return false;
00141 nary->addOperand(inputExpression);
00142 }
00143 return true;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 template<typename T>
00167 static SGExpression<T>*
00168 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
00169 {
00170 if (!expression)
00171 return 0;
00172
00173 std::string name = expression->getName();
00174 if (name == "value") {
00175 T value;
00176 if (!SGReadValueFromContent(expression, value)) {
00177 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
00178 return 0;
00179 }
00180 return new SGConstExpression<T>(value);
00181 }
00182
00183 if (name == "property") {
00184 if (!inputRoot) {
00185 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
00186 "No inputRoot argument given!");
00187 return 0;
00188 }
00189 if (!expression->getStringValue()) {
00190 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00191 return 0;
00192 }
00193 SGPropertyNode* inputNode;
00194 inputNode = inputRoot->getNode(expression->getStringValue(), true);
00195 return new SGPropertyExpression<T>(inputNode);
00196 }
00197
00198 if (name == "abs" || name == "fabs") {
00199 if (expression->nChildren() != 1) {
00200 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00201 return 0;
00202 }
00203 SGSharedPtr<SGExpression<T> > inputExpression;
00204 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
00205 if (!inputExpression) {
00206 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00207 return 0;
00208 }
00209 return new SGAbsExpression<T>(inputExpression);
00210 }
00211
00212 if (name == "sqr") {
00213 if (expression->nChildren() != 1) {
00214 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00215 return 0;
00216 }
00217 SGSharedPtr<SGExpression<T> > inputExpression;
00218 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
00219 if (!inputExpression) {
00220 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00221 return 0;
00222 }
00223 return new SGSqrExpression<T>(inputExpression);
00224 }
00225
00226 if (name == "clip") {
00227 if (expression->nChildren() != 3) {
00228 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00229 return 0;
00230 }
00231 const SGPropertyNode* minProperty = expression->getChild("clipMin");
00232 T clipMin;
00233 if (!SGReadValueFromContent(minProperty, clipMin))
00234 clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
00235
00236 const SGPropertyNode* maxProperty = expression->getChild("clipMax");
00237 T clipMax;
00238 if (!SGReadValueFromContent(maxProperty, clipMax))
00239 clipMin = SGLimits<T>::max();
00240
00241 SGSharedPtr<SGExpression<T> > inputExpression;
00242 for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
00243 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
00244 if (!inputExpression) {
00245 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00246 return 0;
00247 }
00248 return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
00249 }
00250
00251 if (name == "div") {
00252 if (expression->nChildren() != 2) {
00253 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00254 return 0;
00255 }
00256 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
00257 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
00258 SGReadIExpression<T>(inputRoot, expression->getChild(1))
00259 };
00260 if (!inputExpressions[0] || !inputExpressions[1]) {
00261 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00262 return 0;
00263 }
00264 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
00265 }
00266 if (name == "mod") {
00267 if (expression->nChildren() != 2) {
00268 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00269 return 0;
00270 }
00271 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
00272 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
00273 SGReadIExpression<T>(inputRoot, expression->getChild(1))
00274 };
00275 if (!inputExpressions[0] || !inputExpressions[1]) {
00276 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00277 return 0;
00278 }
00279 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
00280 }
00281
00282 if (name == "sum") {
00283 if (expression->nChildren() < 1) {
00284 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00285 return 0;
00286 }
00287 SGSumExpression<T>* output = new SGSumExpression<T>;
00288 if (!SGReadNaryOperands(output, inputRoot, expression)) {
00289 delete output;
00290 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00291 return 0;
00292 }
00293 return output;
00294 }
00295 if (name == "prod" || name == "product") {
00296 if (expression->nChildren() < 1) {
00297 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00298 return 0;
00299 }
00300 SGProductExpression<T>* output = new SGProductExpression<T>;
00301 if (!SGReadNaryOperands(output, inputRoot, expression)) {
00302 delete output;
00303 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00304 return 0;
00305 }
00306 return output;
00307 }
00308 if (name == "min") {
00309 if (expression->nChildren() < 1) {
00310 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00311 return 0;
00312 }
00313 SGMinExpression<T>* output = new SGMinExpression<T>;
00314 if (!SGReadNaryOperands(output, inputRoot, expression)) {
00315 delete output;
00316 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00317 return 0;
00318 }
00319 return output;
00320 }
00321 if (name == "max") {
00322 if (expression->nChildren() < 1) {
00323 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00324 return 0;
00325 }
00326 SGMaxExpression<T>* output = new SGMaxExpression<T>;
00327 if (!SGReadNaryOperands(output, inputRoot, expression)) {
00328 delete output;
00329 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00330 return 0;
00331 }
00332 return output;
00333 }
00334
00335 return 0;
00336 }
00337
00338
00339 template<typename T>
00340 static SGExpression<T>*
00341 SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
00342 {
00343 SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
00344 if (r)
00345 return r;
00346
00347 if (!expression)
00348 return 0;
00349
00350 std::string name = expression->getName();
00351 if (name == "acos") {
00352 if (expression->nChildren() != 1) {
00353 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00354 return 0;
00355 }
00356 SGSharedPtr<SGExpression<T> > inputExpression;
00357 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00358 if (!inputExpression) {
00359 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00360 return 0;
00361 }
00362 return new SGACosExpression<T>(inputExpression);
00363 }
00364
00365 if (name == "asin") {
00366 if (expression->nChildren() != 1) {
00367 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00368 return 0;
00369 }
00370 SGSharedPtr<SGExpression<T> > inputExpression;
00371 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00372 if (!inputExpression) {
00373 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00374 return 0;
00375 }
00376 return new SGASinExpression<T>(inputExpression);
00377 }
00378
00379 if (name == "atan") {
00380 if (expression->nChildren() != 1) {
00381 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00382 return 0;
00383 }
00384 SGSharedPtr<SGExpression<T> > inputExpression;
00385 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00386 if (!inputExpression) {
00387 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00388 return 0;
00389 }
00390 return new SGATanExpression<T>(inputExpression);
00391 }
00392
00393 if (name == "ceil") {
00394 if (expression->nChildren() != 1) {
00395 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00396 return 0;
00397 }
00398 SGSharedPtr<SGExpression<T> > inputExpression;
00399 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00400 if (!inputExpression) {
00401 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00402 return 0;
00403 }
00404 return new SGCeilExpression<T>(inputExpression);
00405 }
00406
00407 if (name == "cos") {
00408 if (expression->nChildren() != 1) {
00409 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00410 return 0;
00411 }
00412 SGSharedPtr<SGExpression<T> > inputExpression;
00413 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00414 if (!inputExpression) {
00415 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00416 return 0;
00417 }
00418 return new SGCosExpression<T>(inputExpression);
00419 }
00420
00421 if (name == "cosh") {
00422 if (expression->nChildren() != 1) {
00423 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00424 return 0;
00425 }
00426 SGSharedPtr<SGExpression<T> > inputExpression;
00427 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00428 if (!inputExpression) {
00429 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00430 return 0;
00431 }
00432 return new SGCoshExpression<T>(inputExpression);
00433 }
00434
00435 if (name == "deg2rad") {
00436 if (expression->nChildren() != 1) {
00437 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00438 return 0;
00439 }
00440 SGSharedPtr<SGExpression<T> > inputExpression;
00441 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00442 if (!inputExpression) {
00443 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00444 return 0;
00445 }
00446 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
00447 }
00448
00449 if (name == "exp") {
00450 if (expression->nChildren() != 1) {
00451 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00452 return 0;
00453 }
00454 SGSharedPtr<SGExpression<T> > inputExpression;
00455 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00456 if (!inputExpression) {
00457 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00458 return 0;
00459 }
00460 return new SGExpExpression<T>(inputExpression);
00461 }
00462
00463 if (name == "floor") {
00464 if (expression->nChildren() != 1) {
00465 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00466 return 0;
00467 }
00468 SGSharedPtr<SGExpression<T> > inputExpression;
00469 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00470 if (!inputExpression) {
00471 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00472 return 0;
00473 }
00474 return new SGFloorExpression<T>(inputExpression);
00475 }
00476
00477 if (name == "log") {
00478 if (expression->nChildren() != 1) {
00479 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00480 return 0;
00481 }
00482 SGSharedPtr<SGExpression<T> > inputExpression;
00483 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00484 if (!inputExpression) {
00485 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00486 return 0;
00487 }
00488 return new SGLogExpression<T>(inputExpression);
00489 }
00490
00491 if (name == "log10") {
00492 if (expression->nChildren() != 1) {
00493 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00494 return 0;
00495 }
00496 SGSharedPtr<SGExpression<T> > inputExpression;
00497 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00498 if (!inputExpression) {
00499 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00500 return 0;
00501 }
00502 return new SGLog10Expression<T>(inputExpression);
00503 }
00504
00505 if (name == "rad2deg") {
00506 if (expression->nChildren() != 1) {
00507 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00508 return 0;
00509 }
00510 SGSharedPtr<SGExpression<T> > inputExpression;
00511 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00512 if (!inputExpression) {
00513 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00514 return 0;
00515 }
00516 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
00517 }
00518
00519 if (name == "sin") {
00520 if (expression->nChildren() != 1) {
00521 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00522 return 0;
00523 }
00524 SGSharedPtr<SGExpression<T> > inputExpression;
00525 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00526 if (!inputExpression) {
00527 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00528 return 0;
00529 }
00530 return new SGSinExpression<T>(inputExpression);
00531 }
00532
00533 if (name == "sinh") {
00534 if (expression->nChildren() != 1) {
00535 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00536 return 0;
00537 }
00538 SGSharedPtr<SGExpression<T> > inputExpression;
00539 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00540 if (!inputExpression) {
00541 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00542 return 0;
00543 }
00544 return new SGSinhExpression<T>(inputExpression);
00545 }
00546
00547 if (name == "sqrt") {
00548 if (expression->nChildren() != 1) {
00549 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00550 return 0;
00551 }
00552 SGSharedPtr<SGExpression<T> > inputExpression;
00553 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00554 if (!inputExpression) {
00555 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00556 return 0;
00557 }
00558 return new SGSqrtExpression<T>(inputExpression);
00559 }
00560
00561 if (name == "tan") {
00562 if (expression->nChildren() != 1) {
00563 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00564 return 0;
00565 }
00566 SGSharedPtr<SGExpression<T> > inputExpression;
00567 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00568 if (!inputExpression) {
00569 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00570 return 0;
00571 }
00572 return new SGTanExpression<T>(inputExpression);
00573 }
00574
00575 if (name == "tanh") {
00576 if (expression->nChildren() != 1) {
00577 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00578 return 0;
00579 }
00580 SGSharedPtr<SGExpression<T> > inputExpression;
00581 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
00582 if (!inputExpression) {
00583 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00584 return 0;
00585 }
00586 return new SGTanhExpression<T>(inputExpression);
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596 if (name == "atan2") {
00597 if (expression->nChildren() != 2) {
00598 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00599 return 0;
00600 }
00601 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
00602 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
00603 SGReadFExpression<T>(inputRoot, expression->getChild(1))
00604 };
00605 if (!inputExpressions[0] || !inputExpressions[1]) {
00606 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00607 return 0;
00608 }
00609 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
00610 }
00611 if (name == "div") {
00612 if (expression->nChildren() != 2) {
00613 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00614 return 0;
00615 }
00616 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
00617 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
00618 SGReadFExpression<T>(inputRoot, expression->getChild(1))
00619 };
00620 if (!inputExpressions[0] || !inputExpressions[1]) {
00621 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00622 return 0;
00623 }
00624 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
00625 }
00626 if (name == "mod") {
00627 if (expression->nChildren() != 2) {
00628 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00629 return 0;
00630 }
00631 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
00632 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
00633 SGReadFExpression<T>(inputRoot, expression->getChild(1))
00634 };
00635 if (!inputExpressions[0] || !inputExpressions[1]) {
00636 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00637 return 0;
00638 }
00639 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
00640 }
00641 if (name == "pow") {
00642 if (expression->nChildren() != 2) {
00643 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00644 return 0;
00645 }
00646 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
00647 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
00648 SGReadIExpression<T>(inputRoot, expression->getChild(1))
00649 };
00650 if (!inputExpressions[0] || !inputExpressions[1]) {
00651 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
00652 return 0;
00653 }
00654 return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
00655 }
00656
00657 return 0;
00658 }
00659
00660 SGExpression<int>*
00661 SGReadIntExpression(SGPropertyNode *inputRoot,
00662 const SGPropertyNode *configNode)
00663 { return SGReadIExpression<int>(inputRoot, configNode); }
00664
00665 SGExpression<float>*
00666 SGReadFloatExpression(SGPropertyNode *inputRoot,
00667 const SGPropertyNode *configNode)
00668 { return SGReadFExpression<float>(inputRoot, configNode); }
00669
00670 SGExpression<double>*
00671 SGReadDoubleExpression(SGPropertyNode *inputRoot,
00672 const SGPropertyNode *configNode)
00673 { return SGReadFExpression<double>(inputRoot, configNode); }
00674
00675
00676
00677
00678
00679
00680 namespace simgear
00681 {
00682 namespace expression
00683 {
00684
00685 bool Parser::readChildren(const SGPropertyNode* exp,
00686 vector<Expression*>& result)
00687 {
00688 for (int i = 0; i < exp->nChildren(); ++i)
00689 result.push_back(read(exp->getChild(i)));
00690 return true;
00691 }
00692
00693 void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
00694 {
00695 ParserMapSingleton::instance()
00696 ->_parserTable.insert(std::make_pair(token, parsefn));
00697 }
00698
00699 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
00700 {
00701 switch (exp->getType()) {
00702 case props::BOOL:
00703 return new SGConstExpression<bool>(getValue<bool>(exp));
00704 case props::INT:
00705 return new SGConstExpression<int>(getValue<int>(exp));
00706 case props::FLOAT:
00707 return new SGConstExpression<float>(getValue<float>(exp));
00708 case props::DOUBLE:
00709 return new SGConstExpression<double>(getValue<double>(exp));
00710 default:
00711 return 0;
00712 }
00713 }
00714
00715 ExpParserRegistrar valueRegistrar("value", valueParser);
00716
00717 template<typename T, typename OpType>
00718 inline Expression* makeConvert(Expression* e)
00719 {
00720 return new ConvertExpression<T,
00721 OpType>(static_cast<SGExpression<OpType>*>(e));
00722 }
00723
00724 Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
00725 {
00726 vector<Expression*>::iterator maxElem
00727 = max_element(exps.begin(), exps.end());
00728 Type maxType = (*maxElem)->getType();
00729 Type resultType = minType < maxType ? maxType : minType;
00730 for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
00731 itr != end;
00732 ++itr) {
00733 if ((*itr)->getType() != resultType) {
00734 switch ((*itr)->getType()) {
00735 case BOOL:
00736 switch (resultType) {
00737 case INT:
00738 *itr = makeConvert<int, bool>(*itr);
00739 break;
00740 case FLOAT:
00741 *itr = makeConvert<float, bool>(*itr);
00742 break;
00743 case DOUBLE:
00744 *itr = makeConvert<double, bool>(*itr);
00745 break;
00746 default:
00747 break;
00748 }
00749 break;
00750 case INT:
00751 switch (resultType) {
00752 case FLOAT:
00753 *itr = makeConvert<float, int>(*itr);
00754 break;
00755 case DOUBLE:
00756 *itr = makeConvert<double, int>(*itr);
00757 break;
00758 default:
00759 break;
00760 }
00761 break;
00762 case FLOAT:
00763 *itr = makeConvert<double, float>(*itr);
00764 break;
00765 default:
00766 break;
00767 }
00768 }
00769 }
00770 return resultType;
00771 }
00772
00773 template<template<typename OpType> class Expr>
00774 Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
00775 {
00776 switch (operandType) {
00777 case BOOL:
00778 {
00779 Expr<bool> *expr = new Expr<bool>();
00780 expr->addOperands(children.begin(), children.end());
00781 return expr;
00782 }
00783 case INT:
00784 {
00785 Expr<int> *expr = new Expr<int>();
00786 expr->addOperands(children.begin(), children.end());
00787 return expr;
00788 }
00789 case FLOAT:
00790 {
00791 Expr<float> *expr = new Expr<float>();
00792 expr->addOperands(children.begin(), children.end());
00793 return expr;
00794 }
00795 case DOUBLE:
00796 {
00797 Expr<double> *expr = new Expr<double>();
00798 expr->addOperands(children.begin(), children.end());
00799 return expr;
00800 }
00801 default:
00802 return 0;
00803 }
00804 }
00805
00806 template<template<typename OpType> class PredExp>
00807 Expression* predParser(const SGPropertyNode* exp, Parser* parser)
00808 {
00809 vector<Expression*> children;
00810 parser->readChildren(exp, children);
00811 Type operandType = promoteAndConvert(children);
00812 return makeTypedOperandExp<PredExp>(operandType, children);
00813 }
00814
00815 ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
00816 ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
00817 ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
00818
00819 template<typename Logicop>
00820 Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
00821 {
00822 using namespace boost;
00823 vector<Expression*> children;
00824 parser->readChildren(exp, children);
00825 vector<Expression*>::iterator notBool =
00826 find_if(children.begin(), children.end(),
00827 bind(&Expression::getType, _1) != BOOL);
00828 if (notBool != children.end())
00829 throw("non boolean operand to logical expression");
00830 Logicop *expr = new Logicop;
00831 expr->addOperands(children.begin(), children.end());
00832 return expr;
00833 }
00834
00835 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
00836 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
00837
00838 int BindingLayout::addBinding(const string& name, Type type)
00839 {
00840
00841 vector<VariableBinding>::iterator itr
00842 = find_if(bindings.begin(), bindings.end(),
00843 bind(&VariableBinding::name, _1) == name);
00844 if (itr != bindings.end())
00845 return itr->location;
00846 int result = bindings.size();
00847 bindings.push_back(VariableBinding(name, type, bindings.size()));
00848 return result;
00849 }
00850
00851 bool BindingLayout::findBinding(const std::string& name,
00852 VariableBinding& result) const
00853 {
00854 using namespace std;
00855 using namespace boost;
00856 vector<VariableBinding>::const_iterator itr
00857 = find_if(bindings.begin(), bindings.end(),
00858 bind(&VariableBinding::name, _1) == name);
00859 if (itr != bindings.end()) {
00860 result = *itr;
00861 return true;
00862 } else {
00863 return false;
00864 }
00865 }
00866 }
00867 }