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"
30 #include <simgear/props/props.hxx>
34 SGReadValueFromString(const char* str, T& value)
37 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
41 s.str(std::string(str));
44 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
52 SGReadValueFromString(const char* str, bool& value)
55 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
59 s.str(std::string(str));
65 if (!SGReadValueFromString(str, stdstr))
68 if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
72 if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
81 SGReadValueFromContent(const SGPropertyNode *node, T& value)
85 return SGReadValueFromString(node->getStringValue(), value);
89 static SGExpression<T>*
90 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
94 SGReadNaryOperands(SGNaryExpression<T>* nary,
95 SGPropertyNode *inputRoot, const SGPropertyNode *expression)
97 for (unsigned i = 0; i < expression->nChildren(); ++i) {
98 SGExpression<T>* inputExpression;
99 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
100 if (!inputExpression)
102 nary->addOperand(inputExpression);
106 // template<typename T>
107 // static SGExpression<T>*
108 // SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
113 // std::string name = expression->getName();
114 // if (name == "value") {
116 // if (!SGReadValueFromContent(expression, value)) {
117 // SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
120 // return new SGConstExpression<T>(value);
127 static SGExpression<T>*
128 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
133 std::string name = expression->getName();
134 if (name == "value") {
136 if (!SGReadValueFromContent(expression, value)) {
137 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
140 return new SGConstExpression<T>(value);
143 if (name == "property") {
145 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
146 "No inputRoot argument given!");
149 if (!expression->getStringValue()) {
150 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
153 SGPropertyNode* inputNode;
154 inputNode = inputRoot->getNode(expression->getStringValue(), true);
155 return new SGPropertyExpression<T>(inputNode);
158 if (name == "abs" || name == "fabs") {
159 if (expression->nChildren() != 1) {
160 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
163 SGSharedPtr<SGExpression<T> > inputExpression;
164 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
165 if (!inputExpression) {
166 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
169 return new SGAbsExpression<T>(inputExpression);
173 if (expression->nChildren() != 1) {
174 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
177 SGSharedPtr<SGExpression<T> > inputExpression;
178 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
179 if (!inputExpression) {
180 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
183 return new SGSqrExpression<T>(inputExpression);
186 if (name == "clip") {
187 if (expression->nChildren() != 3) {
188 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
191 const SGPropertyNode* minProperty = expression->getChild("clipMin");
193 if (!SGReadValueFromContent(minProperty, clipMin))
194 clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
196 const SGPropertyNode* maxProperty = expression->getChild("clipMax");
198 if (!SGReadValueFromContent(maxProperty, clipMax))
199 clipMin = SGLimits<T>::max();
201 SGSharedPtr<SGExpression<T> > inputExpression;
202 for (unsigned i = 0; !inputExpression && i < expression->nChildren(); ++i)
203 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
204 if (!inputExpression) {
205 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
208 return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
212 if (expression->nChildren() != 2) {
213 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
216 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
217 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
218 SGReadIExpression<T>(inputRoot, expression->getChild(1))
220 if (!inputExpressions[0] || !inputExpressions[1]) {
221 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
224 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
227 if (expression->nChildren() != 2) {
228 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
231 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
232 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
233 SGReadIExpression<T>(inputRoot, expression->getChild(1))
235 if (!inputExpressions[0] || !inputExpressions[1]) {
236 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
239 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
243 if (expression->nChildren() < 1) {
244 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
247 SGSumExpression<T>* output = new SGSumExpression<T>;
248 if (!SGReadNaryOperands(output, inputRoot, expression)) {
250 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
255 if (name == "prod" || name == "product") {
256 if (expression->nChildren() < 1) {
257 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
260 SGProductExpression<T>* output = new SGProductExpression<T>;
261 if (!SGReadNaryOperands(output, inputRoot, expression)) {
263 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
269 if (expression->nChildren() < 1) {
270 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
273 SGMinExpression<T>* output = new SGMinExpression<T>;
274 if (!SGReadNaryOperands(output, inputRoot, expression)) {
276 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
282 if (expression->nChildren() < 1) {
283 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
286 SGMaxExpression<T>* output = new SGMaxExpression<T>;
287 if (!SGReadNaryOperands(output, inputRoot, expression)) {
289 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
300 static SGExpression<T>*
301 SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
303 SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
310 std::string name = expression->getName();
311 if (name == "acos") {
312 if (expression->nChildren() != 1) {
313 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
316 SGSharedPtr<SGExpression<T> > inputExpression;
317 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
318 if (!inputExpression) {
319 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
322 return new SGACosExpression<T>(inputExpression);
325 if (name == "asin") {
326 if (expression->nChildren() != 1) {
327 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
330 SGSharedPtr<SGExpression<T> > inputExpression;
331 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
332 if (!inputExpression) {
333 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
336 return new SGASinExpression<T>(inputExpression);
339 if (name == "atan") {
340 if (expression->nChildren() != 1) {
341 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
344 SGSharedPtr<SGExpression<T> > inputExpression;
345 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
346 if (!inputExpression) {
347 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
350 return new SGATanExpression<T>(inputExpression);
353 if (name == "ceil") {
354 if (expression->nChildren() != 1) {
355 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
358 SGSharedPtr<SGExpression<T> > inputExpression;
359 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
360 if (!inputExpression) {
361 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
364 return new SGCeilExpression<T>(inputExpression);
368 if (expression->nChildren() != 1) {
369 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
372 SGSharedPtr<SGExpression<T> > inputExpression;
373 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
374 if (!inputExpression) {
375 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
378 return new SGCosExpression<T>(inputExpression);
381 if (name == "cosh") {
382 if (expression->nChildren() != 1) {
383 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
386 SGSharedPtr<SGExpression<T> > inputExpression;
387 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
388 if (!inputExpression) {
389 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
392 return new SGCoshExpression<T>(inputExpression);
395 if (name == "deg2rad") {
396 if (expression->nChildren() != 1) {
397 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
400 SGSharedPtr<SGExpression<T> > inputExpression;
401 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
402 if (!inputExpression) {
403 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
406 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
410 if (expression->nChildren() != 1) {
411 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
414 SGSharedPtr<SGExpression<T> > inputExpression;
415 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
416 if (!inputExpression) {
417 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
420 return new SGExpExpression<T>(inputExpression);
423 if (name == "floor") {
424 if (expression->nChildren() != 1) {
425 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
428 SGSharedPtr<SGExpression<T> > inputExpression;
429 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
430 if (!inputExpression) {
431 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
434 return new SGFloorExpression<T>(inputExpression);
438 if (expression->nChildren() != 1) {
439 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
442 SGSharedPtr<SGExpression<T> > inputExpression;
443 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
444 if (!inputExpression) {
445 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
448 return new SGLogExpression<T>(inputExpression);
451 if (name == "log10") {
452 if (expression->nChildren() != 1) {
453 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
456 SGSharedPtr<SGExpression<T> > inputExpression;
457 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
458 if (!inputExpression) {
459 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
462 return new SGLog10Expression<T>(inputExpression);
465 if (name == "rad2deg") {
466 if (expression->nChildren() != 1) {
467 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
470 SGSharedPtr<SGExpression<T> > inputExpression;
471 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
472 if (!inputExpression) {
473 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
476 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
480 if (expression->nChildren() != 1) {
481 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
484 SGSharedPtr<SGExpression<T> > inputExpression;
485 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
486 if (!inputExpression) {
487 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
490 return new SGSinExpression<T>(inputExpression);
493 if (name == "sinh") {
494 if (expression->nChildren() != 1) {
495 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
498 SGSharedPtr<SGExpression<T> > inputExpression;
499 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
500 if (!inputExpression) {
501 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
504 return new SGSinhExpression<T>(inputExpression);
507 if (name == "sqrt") {
508 if (expression->nChildren() != 1) {
509 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
512 SGSharedPtr<SGExpression<T> > inputExpression;
513 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
514 if (!inputExpression) {
515 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
518 return new SGSqrtExpression<T>(inputExpression);
522 if (expression->nChildren() != 1) {
523 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
526 SGSharedPtr<SGExpression<T> > inputExpression;
527 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
528 if (!inputExpression) {
529 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
532 return new SGTanExpression<T>(inputExpression);
535 if (name == "tanh") {
536 if (expression->nChildren() != 1) {
537 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
540 SGSharedPtr<SGExpression<T> > inputExpression;
541 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
542 if (!inputExpression) {
543 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
546 return new SGTanhExpression<T>(inputExpression);
549 // if (name == "table") {
551 // if (name == "step") {
553 // if (name == "condition") {
556 if (name == "atan2") {
557 if (expression->nChildren() != 2) {
558 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
561 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
562 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
563 SGReadFExpression<T>(inputRoot, expression->getChild(1))
565 if (!inputExpressions[0] || !inputExpressions[1]) {
566 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
569 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
572 if (expression->nChildren() != 2) {
573 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
576 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
577 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
578 SGReadFExpression<T>(inputRoot, expression->getChild(1))
580 if (!inputExpressions[0] || !inputExpressions[1]) {
581 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
584 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
587 if (expression->nChildren() != 2) {
588 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
591 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
592 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
593 SGReadFExpression<T>(inputRoot, expression->getChild(1))
595 if (!inputExpressions[0] || !inputExpressions[1]) {
596 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
599 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
602 if (expression->nChildren() != 2) {
603 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
606 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
607 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
608 SGReadIExpression<T>(inputRoot, expression->getChild(1))
610 if (!inputExpressions[0] || !inputExpressions[1]) {
611 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
614 return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
621 SGReadIntExpression(SGPropertyNode *inputRoot,
622 const SGPropertyNode *configNode)
623 { return SGReadIExpression<int>(inputRoot, configNode); }
626 SGReadFloatExpression(SGPropertyNode *inputRoot,
627 const SGPropertyNode *configNode)
628 { return SGReadFExpression<float>(inputRoot, configNode); }
630 SGExpression<double>*
631 SGReadDoubleExpression(SGPropertyNode *inputRoot,
632 const SGPropertyNode *configNode)
633 { return SGReadFExpression<double>(inputRoot, configNode); }
635 // SGExpression<bool>*
636 // SGReadBoolExpression(SGPropertyNode *inputRoot,
637 // const SGPropertyNode *configNode)
638 // { return SGReadBExpression<bool>(inputRoot, configNode); }