| 240 | return _input_stack[_next_input_index].next_token == tokid; |
| 241 | } |
| 242 | void reshadefx::preprocessor::consume() |
| 243 | { |
| 244 | _current_input_index = _next_input_index; |
| 245 | |
| 246 | if (_input_stack.empty()) |
| 247 | { |
| 248 | // End of input has been reached already (this can happen when the input text is not terminated with a new line) |
| 249 | assert(_current_input_index == 0); |
| 250 | return; |
| 251 | } |
| 252 | |
| 253 | // Clear out input stack, now that the current token is overwritten |
| 254 | while (_input_stack.size() > (_current_input_index + 1)) |
| 255 | _input_stack.pop_back(); |
| 256 | |
| 257 | // Update location information after switching input levels |
| 258 | input_level &input = _input_stack[_current_input_index]; |
| 259 | if (!input.name.empty() && input.name != _output_location.source) |
| 260 | { |
| 261 | _output += "#line " + std::to_string(input.next_token.location.line) + " \"" + input.name + "\"\n"; |
| 262 | // Line number is increased before checking against next token in 'tokenid::end_of_line' handling in 'parse' function below, so compensate for that here |
| 263 | _output_location.line = input.next_token.location.line - 1; |
| 264 | _output_location.source = input.name; |
| 265 | } |
| 266 | |
| 267 | // Set current token |
| 268 | _token = std::move(input.next_token); |
| 269 | _current_token_raw_data = input.lexer->input_string().substr(_token.offset, _token.length); |
| 270 | |
| 271 | // Get the next token |
| 272 | input.next_token = input.lexer->lex(); |
| 273 | |
| 274 | // Verify string literals (since the lexer cannot throw errors itself) |
| 275 | if (_token == tokenid::string_literal && _current_token_raw_data.back() != '\"') |
| 276 | error(_token.location, "unterminated string literal"); |
| 277 | |
| 278 | // Pop input level if lexical analysis has reached the end of it |
| 279 | // This ensures the EOF token is not consumed until the very last file |
| 280 | while (peek(tokenid::end_of_file)) |
| 281 | { |
| 282 | // Remove any unterminated blocks from the stack |
| 283 | for (; !_if_stack.empty() && _if_stack.back().input_index >= _next_input_index; _if_stack.pop_back()) |
| 284 | error(_if_stack.back().pp_token.location, "unterminated #if"); |
| 285 | |
| 286 | if (_next_input_index == 0) |
| 287 | { |
| 288 | // End of input has been reached, so cannot pop further and this is the last token |
| 289 | _input_stack.pop_back(); |
| 290 | return; |
| 291 | } |
| 292 | else |
| 293 | { |
| 294 | _next_input_index -= 1; |
| 295 | } |
| 296 | } |
| 297 | } |
| 298 | void reshadefx::preprocessor::consume_until(tokenid tokid) |
| 299 | { |