| 451 | } |
| 452 | |
| 453 | void repl::exec(const string &code) |
| 454 | { |
| 455 | // Preprocess |
| 456 | ++line_num; |
| 457 | int mode = 0; |
| 458 | for (auto &ch : code) { |
| 459 | if (mode == 0) { |
| 460 | if (!std::isspace(ch)) { |
| 461 | switch (ch) { |
| 462 | case '#': |
| 463 | context->file_buff.emplace_back(); |
| 464 | return; |
| 465 | case '@': |
| 466 | mode = 1; |
| 467 | break; |
| 468 | default: |
| 469 | mode = -1; |
| 470 | } |
| 471 | } |
| 472 | } |
| 473 | else if (mode == 1) { |
| 474 | if (!std::isspace(ch)) |
| 475 | cmd_buff.push_back(ch); |
| 476 | } |
| 477 | else |
| 478 | break; |
| 479 | } |
| 480 | switch (mode) { |
| 481 | default: |
| 482 | break; |
| 483 | case 0: |
| 484 | return; |
| 485 | case 1: { |
| 486 | std::string cmd; |
| 487 | std::swap(cmd_buff, cmd); |
| 488 | if (cmd == "begin" && !multi_line) { |
| 489 | multi_line = true; |
| 490 | context->file_buff.emplace_back(); |
| 491 | } |
| 492 | else if (cmd == "end" && multi_line) { |
| 493 | multi_line = false; |
| 494 | std::string line; |
| 495 | std::swap(line_buff, line); |
| 496 | this->run(line); |
| 497 | } |
| 498 | else { |
| 499 | auto pos = cmd.find(':'); |
| 500 | std::string arg; |
| 501 | if (pos != std::string::npos) |
| 502 | { |
| 503 | arg = cmd.substr(pos + 1); |
| 504 | cmd = cmd.substr(0, pos); |
| 505 | } |
| 506 | if (cmd == "exit") |
| 507 | { |
| 508 | int code = 0; |
| 509 | current_process->on_process_exit.touch(&code); |
| 510 | } |