| 2916 | } |
| 2917 | |
| 2918 | void GameState::Execute(const char* expression) |
| 2919 | { |
| 2920 | // Reentrancy guard — see Evaluate above and VyhodFrameGuard. |
| 2921 | VyhodFrameGuard frameGuard(*_e); |
| 2922 | |
| 2923 | _e->_error = EvalOK; |
| 2924 | _e->_errorText = RString(); |
| 2925 | |
| 2926 | if (expression[0] == 0) |
| 2927 | { |
| 2928 | return; |
| 2929 | } |
| 2930 | _e->_pos = _e->_pos0 = expression; |
| 2931 | _e->_subexpBeg = expression; |
| 2932 | _e->_subexpEnd = expression + strlen(expression); |
| 2933 | |
| 2934 | while (*_e->_pos) |
| 2935 | { |
| 2936 | vynech(); |
| 2937 | // check if expression is assignment |
| 2938 | // assignment must start with identifier |
| 2939 | _e->_subexpBeg = _e->_pos; |
| 2940 | if (CheckAssignment(_e->_pos)) |
| 2941 | { |
| 2942 | if (!PerformAssignment()) |
| 2943 | { |
| 2944 | break; |
| 2945 | } |
| 2946 | } |
| 2947 | else // non assignment |
| 2948 | { |
| 2949 | GameValue value = Vyhod(); |
| 2950 | CleanStack(); |
| 2951 | if (_e->_error) |
| 2952 | { |
| 2953 | break; |
| 2954 | } |
| 2955 | |
| 2956 | // check expression result |
| 2957 | // if result is nothing it's OK |
| 2958 | if ((value.GetType() & GameNothing) == 0) |
| 2959 | { |
| 2960 | // otherwise we may issue error |
| 2961 | if (_e->_checkOnly) |
| 2962 | { |
| 2963 | TypeError(GameNothing, value.GetType()); |
| 2964 | break; |
| 2965 | } |
| 2966 | } |
| 2967 | } // single command executed |
| 2968 | vynech(); |
| 2969 | char c = *_e->_pos; |
| 2970 | if (c == 0) |
| 2971 | { |
| 2972 | break; |
| 2973 | } |
| 2974 | if (c != ';' && (c != ',' || _e->_checkOnly)) |
| 2975 | { |
no test coverage detected