localOnly restricts assignments to local variables.
| 2700 | |
| 2701 | // localOnly restricts assignments to local variables. |
| 2702 | GameValue GameState::EvaluateMultiple(const char* expression, bool localOnly) const |
| 2703 | { |
| 2704 | // Reentrancy guard — see Evaluate above and VyhodFrameGuard. |
| 2705 | VyhodFrameGuard frameGuard(*_e); |
| 2706 | |
| 2707 | _e->_pos = _e->_pos0 = expression; |
| 2708 | _e->_subexpBeg = expression; |
| 2709 | _e->_subexpEnd = expression + strlen(expression); |
| 2710 | |
| 2711 | _e->_error = EvalOK; |
| 2712 | _e->_errorText = RString(); |
| 2713 | |
| 2714 | GameValue ret = NOTHING; |
| 2715 | while (*_e->_pos) |
| 2716 | { |
| 2717 | if ((ret.GetType() & GameNothing) == 0) |
| 2718 | { |
| 2719 | if (_e->_checkOnly) |
| 2720 | { |
| 2721 | TypeError(GameNothing, ret.GetType()); |
| 2722 | break; |
| 2723 | } |
| 2724 | } |
| 2725 | vynech(); |
| 2726 | // check if expression is assignment |
| 2727 | // assignment must start with identifier |
| 2728 | _e->_subexpBeg = _e->_pos; |
| 2729 | if (CheckAssignment(_e->_pos)) |
| 2730 | { |
| 2731 | if (!const_cast<GameState*>(this)->PerformAssignment(localOnly)) |
| 2732 | { |
| 2733 | break; |
| 2734 | } |
| 2735 | ret = NOTHING; |
| 2736 | } |
| 2737 | else // non assignment |
| 2738 | { |
| 2739 | // check for empty command |
| 2740 | GameValue value = Vyhod(); |
| 2741 | CleanStack(); |
| 2742 | if (_e->_error) |
| 2743 | { |
| 2744 | // exitWith propagates its value even when breaking |
| 2745 | if (_e->_error == EvalBreak) |
| 2746 | ret = value; |
| 2747 | break; |
| 2748 | } |
| 2749 | |
| 2750 | // check expression result |
| 2751 | // if result is nothing it's OK |
| 2752 | // if result is fake type it is not OK |
| 2753 | ret = value; |
| 2754 | } // single command executed |
| 2755 | vynech(); |
| 2756 | char c = *_e->_pos; |
| 2757 | if (c == 0) |
| 2758 | { |
| 2759 | break; |