main.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <iostream>
  2. #include <fstream>
  3. #include "pocketpy.h"
  4. #define PK_DEBUG_TIME
  5. struct Timer{
  6. const char* title;
  7. Timer(const char* title) : title(title) {}
  8. void run(std::function<void()> f){
  9. auto start = std::chrono::high_resolution_clock::now();
  10. f();
  11. auto end = std::chrono::high_resolution_clock::now();
  12. double elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000000.0;
  13. #ifdef PK_DEBUG_TIME
  14. std::cout << title << ": " << elapsed << " s" << std::endl;
  15. #endif
  16. }
  17. };
  18. ThreadedVM* new_tvm_with_callbacks(){
  19. ThreadedVM* vm = pkpy_new_tvm([](const VM* vm, const char* str) {
  20. std::cout << str; std::cout.flush();
  21. }, [](const VM* vm, const char* str) {
  22. std::cerr << str; std::cerr.flush();
  23. });
  24. return vm;
  25. }
  26. VM* new_vm_with_callbacks(){
  27. VM* vm = pkpy_new_vm([](const VM* vm, const char* str) {
  28. std::cout << str; std::cout.flush();
  29. }, [](const VM* vm, const char* str) {
  30. std::cerr << str; std::cerr.flush();
  31. });
  32. return vm;
  33. }
  34. #if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__wasm32__) || defined(__wasm64__)
  35. // these code is for demo use, feel free to modify it
  36. REPL* _repl;
  37. extern "C" {
  38. __EXPORT
  39. void repl_start(){
  40. _repl = pkpy_new_repl(new_vm_with_callbacks(), false);
  41. }
  42. __EXPORT
  43. bool repl_input(const char* line){
  44. return pkpy_repl_input(_repl, line);
  45. }
  46. }
  47. #else
  48. int main(int argc, char** argv){
  49. if(argc == 1){
  50. REPL repl(new_vm_with_callbacks());
  51. while(true){
  52. std::string line;
  53. std::getline(std::cin, line);
  54. repl.input(line);
  55. }
  56. return 0;
  57. }
  58. if(argc == 2){
  59. std::string filename = argv[1];
  60. if(filename == "-h" || filename == "--help") goto __HELP;
  61. std::ifstream file(filename);
  62. if(!file.is_open()){
  63. std::cerr << "File not found: " << filename << std::endl;
  64. return 1;
  65. }
  66. std::string src((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
  67. ThreadedVM* vm = new_tvm_with_callbacks();
  68. _Code code;
  69. Timer("Compile time").run([&]{
  70. code = compile(vm, src.c_str(), filename);
  71. });
  72. if(code == nullptr) return 1;
  73. //std::cout << code->toString() << std::endl;
  74. Timer("Running time").run([=]{
  75. vm->startExec(code);
  76. while(pkpy_tvm_get_state(vm) != THREAD_FINISHED){
  77. if(pkpy_tvm_get_state(vm) == THREAD_SUSPENDED){
  78. std::string line;
  79. std::getline(std::cin, line);
  80. pkpy_tvm_write_stdin(vm, line.c_str());
  81. pkpy_tvm_resume(vm);
  82. }
  83. }
  84. });
  85. return 0;
  86. }
  87. __HELP:
  88. std::cout << "Usage: pocketpy [filename]" << std::endl;
  89. return 0;
  90. }
  91. #endif