main.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include <fstream>
  2. #include <filesystem>
  3. #include <iostream>
  4. #include <sstream>
  5. #if __has_include("pocketpy_c.h")
  6. #include "pocketpy_c.h"
  7. #else
  8. #include "pocketpy.h"
  9. #endif
  10. #ifdef _WIN32
  11. std::string pkpy_platform_getline(bool* eof){
  12. HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
  13. std::wstringstream wss;
  14. WCHAR buf;
  15. DWORD read;
  16. while (ReadConsoleW(hStdin, &buf, 1, &read, NULL) && buf != L'\n') {
  17. if(eof && buf == L'\x1A') *eof = true; // Ctrl+Z
  18. wss << buf;
  19. }
  20. std::wstring wideInput = wss.str();
  21. int length = WideCharToMultiByte(CP_UTF8, 0, wideInput.c_str(), (int)wideInput.length(), NULL, 0, NULL, NULL);
  22. std::string output;
  23. output.resize(length);
  24. WideCharToMultiByte(CP_UTF8, 0, wideInput.c_str(), (int)wideInput.length(), &output[0], length, NULL, NULL);
  25. if(!output.empty() && output.back() == '\r') output.pop_back();
  26. return output;
  27. }
  28. #else
  29. std::string pkpy_platform_getline(bool* eof){
  30. std::string output;
  31. if(!std::getline(std::cin, output)){
  32. if(eof) *eof = true;
  33. }
  34. return output;
  35. }
  36. #endif
  37. std::string f_input(){
  38. bool eof;
  39. return pkpy_platform_getline(&eof);
  40. }
  41. static int f_input(pkpy_vm* vm){
  42. if(!pkpy_is_none(vm, -1)){
  43. pkpy_CString prompt;
  44. bool ok = pkpy_to_string(vm, -1, &prompt);
  45. if(!ok) return 0;
  46. std::cout << std::string_view(prompt.data, prompt.size) << std::flush;
  47. }
  48. bool eof;
  49. std::string output = pkpy_platform_getline(&eof);
  50. pkpy_push_string(vm, pkpy_string(output.c_str()));
  51. return 1;
  52. }
  53. int main(int argc, char** argv){
  54. #if _WIN32
  55. SetConsoleCP(CP_UTF8);
  56. SetConsoleOutputCP(CP_UTF8);
  57. #endif
  58. pkpy_vm* vm = pkpy_new_vm(true);
  59. pkpy_push_function(vm, "input(prompt=None) -> str", f_input);
  60. pkpy_eval(vm, "__import__('builtins')");
  61. pkpy_setattr(vm, pkpy_name("input"));
  62. if(argc == 1){
  63. void* repl = pkpy_new_repl(vm);
  64. bool need_more_lines = false;
  65. while(true){
  66. std::cout << (need_more_lines ? "... " : ">>> ");
  67. bool eof = false;
  68. std::string line = pkpy_platform_getline(&eof);
  69. if(eof) break;
  70. need_more_lines = pkpy_repl_input(repl, line.c_str());
  71. }
  72. pkpy_delete_vm(vm);
  73. return 0;
  74. }
  75. if(argc == 2){
  76. std::string argv_1 = argv[1];
  77. if(argv_1 == "-h" || argv_1 == "--help") goto __HELP;
  78. std::filesystem::path filepath(argv[1]);
  79. filepath = std::filesystem::absolute(filepath);
  80. if(!std::filesystem::exists(filepath)){
  81. std::cerr << "File not found: " << argv_1 << std::endl;
  82. return 2;
  83. }
  84. std::ifstream file(filepath);
  85. if(!file.is_open()){
  86. std::cerr << "Failed to open file: " << argv_1 << std::endl;
  87. return 3;
  88. }
  89. std::string src((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
  90. file.close();
  91. // set parent path as cwd
  92. std::filesystem::current_path(filepath.parent_path());
  93. bool ok = pkpy_exec_2(vm, src.c_str(), filepath.filename().string().c_str(), 0, NULL);
  94. if(!ok) pkpy_clear_error(vm, NULL);
  95. pkpy_delete_vm(vm);
  96. return ok ? 0 : 1;
  97. }
  98. __HELP:
  99. std::cout << "Usage: pocketpy [filename]" << std::endl;
  100. return 0;
  101. }