#pragma once #include "compiler.h" #include "ceval.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #endif namespace pkpy{ #ifdef _WIN32 inline std::string getline(bool* eof=nullptr) { HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); std::wstringstream wss; WCHAR buf; DWORD read; while (ReadConsoleW(hStdin, &buf, 1, &read, NULL) && buf != L'\n') { if(eof && buf == L'\x1A') *eof = true; // Ctrl+Z wss << buf; } std::wstring wideInput = wss.str(); int length = WideCharToMultiByte(CP_UTF8, 0, wideInput.c_str(), (int)wideInput.length(), NULL, 0, NULL, NULL); std::string output; output.resize(length); WideCharToMultiByte(CP_UTF8, 0, wideInput.c_str(), (int)wideInput.length(), &output[0], length, NULL, NULL); if(!output.empty() && output.back() == '\r') output.pop_back(); return output; } #else inline std::string getline(bool* eof=nullptr){ std::string line; if(!std::getline(std::cin, line)){ if(eof) *eof = true; } return line; } #endif class REPL { protected: int need_more_lines = 0; std::string buffer; VM* vm; public: REPL(VM* vm) : vm(vm){ vm->_stdout(vm, "pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") "); vm->_stdout(vm, fmt("[", sizeof(void*)*8, " bit]" "\n")); vm->_stdout(vm, "https://github.com/blueloveTH/pocketpy" "\n"); vm->_stdout(vm, "Type \"exit()\" to exit." "\n"); } bool input(std::string line){ CompileMode mode = REPL_MODE; if(need_more_lines){ buffer += line; buffer += '\n'; int n = buffer.size(); if(n>=need_more_lines){ for(int i=buffer.size()-need_more_lines; iexec(line, "", mode); }catch(NeedMoreLines& ne){ buffer += line; buffer += '\n'; need_more_lines = ne.is_compiling_class ? 3 : 2; if (need_more_lines) return true; } return false; } }; } // namespace pkpy