mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
...
This commit is contained in:
parent
5616c87a23
commit
6b25aae3f7
@ -67,7 +67,10 @@ __NEXT_STEP:;
|
|||||||
TARGET(DUP_TOP) PUSH(TOP()); DISPATCH();
|
TARGET(DUP_TOP) PUSH(TOP()); DISPATCH();
|
||||||
TARGET(ROT_TWO) std::swap(TOP(), SECOND()); DISPATCH();
|
TARGET(ROT_TWO) std::swap(TOP(), SECOND()); DISPATCH();
|
||||||
TARGET(PRINT_EXPR)
|
TARGET(PRINT_EXPR)
|
||||||
if(TOP() != None) *_stdout << CAST(Str&, asRepr(TOP())) << '\n';
|
if(TOP() != None){
|
||||||
|
_stdout(this, CAST(Str&, asRepr(TOP())));
|
||||||
|
_stdout(this, "\n");
|
||||||
|
}
|
||||||
POP();
|
POP();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
|
@ -14,7 +14,7 @@ int main(int argc, char** argv){
|
|||||||
pkpy::REPL* repl = pkpy_new_repl(vm);
|
pkpy::REPL* repl = pkpy_new_repl(vm);
|
||||||
bool need_more_lines = false;
|
bool need_more_lines = false;
|
||||||
while(true){
|
while(true){
|
||||||
(*vm->_stdout) << (need_more_lines ? "... " : ">>> ");
|
vm->_stdout(vm, need_more_lines ? "... " : ">>> ");
|
||||||
bool eof = false;
|
bool eof = false;
|
||||||
std::string line = pkpy::getline(&eof);
|
std::string line = pkpy::getline(&eof);
|
||||||
if(eof) break;
|
if(eof) break;
|
||||||
|
@ -770,12 +770,12 @@ inline void add_module_sys(VM* vm){
|
|||||||
vm->setattr(mod, "stderr", stderr_);
|
vm->setattr(mod, "stderr", stderr_);
|
||||||
|
|
||||||
vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) {
|
vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) {
|
||||||
(*vm->_stdout) << CAST(Str&, args[0]).sv();
|
vm->_stdout(vm, CAST(Str&, args[0]));
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_func<1>(stderr_, "write", [](VM* vm, ArgsView args) {
|
vm->bind_func<1>(stderr_, "write", [](VM* vm, ArgsView args) {
|
||||||
(*vm->_stderr) << CAST(Str&, args[0]).sv();
|
vm->_stderr(vm, CAST(Str&, args[0]));
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -828,7 +828,7 @@ inline void add_module_dis(VM* vm){
|
|||||||
PyObject* f = args[0];
|
PyObject* f = args[0];
|
||||||
if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, args[0]).func;
|
if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, args[0]).func;
|
||||||
CodeObject_ code = CAST(Function&, f).decl->code;
|
CodeObject_ code = CAST(Function&, f).decl->code;
|
||||||
(*vm->_stdout) << vm->disassemble(code);
|
vm->_stdout(vm, vm->disassemble(code));
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1105,15 +1105,9 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
pkpy::VM* pkpy_new_vm(bool use_stdio=true, bool enable_os=true){
|
pkpy::VM* pkpy_new_vm(bool enable_os=true){
|
||||||
pkpy::VM* p = new pkpy::VM(use_stdio, enable_os);
|
pkpy::VM* p = new pkpy::VM(enable_os);
|
||||||
_pk_deleter_map[p] = [](void* p){ delete (pkpy::VM*)p; };
|
_pk_deleter_map[p] = [](void* p){ delete (pkpy::VM*)p; };
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
|
||||||
char* pkpy_vm_read_output(pkpy::VM* vm){
|
|
||||||
std::string json = vm->read_output();
|
|
||||||
return strdup(json.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -49,10 +49,10 @@ protected:
|
|||||||
VM* vm;
|
VM* vm;
|
||||||
public:
|
public:
|
||||||
REPL(VM* vm) : vm(vm){
|
REPL(VM* vm) : vm(vm){
|
||||||
(*vm->_stdout) << ("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") ");
|
vm->_stdout(vm, "pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") ");
|
||||||
(*vm->_stdout) << "[" << std::to_string(sizeof(void*) * 8) << " bit]" "\n";
|
vm->_stdout(vm, fmt("[", sizeof(void*)*8, " bit]" "\n"));
|
||||||
(*vm->_stdout) << ("https://github.com/blueloveTH/pocketpy" "\n");
|
vm->_stdout(vm, "https://github.com/blueloveTH/pocketpy" "\n");
|
||||||
(*vm->_stdout) << ("Type \"exit()\" to exit." "\n");
|
vm->_stdout(vm, "Type \"exit()\" to exit." "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool input(std::string line){
|
bool input(std::string line){
|
||||||
|
37
src/vm.h
37
src/vm.h
@ -73,6 +73,8 @@ struct FrameId{
|
|||||||
Frame* operator->() const { return &data->operator[](index); }
|
Frame* operator->() const { return &data->operator[](index); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void(*PrintFunc)(VM*, const Str&);
|
||||||
|
|
||||||
class VM {
|
class VM {
|
||||||
VM* vm; // self reference for simplify code
|
VM* vm; // self reference for simplify code
|
||||||
public:
|
public:
|
||||||
@ -93,10 +95,8 @@ public:
|
|||||||
PyObject* StopIteration;
|
PyObject* StopIteration;
|
||||||
PyObject* _main; // __main__ module
|
PyObject* _main; // __main__ module
|
||||||
|
|
||||||
std::stringstream _stdout_buffer;
|
PrintFunc _stdout;
|
||||||
std::stringstream _stderr_buffer;
|
PrintFunc _stderr;
|
||||||
std::ostream* _stdout;
|
|
||||||
std::ostream* _stderr;
|
|
||||||
|
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
|
|
||||||
@ -109,31 +109,16 @@ public:
|
|||||||
|
|
||||||
const bool enable_os;
|
const bool enable_os;
|
||||||
|
|
||||||
VM(bool use_stdio=true, bool enable_os=true) : heap(this), enable_os(enable_os) {
|
VM(bool enable_os=true) : heap(this), enable_os(enable_os) {
|
||||||
this->vm = this;
|
this->vm = this;
|
||||||
this->_stdout = use_stdio ? &std::cout : &_stdout_buffer;
|
_stdout = [](VM* vm, const Str& s) { std::cout << s; };
|
||||||
this->_stderr = use_stdio ? &std::cerr : &_stderr_buffer;
|
_stderr = [](VM* vm, const Str& s) { std::cerr << s; };
|
||||||
callstack.reserve(8);
|
callstack.reserve(8);
|
||||||
_initialized = false;
|
_initialized = false;
|
||||||
init_builtin_types();
|
init_builtin_types();
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_stdio_used() const { return _stdout == &std::cout; }
|
|
||||||
|
|
||||||
std::string read_output(){
|
|
||||||
if(is_stdio_used()) UNREACHABLE();
|
|
||||||
std::stringstream* s_out = (std::stringstream*)(vm->_stdout);
|
|
||||||
std::stringstream* s_err = (std::stringstream*)(vm->_stderr);
|
|
||||||
pkpy::Str _stdout = s_out->str();
|
|
||||||
pkpy::Str _stderr = s_err->str();
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << '{' << "\"stdout\": " << _stdout.escape(false);
|
|
||||||
ss << ", " << "\"stderr\": " << _stderr.escape(false) << '}';
|
|
||||||
s_out->str(""); s_err->str("");
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameId top_frame() {
|
FrameId top_frame() {
|
||||||
#if DEBUG_EXTRA_CHECK
|
#if DEBUG_EXTRA_CHECK
|
||||||
if(callstack.empty()) FATAL_ERROR();
|
if(callstack.empty()) FATAL_ERROR();
|
||||||
@ -195,13 +180,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
return _exec(code, _module);
|
return _exec(code, _module);
|
||||||
}catch (const Exception& e){
|
}catch (const Exception& e){
|
||||||
*_stderr << e.summary() << '\n';
|
_stderr(this, e.summary() + "\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
#if !DEBUG_FULL_EXCEPTION
|
#if !DEBUG_FULL_EXCEPTION
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
*_stderr << "An std::exception occurred! It could be a bug.\n";
|
_stderr(this, "An std::exception occurred! It could be a bug.\n");
|
||||||
*_stderr << e.what() << '\n';
|
_stderr(this, e.what());
|
||||||
|
_stderr(this, "\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
callstack.clear();
|
callstack.clear();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user