| 502 | } |
| 503 | |
| 504 | FieldGeneratorPtr ExpressionParser::parsePrimary(LexInfo& lex) const { |
| 505 | switch (lex.curtok) { |
| 506 | case -1: { // a number |
| 507 | lex.nextToken(); // Eat number |
| 508 | return std::make_shared<FieldValue>(lex.curval); |
| 509 | } |
| 510 | case -2: { |
| 511 | return parseIdentifierExpr(lex); |
| 512 | } |
| 513 | case -3: { |
| 514 | // A parameter, passed as an argument to generate |
| 515 | auto gen = std::make_shared<FieldParam>(lex.curident); |
| 516 | lex.nextToken(); |
| 517 | return gen; |
| 518 | } |
| 519 | case '-': { |
| 520 | // Unary minus |
| 521 | // Don't eat the minus, and return an implicit zero |
| 522 | return std::make_shared<FieldValue>(0.0); |
| 523 | } |
| 524 | case '!': { |
| 525 | // Logical not |
| 526 | lex.nextToken(); // Eat '!' |
| 527 | return std::make_shared<LogicalNot>(parsePrimary(lex)); |
| 528 | } |
| 529 | case '(': { |
| 530 | return parseParenExpr(lex); |
| 531 | } |
| 532 | case '[': { |
| 533 | // Define a new context (scope). |
| 534 | return parseContextExpr(lex); |
| 535 | } |
| 536 | } |
| 537 | throw ParseException("Unexpected token {:d} ({:c})", static_cast<int>(lex.curtok), |
| 538 | static_cast<char>(lex.curtok)); |
| 539 | } |
| 540 | |
| 541 | FieldGeneratorPtr ExpressionParser::parseBinOpRHS(LexInfo& lex, int ExprPrec, |
| 542 | FieldGeneratorPtr lhs) const { |