* @throws InternalError thrown if maximum AST depth is exceeded */
| 728 | * @throws InternalError thrown if maximum AST depth is exceeded |
| 729 | */ |
| 730 | static void compileBinOp(Token *&tok, AST_state& state, void (*f)(Token *&tok, AST_state& state)) |
| 731 | { |
| 732 | Token *binop = tok; |
| 733 | if (f) { |
| 734 | tok = tok->next(); |
| 735 | if (Token::simpleMatch(binop, ",") && state.inGeneric) |
| 736 | skipGenericType(tok); |
| 737 | const bool inGenericSaved = state.inGeneric; |
| 738 | state.inGeneric = false; |
| 739 | if (Token::Match(binop, "::|. ~")) |
| 740 | tok = tok->next(); |
| 741 | state.depth++; |
| 742 | if (tok && state.depth <= AST_MAX_DEPTH) |
| 743 | f(tok, state); |
| 744 | if (state.depth > AST_MAX_DEPTH) |
| 745 | throw InternalError(tok, "maximum AST depth exceeded", InternalError::AST); |
| 746 | state.depth--; |
| 747 | state.inGeneric = inGenericSaved; |
| 748 | } |
| 749 | |
| 750 | // TODO: Should we check if op is empty. |
| 751 | // * Is it better to add assertion that it isn't? |
| 752 | // * Write debug warning if it's empty? |
| 753 | if (!state.op.empty()) { |
| 754 | binop->astOperand2(state.op.top()); |
| 755 | state.op.pop(); |
| 756 | } |
| 757 | if (!state.op.empty()) { |
| 758 | binop->astOperand1(state.op.top()); |
| 759 | state.op.pop(); |
| 760 | } |
| 761 | if (!state.op.empty() && state.op.top() == binop) |
| 762 | throw InternalError(tok, "Syntax Error: Infinite loop when creating AST.", InternalError::AST); |
| 763 | state.op.push(binop); |
| 764 | } |
| 765 | |
| 766 | static void compileExpression(Token *&tok, AST_state& state); |
| 767 |
no test coverage detected