This commit is contained in:
BLUELOVETH 2023-08-07 21:08:11 +08:00
parent cab174c005
commit c87127dbbd
9 changed files with 38 additions and 73 deletions

View File

@ -15,8 +15,4 @@ May be one of:
+ `darwin`
+ `android`
+ `ios`
+ `emscripten`
### `sys._repl()`
Get a REPL for this vm. Use its `input` method to feed strings to the REPL. This function is experimental.
+ `emscripten`

View File

@ -12,6 +12,7 @@ extern "C" {
typedef struct pkpy_vm_handle pkpy_vm;
typedef int (*pkpy_CFunction)(pkpy_vm*);
typedef void (*pkpy_COutputHandler)(pkpy_vm*, const char*, int);
typedef int pkpy_CName;
typedef int pkpy_CType;
@ -92,6 +93,7 @@ PK_EXPORT pkpy_CString pkpy_string(const char* s);
PK_EXPORT pkpy_CName pkpy_name(const char* s);
PK_EXPORT pkpy_CString pkpy_name_to_string(pkpy_CName name);
PK_EXPORT void pkpy_compile_to_string(pkpy_vm*, const char* source, const char* filename, int mode, bool* ok, char** out);
PK_EXPORT void pkpy_set_output_handler(pkpy_vm*, pkpy_COutputHandler handler);
/* REPL */
PK_EXPORT void* pkpy_new_repl(pkpy_vm*);

View File

@ -104,7 +104,7 @@ struct FrameId{
Frame* get() const { return &data->operator[](index); }
};
typedef void(*PrintFunc)(VM*, const Str&);
typedef void(*PrintFunc)(VM*, const char*, int);
class VM {
PK_ALWAYS_PASS_BY_POINTER(VM)
@ -181,6 +181,10 @@ public:
void _push_varargs(PyObject* _0, PyObject* _1, PyObject* _2){ PUSH(_0); PUSH(_1); PUSH(_2); }
void _push_varargs(PyObject* _0, PyObject* _1, PyObject* _2, PyObject* _3){ PUSH(_0); PUSH(_1); PUSH(_2); PUSH(_3); }
void stdout_write(const Str& s){
_stdout(this, s.data, s.size);
}
template<typename... Args>
PyObject* call(PyObject* callable, Args&&... args){
PUSH(callable);

View File

@ -73,7 +73,7 @@ __NEXT_STEP:;
THIRD() = _0;
DISPATCH();
TARGET(PRINT_EXPR)
if(TOP() != None) _stdout(this, CAST(Str&, py_repr(TOP())) + "\n");
if(TOP() != None) stdout_write(CAST(Str&, py_repr(TOP())) + "\n");
POP();
DISPATCH();
/*****************************************/

View File

@ -1293,59 +1293,8 @@ void add_module_time(VM* vm){
});
}
struct PyREPL{
PY_CLASS(PyREPL, sys, _repl)
REPL* repl;
PyREPL(VM* vm){ repl = new REPL(vm); }
~PyREPL(){ delete repl; }
PyREPL(const PyREPL&) = delete;
PyREPL& operator=(const PyREPL&) = delete;
PyREPL(PyREPL&& other) noexcept{
repl = other.repl;
other.repl = nullptr;
}
struct TempOut{
PrintFunc backup;
VM* vm;
TempOut(VM* vm, PrintFunc f){
this->vm = vm;
this->backup = vm->_stdout;
vm->_stdout = f;
}
~TempOut(){
vm->_stdout = backup;
}
TempOut(const TempOut&) = delete;
TempOut& operator=(const TempOut&) = delete;
TempOut(TempOut&&) = delete;
TempOut& operator=(TempOut&&) = delete;
};
static void _register(VM* vm, PyObject* mod, PyObject* type){
vm->bind_constructor<1>(type, [](VM* vm, ArgsView args){
return VAR_T(PyREPL, vm);
});
vm->bind_method<1>(type, "input", [](VM* vm, ArgsView args){
PyREPL& self = _CAST(PyREPL&, args[0]);
const Str& s = CAST(Str&, args[1]);
PK_LOCAL_STATIC std::stringstream ss_out;
ss_out.str("");
TempOut _(vm, [](VM* vm, const Str& s){ ss_out << s; });
bool ok = self.repl->input(s.str());
return VAR(Tuple({VAR(ok), VAR(ss_out.str())}));
});
}
};
void add_module_sys(VM* vm){
PyObject* mod = vm->new_module("sys");
PyREPL::register_class(vm, mod);
vm->setattr(mod, "version", VAR(PK_VERSION));
vm->setattr(mod, "platform", VAR(PK_SYS_PLATFORM));
@ -1355,12 +1304,14 @@ void add_module_sys(VM* vm){
vm->setattr(mod, "stderr", stderr_);
vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) {
vm->_stdout(vm, CAST(Str&, args[0]));
Str& s = CAST(Str&, args[0]);
vm->_stdout(vm, s.data, s.size);
return vm->None;
});
vm->bind_func<1>(stderr_, "write", [](VM* vm, ArgsView args) {
vm->_stderr(vm, CAST(Str&, args[0]));
Str& s = CAST(Str&, args[0]);
vm->_stderr(vm, s.data, s.size);
return vm->None;
});
}
@ -1460,7 +1411,8 @@ void add_module_traceback(VM* vm){
vm->bind_func<0>(mod, "print_exc", [](VM* vm, ArgsView args) {
if(vm->_last_exception==nullptr) vm->ValueError("no exception");
Exception& e = CAST(Exception&, vm->_last_exception);
vm->_stdout(vm, e.summary());
Str sum = e.summary();
vm->_stdout(vm, sum.data, sum.size);
return vm->None;
});
@ -1486,7 +1438,8 @@ void add_module_dis(VM* vm){
vm->bind_func<1>(mod, "dis", [](VM* vm, ArgsView args) {
CodeObject_ code = get_code(vm, args[0]);
vm->_stdout(vm, vm->disassemble(code));
Str msg = vm->disassemble(code);
vm->_stdout(vm, msg.data, msg.size);
return vm->None;
});

View File

@ -569,6 +569,11 @@ void pkpy_compile_to_string(pkpy_vm* vm_handle, const char* source, const char*
}
}
void pkpy_set_output_handler(pkpy_vm* vm_handle, pkpy_COutputHandler handler){
VM* vm = (VM*) vm_handle;
vm->_stdout = reinterpret_cast<PrintFunc>(handler);
}
void* pkpy_new_repl(pkpy_vm* vm_handle){
return new REPL((VM*)vm_handle);
}

View File

@ -2,10 +2,10 @@
namespace pkpy {
REPL::REPL(VM* vm) : vm(vm){
vm->_stdout(vm, "pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") ");
vm->_stdout(vm, fmt("[", sizeof(void*)*8, " bit] on ", PK_SYS_PLATFORM "\n"));
vm->_stdout(vm, "https://github.com/blueloveTH/pocketpy" "\n");
vm->_stdout(vm, "Type \"exit()\" to exit." "\n");
vm->stdout_write("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") ");
vm->stdout_write(fmt("[", sizeof(void*)*8, " bit] on ", PK_SYS_PLATFORM "\n"));
vm->stdout_write("https://github.com/blueloveTH/pocketpy" "\n");
vm->stdout_write("Type \"exit()\" to exit." "\n");
}
bool REPL::input(std::string line){

View File

@ -5,13 +5,13 @@ namespace pkpy{
VM::VM(bool enable_os) : heap(this), enable_os(enable_os) {
this->vm = this;
this->_c.error = nullptr;
_stdout = [](VM* vm, const Str& s) {
_stdout = [](VM* vm, const char* buf, int size) {
PK_UNUSED(vm);
std::cout << s;
std::cout.write(buf, size);
};
_stderr = [](VM* vm, const Str& s) {
_stderr = [](VM* vm, const char* buf, int size) {
PK_UNUSED(vm);
std::cerr << s;
std::cerr.write(buf, size);
};
callstack.reserve(8);
_main = nullptr;
@ -99,13 +99,14 @@ namespace pkpy{
#endif
return _exec(code, _module);
}catch (const Exception& e){
_stderr(this, e.summary() + "\n");
Str sum = e.summary() + "\n";
_stderr(this, sum.data, sum.size);
}
#if !PK_DEBUG_FULL_EXCEPTION
catch (const std::exception& e) {
Str msg = "An std::exception occurred! It could be a bug.\n";
msg = msg + e.what();
_stderr(this, msg + "\n");
msg = msg + e.what() + "\n";
_stderr(this, msg.data, msg.size);
}
#endif
callstack.clear();

View File

@ -237,6 +237,10 @@ void pkpy_compile_to_string(pkpy_vm* vm, const char* source, const char* filenam
}
void pkpy_set_output_handler(pkpy_vm* vm, pkpy_COutputHandler handler) {
}
void* pkpy_new_repl(pkpy_vm* vm) {
void* returnValue;
return returnValue;