OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
Expressions.cpp
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2// $RCSfile: Expressions.cpp,v $
3// ------------------------------------------------------------------------
4// $Revision: 1.2.4.1 $
5// ------------------------------------------------------------------------
6// Copyright: see Copyright.readme
7// ------------------------------------------------------------------------
8//
9// Namespace Expressions:
10// This namespace contains the attribute parsers for OPAL:
11// a collection of functions.
12//
13// ------------------------------------------------------------------------
14//
15// $Date: 2002/12/09 15:06:08 $
16// $Author: jsberg $
17//
18// ------------------------------------------------------------------------
19
21#include <algorithm>
22#include <cerrno>
23#include <cmath>
24#include <list>
25#include <sstream>
26#include <vector>
34#include "Expressions/ABinary.h"
35#include "Expressions/AColumn.h"
36#include "Expressions/AList.h"
38#include "Expressions/ARow.h"
39#include "Expressions/ASUnary.h"
40#include "Expressions/ATable.h"
41#include "Expressions/AUnary.h"
42#include "Expressions/Indexer.h"
43#include "Expressions/SBinary.h"
44#include "Expressions/SCell.h"
47#include "Expressions/SHash.h"
48#include "Expressions/SNull.h"
51#include "Expressions/SUnary.h"
52#include "Expressions/TFind.h"
57#include "PartBunch/PartBunch.h"
59#include "Utilities/Options.h"
63
64// Namespace Expressions
65// ------------------------------------------------------------------------
66
67namespace Expressions {
68
69 // Boolean operators.
70 // ----------------------------------------------------------------------
71
72 bool Or(bool a, bool b) { return a || b; }
73 static const TFunction2<bool, bool> logOr = {"||", 1, Or};
74
75 bool And(bool a, bool b) { return a && b; }
76 static const TFunction2<bool, bool> logAnd = {"&&", 2, And};
77
78 bool Le(double a, double b) { return a <= b; }
79 static const TFunction2<bool, double> lessEqual = {"<=", 3, Le};
80
81 bool Lt(double a, double b) { return a < b; }
82 static const TFunction2<bool, double> less = {"<", 3, Lt};
83
84 bool Ge(double a, double b) { return a >= b; }
85 static const TFunction2<bool, double> greaterEqual = {">=", 3, Ge};
86
87 bool Gt(double a, double b) { return a > b; }
88 static const TFunction2<bool, double> greater = {">", 3, Gt};
89
90 bool Eq(double a, double b) { return a == b; }
91 static const TFunction2<bool, double> equal = {"==", 3, Eq};
92
93 bool Ne(double a, double b) { return a != b; }
94 static const TFunction2<bool, double> notEqual = {"!=", 3, Ne};
95
96 // Real operators with one or two operands.
97 // ----------------------------------------------------------------------
98
99 double Neg(double a) { return -a; }
100
101 static const TFunction1<double, double> negate = {"-", 5, Neg};
102
103 double Sign(double a) { return (a > 0.) ? 1. : (a < 0.) ? -1. : 0.; }
104
105 double Tgauss(double a) {
106 double x, y;
107 do {
109 } while (std::abs(x) > a);
110 return x;
111 }
112
113 double Add(double a, double b) { return a + b; }
114
115 static const TFunction2<double, double> plus = {"+", 4, Add};
116
117 double Sub(double a, double b) { return a - b; }
118
119 static const TFunction2<double, double> minus = {"-", 4, Sub};
120
121 double Mpy(double a, double b) { return a * b; }
122
123 static TFunction2<double, double> times = {"*", 5, Mpy};
124
125 double Div(double a, double b) {
126 if (b == 0.0) {
127 errno = EDOM;
128 return 1.0;
129 } else {
130 return a / b;
131 }
132 }
133
134 static TFunction2<double, double> divide = {"/", 5, Div};
135
136 // Real functions without arguments.
137 // ----------------------------------------------------------------------
138
139 double getEkin() {
141
142 if (p)
143 std::cout << "PartBuch valid" << std::endl;
144 else
145 std::cout << "PartBuch not valid" << std::endl;
146
147 if (p) return 0.0;
148 // return p->get_meanKineticEnergy();
149 else
150 return -1.0;
151 }
152
153 double ranf() { return Options::rangen.uniform(); }
154
155 double gauss() {
156 double x, y;
158 return x;
159 }
160
161 static TFunction0<double> table0[] = {
162 {"GETEKIN", -2, getEkin},
163 {"RANF", -2, ranf},
164 {"GAUSS", -2, gauss},
165 {"SI", -2, SFunction::arcIn},
166 {"SC", -2, SFunction::arcCtr},
167 {"SO", -2, SFunction::arcOut},
168 {0, -1, 0}};
169
170 // Real functions with two arguments.
171 // ----------------------------------------------------------------------
172
173 static const TFunction1<double, double> table1[] = {
174 {"TRUNC", -1, std::trunc}, {"ROUND", -1, std::round}, {"FLOOR", -1, std::floor},
175 {"CEIL", -1, std::ceil}, {"SIGN", -1, Sign}, {"SQRT", -1, std::sqrt},
176 {"LOG", -1, std::log}, {"EXP", -1, std::exp}, {"SIN", -1, std::sin},
177 {"COS", -1, std::cos}, {"ABS", -1, std::abs}, {"TAN", -1, std::tan},
178 {"ASIN", -1, std::asin}, {"ACOS", -1, std::acos}, {"ATAN", -1, std::atan},
179 {"TGAUSS", -2, Tgauss}, {"ERF", -1, std::erf}, {0, -1, 0}};
180
181 // Real functions with two arguments.
182 // ----------------------------------------------------------------------
183
184 double Max(double a, double b) { return std::max(a, b); }
185
186 double Min(double a, double b) { return std::min(a, b); }
187
188 double Mod(double a, double b) {
189 if (b <= 0.0) errno = EDOM;
190 return fmod(a, b);
191 }
192
193 static TFunction2<double, double> power = {"^", 6, pow};
194
195 static const TFunction2<double, double> table2[] = {{"ATAN2", -1, atan2}, {"MAX", -1, Max},
196 {"MIN", -1, Min}, {"MOD", -1, Mod},
197 {"POW", -2, pow}, {0, -1, 0}};
198
199 // Function of arrays giving a real result.
200 // ----------------------------------------------------------------------
201
202 double Mina(const std::vector<double>& array) {
203 if (array.size()) {
204 double result = array[0];
205 for (std::vector<double>::size_type i = 1; i < array.size(); ++i) {
206 result = Min(array[i], result);
207 }
208 return result;
209 } else if (Options::warn) {
210 std::cerr << "\n### Warning ### \"VMIN\" function of empty array.\n" << std::endl;
211 }
212 return 0.0;
213 }
214
215 double Maxa(const std::vector<double>& array) {
216 if (array.size()) {
217 double result = array[0];
218 for (std::vector<double>::size_type i = 1; i < array.size(); ++i) {
219 result = std::max(array[i], result);
220 }
221 return result;
222 } else if (Options::warn) {
223 std::cerr << "\n### Warning ### \"VMAX\" function of empty array.\n" << std::endl;
224 }
225 return 0.0;
226 }
227
228 double Rmsa(const std::vector<double>& array) {
229 if (array.size()) {
230 double result = 0.0;
231 for (std::vector<double>::size_type i = 0; i < array.size(); ++i) {
232 result += array[i] * array[i];
233 }
234 return sqrt(result / double(array.size()));
235 } else if (Options::warn) {
236 std::cerr << "\n### Warning ### \"VRMS\" function of empty array.\n" << std::endl;
237 }
238 return 0.0;
239 }
240
241 double AbsMax(const std::vector<double>& array) {
242 if (array.size()) {
243 double result = std::abs(array[0]);
244 for (std::vector<double>::size_type i = 1; i < array.size(); ++i) {
245 result = std::max(std::abs(array[i]), result);
246 }
247 return result;
248 } else if (Options::warn) {
249 std::cerr << "\n### Warning ### \"VABSMAX\" function of empty array.\n" << std::endl;
250 }
251 return 0.0;
252 }
253
255 static const ArrayFun tablea[] = {
256 {"VMIN", -1, Mina},
257 {"VMAX", -1, Maxa},
258 {"VRMS", -1, Rmsa},
259 {"VABSMAX", -1, AbsMax},
260 {0, -1, 0}};
261
262 // Internal variables.
263 const Table* currentTable = 0;
264 std::unique_ptr<ATable> currentArray;
265
266 // FORWARD DECLARATIONS FOR LOCAL FUNCTIONS.
267 // ------------------------------------------------------------------------
268
269 // Parse an "&&" expression.
271
272 // Parse an array factor.
274
275 // Parse an array primary.
277
278 // Parse an array term.
280
281 // Parse a token list in brackets (for macro argument and the like).
282 // This method also checks the nesting of parentheses.
283 void parseBracketList(Statement& stat, char close, std::list<Token>& result);
284
285 // Parse a real factor.
287
288 // Parse a real primary expression.
290
291 // Parse a relational expression.
293
294 // Parse a real term.
296
297 // Parse a column generator "COLUMN(table,column,range)".
299
300 // Parse a row generator "ROW(table,place,...)".
302
303 // Parse a table generator "TABLE(n1:n2:n3,expr)".
305
306 // PARSE SCALAR EXPRESSIONS.
307 // ------------------------------------------------------------------------
308
310 PtrToScalar<bool> second;
311 PtrToScalar<bool> result = parseAnd(stat);
312
313 while (stat.delimiter("||")) {
314 second = parseAnd(stat);
315 result = SBinary<bool, bool>::make(logOr, result, second);
316 }
317
318 return result;
319 }
320
322 PtrToScalar<double> result;
323 PtrToScalar<double> second;
324
325 if (stat.delimiter('+')) {
326 // Unary plus.
327 result = parseTerm(stat);
328 } else if (stat.delimiter('-')) {
329 // Unary minus.
330 result = parseTerm(stat);
331 result = SUnary<double, double>::make(negate, result);
332 } else {
333 result = parseTerm(stat);
334 }
335
336 while (true) {
337 if (stat.delimiter('+')) {
338 second = parseTerm(stat);
339 result = SBinary<double, double>::make(plus, result, second);
340 } else if (stat.delimiter('-')) {
341 second = parseTerm(stat);
342 result = SBinary<double, double>::make(minus, result, second);
343 } else {
344 break;
345 }
346 }
347
348 return result;
349 }
350
351 double parseRealConst(Statement& stat) {
352 PtrToScalar<double> expr = parseReal(stat);
353 return expr->evaluate();
354 }
355
356 std::string parseString(Statement& stat, const char msg[]) {
357 std::string result = std::string("");
358 std::string temp;
359 bool isWord = stat.word(temp);
360
361 while (isWord || stat.str(temp)) {
362 if (isWord && temp == "TO_STRING") {
363 parseDelimiter(stat, '(');
364 double value = parseRealConst(stat);
365 parseDelimiter(stat, ')');
366 std::ostringstream os;
367 os << value;
368 result += os.str();
369 } else {
370 result += temp;
371 }
372
373 if (!stat.delimiter('&')) break;
374 isWord = stat.word(temp);
375 }
376
377 if (result.empty()) {
378 std::string errorMsg(msg);
379 errorMsg = stat.str() + "\n" + errorMsg;
380 throw ParseError("Expressions::parseString()", errorMsg);
381 } else {
382 return result;
383 }
384 }
385
386 std::string parseStringValue(Statement& stat, const char msg[]) {
387 std::string result;
388 std::string temp;
389 Object* object = nullptr;
390 bool isWord = stat.word(temp);
391 bool isValidObject = isWord && (object = OpalData::getInstance()->find(temp), object);
392 bool isConversion = isWord && temp == "TO_STRING";
393
394 while (stat.str(temp) || isValidObject || isConversion) {
395 if (isValidObject) {
396 StringConstant* stringConst = dynamic_cast<StringConstant*>(object);
397 if (stringConst) {
398 result += stringConst->getString();
399 } else {
400 result += temp;
401 break;
402 }
403 } else if (isConversion) {
404 parseDelimiter(stat, '(');
405 double value = parseRealConst(stat);
406 parseDelimiter(stat, ')');
407 std::ostringstream os;
408 os << value;
409 result += os.str();
410 } else {
411 result += temp;
412 }
413
414 if (!stat.delimiter('&')) {
415 break;
416 }
417
418 object = nullptr;
419 isWord = stat.word(temp);
420 isValidObject = isWord && (object = OpalData::getInstance()->find(temp), object);
421 isConversion = isWord && temp == "TO_STRING";
422 }
423
424 if (result.empty()) {
425 std::string errorMsg(msg);
426 errorMsg = stat.str() + "\n" + errorMsg;
427 throw ParseError("Expressions::parseStringValue()", errorMsg);
428 } else {
429 return result;
430 }
431 }
432
433 // PARSE ARRAY EXPRESSIONS
434 // ------------------------------------------------------------------------
435
437 ArrayOfPtrs<bool> array;
438
439 if (stat.delimiter('{')) {
440 // List of boolean expressions within braces.
441 do {
442 array.push_back(parseBool(stat));
443 } while (stat.delimiter(','));
444
445 parseDelimiter(stat, '}');
446 } else {
447 // A single boolean expression.
448 array.push_back(parseBool(stat));
449 }
450
451 return new AList<bool>(array);
452 }
453
455 PtrToArray<double> result;
456 PtrToArray<double> second;
457
458 if (stat.delimiter('+')) {
459 // Unary plus.
460 result = parseArrayTerm(stat);
461 } else if (stat.delimiter('-')) {
462 // Unary minus.
463 result = parseArrayTerm(stat);
464 result = new AUnary<double, double>(negate, result);
465 } else {
466 result = parseArrayTerm(stat);
467 }
468
469 while (true) {
470 if (stat.delimiter('+')) {
471 second = parseArrayTerm(stat);
472 result = new ABinary<double, double>(plus, result, second);
473 } else if (stat.delimiter('-')) {
474 second = parseArrayTerm(stat);
475 result = new ABinary<double, double>(minus, result, second);
476 } else {
477 break;
478 }
479 }
480
481 return result;
482 }
483
486 std::vector<double> value = arg->evaluate();
488
489 for (ArrayOfPtrs<double>::size_type i = 0; i < value.size(); ++i) {
490 array.push_back(new SConstant<double>(value[i]));
491 }
492
493 return new AList<double>(array);
494 }
495
496 std::vector<std::string> parseStringArray(Statement& stat) {
497 std::vector<std::string> array;
498
499 if (stat.delimiter('{')) {
500 // List of string values within braces.
501 do {
502 array.push_back(parseStringValue(stat, "String value expected."));
503 } while (stat.delimiter(','));
504
505 parseDelimiter(stat, '}');
506 } else {
507 // A single string value.
508 array.push_back(parseStringValue(stat, "String value expected."));
509 }
510
511 return array;
512 }
513
514 void parseDelimiter(Statement& stat, char delim) {
515 if (!stat.delimiter(delim)) {
516 throw ParseError(
517 "Expressions::parseDelimiter()",
518 std::string("Delimiter '") + delim + "' expected.");
519 }
520 }
521
522 void parseDelimiter(Statement& stat, const char delim[2]) {
523 if (!stat.delimiter(delim)) {
524 throw ParseError(
525 "Expressions::parseDelimiter()",
526 std::string("Delimiter '") + delim + "' expected.");
527 }
528 }
529
531 if (stat.keyword("SELECTED")) {
532 return PlaceRep("SELECTED");
533 } else {
534 PlaceRep pos;
535
536 do {
537 if (stat.delimiter('#')) {
538 static char msg[] = "Expected 'S' or 'E' after '#'.";
539 if (stat.keyword("S")) {
540 pos.append("#S", 0);
541 } else if (stat.keyword("E")) {
542 pos.append("#E", 0);
543 } else {
544 throw ParseError("Expression::parsePlace()", msg);
545 }
546 break;
547 } else {
548 std::string name = parseString(stat, "Expected <name> or '#'.");
549 int occurrence = 1;
550 if (stat.delimiter('[')) {
551 occurrence = int(std::round(parseRealConst(stat)));
552 parseDelimiter(stat, ']');
553
554 if (occurrence <= 0) {
555 throw ParseError(
556 "Expressions::parsePlace()",
557 "Occurrence counter must be positive.");
558 }
559 }
560 pos.append(name, occurrence);
561 }
562 } while (stat.delimiter("::"));
563
564 return pos;
565 }
566 }
567
569 if (stat.keyword("FULL")) {
570 return RangeRep();
571 } else {
572 PlaceRep first = parsePlace(stat);
573 PlaceRep last = first;
574 if (stat.delimiter('/')) last = parsePlace(stat);
575 return RangeRep(first, last);
576 }
577 }
578
580 std::string objName = parseString(stat, "Object name expected.");
581
582 // Test for attribute name.
583 std::string attrName;
584
585 if (stat.delimiter("->")) {
586 // Reference to object attribute.
587 attrName = parseString(stat, "Attribute name expected.");
588 }
589
590 // Parse an index, if present.
591 int index = 0;
592
593 if (stat.delimiter('[')) {
594 index = int(std::round(parseRealConst(stat)));
595 parseDelimiter(stat, ']');
596
597 if (index <= 0) {
598 throw ParseError("Expressions::parseReference()", "Index must be positive.");
599 }
600 }
601
602 // Build reference and fill in the attribute pointer.
603 return new SRefAttr<double>(objName, attrName, index);
604 }
605
607 std::string tabName = parseString(stat, "Table name expected.");
608 parseDelimiter(stat, '@');
609 return TableRowRep(tabName, parsePlace(stat));
610 }
611
612 // ANCILLARY FUNCTIONS.
613 // ------------------------------------------------------------------------
614
616 currentTable = t;
617 PtrToScalar<double> result = parseReal(stat);
618 currentTable = 0;
619 return result;
620 }
621
622 std::list<Token> parseTokenList(Statement& stat) {
623 std::list<Token> result;
624
625 while (!stat.atEnd()) {
626 stat.mark();
627 Token token = stat.getCurrent();
628
629 // End of list if one of the following tokens occurs outside
630 // of brackets.
631 if (token.isDel(',') || token.isDel(';') || token.isDel(')') || token.isDel(']')
632 || token.isDel('}')) {
633 // Must reread the terminating token.
634 stat.restore();
635 break;
636 }
637
638 result.push_back(token);
639
640 if (token.isDel('(')) {
641 parseBracketList(stat, ')', result);
642 } else if (token.isDel('[')) {
643 parseBracketList(stat, ']', result);
644 } else if (token.isDel('{')) {
645 parseBracketList(stat, '}', result);
646 }
647 }
648
649 return result;
650 }
651
652 std::vector<std::list<Token> > parseTokenListArray(Statement& stat) {
653 std::vector<std::list<Token> > array;
654
655 if (stat.delimiter('{')) {
656 // List of token lists within braces.
657 do {
658 array.push_back(parseTokenList(stat));
659 } while (stat.delimiter(','));
660
661 parseDelimiter(stat, '}');
662 } else {
663 // A single token list.
664 array.push_back(parseTokenList(stat));
665 }
666
667 return array;
668 }
669
670 // LOCAL FUNCTIONS.
672 PtrToScalar<bool> result = parseRelation(stat);
673 PtrToScalar<bool> second;
674
675 while (stat.delimiter("&&")) {
676 second = parseRelation(stat);
677 result = SBinary<bool, bool>::make(logAnd, result, second);
678 }
679
680 return result;
681 }
682
685 PtrToArray<double> second;
686
687 if (stat.delimiter('^')) {
688 second = parseArrayPrimary(stat);
689 result = new ABinary<double, double>(power, result, second);
690 }
691
692 return result;
693 }
694
696 PtrToArray<double> result;
697 double value;
698
699 if (stat.delimiter('(')) {
700 result = parseRealArray(stat);
701 parseDelimiter(stat, ')');
702 } else if (stat.delimiter('{')) {
704 do {
705 array.push_back(parseReal(stat));
706 } while (stat.delimiter(','));
707 parseDelimiter(stat, '}');
708 result = new AList<double>(array);
709 } else if (stat.keyword("COLUMN")) {
710 result = parseColumnGenerator(stat);
711 } else if (stat.keyword("ROW")) {
712 result = parseRowGenerator(stat);
713 } else if (stat.keyword("TABLE")) {
714 result = parseTableGenerator(stat);
715 } else if (stat.real(value)) {
717 array.push_back(new SConstant<double>(value));
718 result = new AList<double>(array);
719 } else {
720 std::string frstName = parseString(stat, "Object name expected.");
721 if (stat.delimiter('(')) {
722 // Possible function call.
725 if (const TFunction2<double, double>* fun = find(table2, frstName)) {
726 arg1 = parseRealArray(stat);
727 parseDelimiter(stat, ',');
728 arg2 = parseRealArray(stat);
729 result = new ABinary<double, double>(*fun, arg1, arg2);
730 } else if (const TFunction1<double, double>* fun = find(table1, frstName)) {
731 arg1 = parseRealArray(stat);
732 result = new AUnary<double, double>(*fun, arg1);
733 } else if (frstName == "EVAL") {
734 result = parseRealConstArray(stat);
735 } else if (const TFunction0<double>* fun = find(table0, frstName)) {
737 array.push_back(SNull<double>::make(*fun));
738 result = new AList<double>(array);
739 } else if (const ArrayFun* fun = find(tablea, frstName)) {
740 arg1 = parseRealArray(stat);
742 array.push_back(new ASUnary<double>(*fun, arg1));
743 result = new AList<double>(array);
744 } else {
745 throw ParseError(
746 "parseArrayPrimary()",
747 "Invalid array function name \"" + frstName + "\".");
748 }
749 parseDelimiter(stat, ')');
750 } else if (stat.delimiter("->")) {
751 std::string scndName = parseString(stat, "Attribute name expected.");
752 result = new ARefExpr<double>(frstName, scndName);
753 } else if (stat.delimiter('@')) {
754 PlaceRep row = parsePlace(stat);
755 // Possible column names.
756 if (stat.delimiter("->")) {
757 std::vector<std::string> cols = parseStringArray(stat);
758 result = new ARow(frstName, row, cols);
759 } else {
760 throw ParseError("Expressions::parseReal()", "Expected a column name.");
761 }
762 } else {
763 result = new ARefExpr<double>(frstName, "");
764 }
765 }
766
767 return result;
768 }
769
772 PtrToArray<double> second;
773
774 while (true) {
775 if (stat.delimiter('*')) {
776 second = parseArrayFactor(stat);
777 result = new ABinary<double, double>(times, result, second);
778 } else if (stat.delimiter('/')) {
779 second = parseArrayFactor(stat);
780 result = new ABinary<double, double>(divide, result, second);
781 } else {
782 break;
783 }
784 }
785
786 return result;
787 }
788
789 void parseBracketList(Statement& stat, char close, std::list<Token>& result) {
790 while (true) {
791 if (stat.atEnd() || stat.delimiter(';')) {
792 throw ParseError(
793 "Expressions::parseBracketList()",
794 "Parentheses, brackets or braces do not nest.");
795 }
796
797 Token token = stat.getCurrent();
798 result.push_back(token);
799
800 if (token.isDel('(')) {
801 parseBracketList(stat, ')', result);
802 } else if (token.isDel('[')) {
803 parseBracketList(stat, ']', result);
804 } else if (token.isDel('{')) {
805 parseBracketList(stat, '}', result);
806 } else if (token.isDel(close)) {
807 return;
808 }
809 }
810 }
811
813 PtrToScalar<double> result = parsePrimary(stat);
814 PtrToScalar<double> second;
815
816 if (stat.delimiter('^')) {
817 second = parsePrimary(stat);
818 result = SBinary<double, double>::make(power, result, second);
819 }
820
821 return result;
822 }
823
827 PtrToScalar<double> result;
828 double value;
829
830 if (stat.delimiter('(')) {
831 // Expression in "(...)".
832 result = parseReal(stat);
833 parseDelimiter(stat, ')');
834 } else if (stat.real(value)) {
835 // Litteral constant.
836 result = new SConstant<double>(value);
837 } else if (currentArray && stat.delimiter('#')) {
838 // "#" hash expression
839 result = new SHash(*currentArray);
840 } else {
841 // Primary beginning with a name.
842 std::string frstName = parseString(stat, "Real primary expected.");
843
844 if (stat.delimiter('(')) {
845 // Possible function call.
846 if (const TFunction2<double, double>* fun = find(table2, frstName)) {
847 arg1 = parseReal(stat);
848 parseDelimiter(stat, ',');
849 arg2 = parseReal(stat);
850 result = SBinary<double, double>::make(*fun, arg1, arg2);
851 } else if (const TFunction1<double, double>* fun = find(table1, frstName)) {
852 arg1 = parseReal(stat);
853 result = SUnary<double, double>::make(*fun, arg1);
854 } else if (frstName == "EVAL") {
855 result = new SConstant<double>(parseRealConst(stat));
856 } else if (const TFunction0<double>* fun = find(table0, frstName)) {
857 result = SNull<double>::make(*fun);
858 } else if (const ArrayFun* fun = find(tablea, frstName)) {
860 result = new ASUnary<double>(*fun, arg1);
861 } else {
862 throw ParseError(
863 "parsePrimary()", "Unknown function name \"" + frstName + "\".");
864 }
865 parseDelimiter(stat, ')');
866 } else if (stat.delimiter("->")) {
867 // Possible parameter or object->attribute clause.
868 std::string scndName = parseString(stat, "Attribute or element name expected.");
869
870 // Possible index.
871 if (stat.delimiter('[')) {
872 arg2 = parseReal(stat);
873 parseDelimiter(stat, ']');
874 PtrToArray<double> arg1 = new ARefExpr<double>(frstName, scndName);
875 result = new Indexer<double>(arg1, arg2);
876 } else {
877 result = new SRefExpr<double>(frstName, scndName);
878 }
879 } else if (stat.delimiter('@')) {
880 PlaceRep row = parsePlace(stat);
881 // Possible column name.
882 if (stat.delimiter("->")) {
883 std::string col = parseString(stat, "Column name expected.");
884 result = new SCell(frstName, row, col);
885 } else {
886 throw ParseError("Expressions::parseReal()", "Expected a column name.");
887 }
888 } else {
889 // If the name is indexed, the name must be a global vector.
890 if (stat.delimiter('[')) {
891 arg2 = parseReal(stat);
892 parseDelimiter(stat, ']');
893 PtrToArray<double> arg1 = new ARefExpr<double>(frstName, "");
894 result = new Indexer<double>(arg1, arg2);
895 } else if (currentTable) {
896 // Try making a column expression.
897 result = currentTable->makeColumnExpression(frstName);
898 if (!result.isValid()) {
899 // Could not make a column expression from this name.
900 result = new SRefExpr<double>(frstName, "");
901 }
902 } else {
903 // Simple name must be a global variable.
904 result = new SRefExpr<double>(frstName, "");
905 }
906 }
907 }
908
909 return result;
910 }
911
914 PtrToScalar<double> second;
915 PtrToScalar<bool> result;
916 bool value;
917 std::string name;
918
919 if (stat.delimiter('(')) {
920 result = parseBool(stat);
921 parseDelimiter(stat, ')');
922 } else if (stat.boolean(value)) {
923 result = new SConstant<bool>(value);
924 } else {
925 stat.mark();
926 BoolConstant* bc = 0;
927 if (stat.word(name)
928 && (bc = dynamic_cast<BoolConstant*>(OpalData::getInstance()->find(name)))) {
929 return new SConstant<bool>(bc->getBool());
930 }
931
932 stat.restore();
933 first = parseReal(stat);
934 const TFunction2<bool, double>* code = 0;
935 if (stat.delimiter('<')) {
936 code = &less;
937 } else if (stat.delimiter('>')) {
938 code = &greater;
939 } else if (stat.delimiter(">=")) {
940 code = &greaterEqual;
941 } else if (stat.delimiter("<=")) {
942 code = &lessEqual;
943 } else if (stat.delimiter("==")) {
944 code = &equal;
945 } else if (stat.delimiter("!=")) {
946 code = &notEqual;
947 } else {
948 throw ParseError("parseRelation()", "Invalid boolean expression.");
949 }
950 second = parseReal(stat);
951 result = SBinary<bool, double>::make(*code, first, second);
952 }
953
954 return result;
955 }
956
958 PtrToScalar<double> result = parseFactor(stat);
959 PtrToScalar<double> second;
960
961 while (true) {
962 if (stat.delimiter('*')) {
963 second = parseFactor(stat);
964 result = SBinary<double, double>::make(times, result, second);
965 } else if (stat.delimiter('/')) {
966 second = parseFactor(stat);
967 result = SBinary<double, double>::make(divide, result, second);
968 } else {
969 break;
970 }
971 }
972
973 return result;
974 }
975
977 // COLUMN function builds an array from a table column.
978 // format: COLUMN(<table>, <column>) or
979 // COLUMN(<table>, <column>, <range>).
980 // The word "COLUMN" has already been seen by the caller.
981 parseDelimiter(stat, '(');
982 std::string tabName = parseString(stat, "Table name expected.");
983
984 // Column name.
985 parseDelimiter(stat, ',');
986 std::string colName = parseString(stat, "Column name expected.");
987
988 // Optional range specification.
989 RangeRep range;
990 if (stat.delimiter(',')) {
991 range = parseRange(stat);
992 }
993
994 parseDelimiter(stat, ')');
995 return new AColumn(tabName, colName, range);
996 }
997
999 // ROW function builds an array from a table row.
1000 // format: ROW(<table>, <place>) or
1001 // ROW(<table>, <place>, <columns>).
1002 // The word "ROW" has already been seen by the caller.
1003 parseDelimiter(stat, '(');
1004 std::string tabName = parseString(stat, "Table name expected.");
1005
1006 // Row position.
1007 parseDelimiter(stat, ',');
1008 PlaceRep row = parsePlace(stat);
1009
1010 // Optional column specifications.
1011 std::vector<std::string> columns;
1012 if (stat.delimiter(',')) {
1013 columns = parseStringArray(stat);
1014 parseDelimiter(stat, ')');
1015 }
1016
1017 return new ARow(tabName, row, columns);
1018 }
1019
1021 // TABLE function generates an array from expressions.
1022 // format: "TABLE(<n>, <real>)" or
1023 // "TABLE(<n1>:<n2>, <real>)" or
1024 // "TABLE(<n1>:<n2>:<dn>, <real>)".
1025 // The word "TABLE" has already been read by the caller.
1026 parseDelimiter(stat, '(');
1027
1028 // Read the array index set.
1029 int frst = int(std::round(parseRealConst(stat)));
1030 int last = 1;
1031 int step = 1;
1032
1033 if (stat.delimiter(',')) {
1034 last = frst;
1035 frst = 1;
1036 } else if (stat.delimiter(':')) {
1037 last = int(std::round(parseRealConst(stat)));
1038 if (stat.delimiter(':')) {
1039 step = int(std::round(parseRealConst(stat)));
1040 }
1041 parseDelimiter(stat, ',');
1042 } else {
1043 throw ParseError(
1044 "Expressions::parseTableGenerator()", "Index set incorrect or missing.");
1045 }
1046
1047 // Check the array index set.
1048 if (frst <= 0 || last <= 0 || step <= 0) {
1049 throw ParseError("Expressions::parseTableGenerator()", "Invalid array index set.");
1050 }
1051
1052 // Construct the expression generator.
1053 currentArray = std::make_unique<ATable>(frst, last, step);
1054 currentArray->defineExpression(parseReal(stat));
1055 parseDelimiter(stat, ')');
1056
1057 // The call to release() is required because of type constraints.
1058 return currentArray.release();
1059 }
1060
1061} // namespace Expressions
Template PIC bunch: IPPL PicManager, shared field mesh/solver, and multiple particle containers.
virtual bool getBool() const
Return value.
An array expression with two array operands.
Definition ABinary.h:40
An array expression defined as a table column.
Definition AColumn.h:35
An array expression defined by a list of scalar expressions.
Definition AList.h:35
An expression defined as a reference to an array.
Definition ARefExpr.h:41
An array expression defined as a table row.
Definition ARow.h:34
A scalar expression with one array operand.
Definition ASUnary.h:40
An array expression with one array operand.
Definition AUnary.h:39
An array of pointers to scalar expressions.
A scalar expression to retrieve an indexed component from an array.
Definition Indexer.h:39
A pointer to an array expression.
A pointer to a scalar expression.
static Scalar< T > * make(const TFunction2< T, U > &, PtrToScalar< U > left, PtrToScalar< U > right)
Make a new expression.
Definition SBinary.h:118
A scalar expression referring to a table cell.
Definition SCell.h:35
A scalar constant expression.
Definition SConstant.h:35
A scalar expression.
Definition SHash.h:35
A scalar expression without operands.
Definition SNull.h:37
static Scalar< T > * make(const TFunction0< T > &function)
Make expression.
Definition SNull.h:107
An attribute defined as a reference to a scalar.
Definition SRefAttr.h:47
An expression defined as a reference to a scalar.
Definition SRefExpr.h:40
static Scalar< T > * make(const TFunction1< T, U > &function, PtrToScalar< U > operand)
Make a new expression.
Definition SUnary.h:116
The base class for all OPAL objects.
Definition Object.h:45
PartBunch_t * getPartBunch()
Definition OpalData.cpp:312
Object * find(const std::string &name)
Find entry.
Definition OpalData.cpp:477
static OpalData * getInstance()
Definition OpalData.cpp:193
Parse exception.
Definition ParseError.h:31
Representation of a place within a beam line or sequence.
Definition PlaceRep.h:40
void append(const std::string &, int occur)
Add a name/occurrence pair.
Definition PlaceRep.cpp:47
void gauss(double &gr1, double &gr2)
Gaussian distribution.
double uniform()
Uniform distribution.
Representation of a range within a beam line or sequence.
Definition RangeRep.h:33
static double arcIn()
Return arc length at entrance SI().
Definition SFunction.cpp:37
static double arcOut()
Return arc length at exit SO().
Definition SFunction.cpp:59
static double arcCtr()
Return arc length at center SC().
Definition SFunction.cpp:48
Interface for statements.
Definition Statement.h:37
Token & getCurrent()
Return current token and skip it.
Definition Statement.cpp:61
bool str(std::string &value)
Return string value.
void restore()
Return to marked position.
bool keyword(const char *s)
Test for keyword.
void mark()
Mark position in command.
bool word(std::string &value)
Return word value.
bool boolean(bool &value)
Return boolean value.
Definition Statement.cpp:43
bool real(double &value)
Return real value.
bool atEnd() const
Test for end of command.
Definition Statement.cpp:41
bool delimiter(char c)
Test for delimiter.
Definition Statement.cpp:83
virtual std::string getString() const
Return value.
Representation of a table row reference.
Definition TableRowRep.h:35
The base class for all OPAL tables.
Definition Table.h:41
virtual Expressions::PtrToScalar< double > makeColumnExpression(const std::string &) const =0
Representation of a single input token.
Definition Token.h:32
bool isDel(char del) const
Test for delimiter.
Definition Token.cpp:81
Representation objects and parsers for attribute expressions.
std::string parseStringValue(Statement &, const char msg[])
bool And(bool a, bool b)
bool Or(bool a, bool b)
double Add(double a, double b)
PtrToScalar< bool > parseBool(Statement &)
Parse boolean expression.
bool Ge(double a, double b)
TFunction1< double, const std::vector< double > & > ArrayFun
PtrToScalar< double > parseReal(Statement &)
Parse real expression.
bool Lt(double a, double b)
double Min(double a, double b)
PtrToArray< double > parseArrayTerm(Statement &stat)
double Max(double a, double b)
double Neg(double a)
PtrToScalar< bool > parseAnd(Statement &stat)
double Div(double a, double b)
PtrToScalar< double > parseTerm(Statement &stat)
bool Eq(double a, double b)
double Tgauss(double a)
PtrToArray< double > parseRealConstArray(Statement &)
Parse real array constant.
double Rmsa(const std::vector< double > &array)
PtrToArray< double > parseRowGenerator(Statement &stat)
double Mod(double a, double b)
std::vector< std::string > parseStringArray(Statement &)
Parse string array.
RangeRep parseRange(Statement &)
Parse range specification.
PlaceRep parsePlace(Statement &)
Parse place specification.
const T * find(const T table[], const std::string &name)
Look up name.
Definition TFind.h:33
double ranf()
double Maxa(const std::vector< double > &array)
bool Ne(double a, double b)
SRefAttr< double > * parseReference(Statement &)
Parse variable reference.
std::vector< std::list< Token > > parseTokenListArray(Statement &)
Parse a token list array (for LIST commands).
PtrToArray< double > parseRealArray(Statement &)
Parse real array expression.
PtrToArray< double > parseArrayFactor(Statement &stat)
PtrToArray< double > parseTableGenerator(Statement &stat)
PtrToScalar< double > parseTableExpression(Statement &, const Table *)
Parse table expression (depends on a table's rows).
std::list< Token > parseTokenList(Statement &)
Parse a token list (for macro argument and the like).
double Mpy(double a, double b)
double AbsMax(const std::vector< double > &array)
TableRowRep parseTableRow(Statement &)
Parse a token list (for macro argument and the like).
std::string parseString(Statement &, const char msg[])
Parse string value.
PtrToScalar< bool > parseRelation(Statement &stat)
void parseBracketList(Statement &stat, char close, std::list< Token > &result)
PtrToArray< double > parseArrayPrimary(Statement &stat)
const Table * currentTable
double Mina(const std::vector< double > &array)
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
PtrToScalar< double > parsePrimary(Statement &stat)
std::unique_ptr< ATable > currentArray
double Sub(double a, double b)
double parseRealConst(Statement &)
Parse real constant.
double Sign(double a)
PtrToArray< bool > parseBoolArray(Statement &)
Parse boolean array expression.
PtrToArray< double > parseColumnGenerator(Statement &stat)
bool Gt(double a, double b)
bool Le(double a, double b)
double getEkin()
PtrToScalar< double > parseFactor(Statement &stat)
double gauss()
bool warn
Warn flag.
Definition Options.cpp:33
Random rangen
Definition Options.cpp:36
An operand-less function returning a T.
Definition TFunction0.h:31
A function of one U, returning a T.
Definition TFunction1.h:31
A function of two U's returning a T.
Definition TFunction2.h:31