mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 03:50:16 +00:00
90 lines
2.4 KiB
C++
90 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include "compiler.h"
|
|
#include "ceval.h"
|
|
|
|
#ifdef _WIN32
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <Windows.h>
|
|
#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; i<buffer.size(); i++){
|
|
// no enough lines
|
|
if(buffer[i] != '\n') return true;
|
|
}
|
|
need_more_lines = 0;
|
|
line = buffer;
|
|
buffer.clear();
|
|
mode = CELL_MODE;
|
|
}else{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
try{
|
|
vm->exec(line, "<stdin>", 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
|