mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
cab174c005
commit
c87127dbbd
@ -15,8 +15,4 @@ May be one of:
|
|||||||
+ `darwin`
|
+ `darwin`
|
||||||
+ `android`
|
+ `android`
|
||||||
+ `ios`
|
+ `ios`
|
||||||
+ `emscripten`
|
+ `emscripten`
|
||||||
|
|
||||||
### `sys._repl()`
|
|
||||||
|
|
||||||
Get a REPL for this vm. Use its `input` method to feed strings to the REPL. This function is experimental.
|
|
@ -12,6 +12,7 @@ extern "C" {
|
|||||||
|
|
||||||
typedef struct pkpy_vm_handle pkpy_vm;
|
typedef struct pkpy_vm_handle pkpy_vm;
|
||||||
typedef int (*pkpy_CFunction)(pkpy_vm*);
|
typedef int (*pkpy_CFunction)(pkpy_vm*);
|
||||||
|
typedef void (*pkpy_COutputHandler)(pkpy_vm*, const char*, int);
|
||||||
typedef int pkpy_CName;
|
typedef int pkpy_CName;
|
||||||
typedef int pkpy_CType;
|
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_CName pkpy_name(const char* s);
|
||||||
PK_EXPORT pkpy_CString pkpy_name_to_string(pkpy_CName name);
|
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_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 */
|
/* REPL */
|
||||||
PK_EXPORT void* pkpy_new_repl(pkpy_vm*);
|
PK_EXPORT void* pkpy_new_repl(pkpy_vm*);
|
||||||
|
@ -104,7 +104,7 @@ struct FrameId{
|
|||||||
Frame* get() const { return &data->operator[](index); }
|
Frame* get() const { return &data->operator[](index); }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void(*PrintFunc)(VM*, const Str&);
|
typedef void(*PrintFunc)(VM*, const char*, int);
|
||||||
|
|
||||||
class VM {
|
class VM {
|
||||||
PK_ALWAYS_PASS_BY_POINTER(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){ 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 _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>
|
template<typename... Args>
|
||||||
PyObject* call(PyObject* callable, Args&&... args){
|
PyObject* call(PyObject* callable, Args&&... args){
|
||||||
PUSH(callable);
|
PUSH(callable);
|
||||||
|
@ -73,7 +73,7 @@ __NEXT_STEP:;
|
|||||||
THIRD() = _0;
|
THIRD() = _0;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
TARGET(PRINT_EXPR)
|
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();
|
POP();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
|
@ -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){
|
void add_module_sys(VM* vm){
|
||||||
PyObject* mod = vm->new_module("sys");
|
PyObject* mod = vm->new_module("sys");
|
||||||
PyREPL::register_class(vm, mod);
|
|
||||||
vm->setattr(mod, "version", VAR(PK_VERSION));
|
vm->setattr(mod, "version", VAR(PK_VERSION));
|
||||||
vm->setattr(mod, "platform", VAR(PK_SYS_PLATFORM));
|
vm->setattr(mod, "platform", VAR(PK_SYS_PLATFORM));
|
||||||
|
|
||||||
@ -1355,12 +1304,14 @@ 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(vm, CAST(Str&, args[0]));
|
Str& s = CAST(Str&, args[0]);
|
||||||
|
vm->_stdout(vm, s.data, s.size);
|
||||||
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(vm, CAST(Str&, args[0]));
|
Str& s = CAST(Str&, args[0]);
|
||||||
|
vm->_stderr(vm, s.data, s.size);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1460,7 +1411,8 @@ void add_module_traceback(VM* vm){
|
|||||||
vm->bind_func<0>(mod, "print_exc", [](VM* vm, ArgsView args) {
|
vm->bind_func<0>(mod, "print_exc", [](VM* vm, ArgsView args) {
|
||||||
if(vm->_last_exception==nullptr) vm->ValueError("no exception");
|
if(vm->_last_exception==nullptr) vm->ValueError("no exception");
|
||||||
Exception& e = CAST(Exception&, vm->_last_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;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1486,7 +1438,8 @@ void add_module_dis(VM* vm){
|
|||||||
|
|
||||||
vm->bind_func<1>(mod, "dis", [](VM* vm, ArgsView args) {
|
vm->bind_func<1>(mod, "dis", [](VM* vm, ArgsView args) {
|
||||||
CodeObject_ code = get_code(vm, args[0]);
|
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;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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){
|
void* pkpy_new_repl(pkpy_vm* vm_handle){
|
||||||
return new REPL((VM*)vm_handle);
|
return new REPL((VM*)vm_handle);
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
REPL::REPL(VM* vm) : vm(vm){
|
REPL::REPL(VM* vm) : vm(vm){
|
||||||
vm->_stdout(vm, "pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") ");
|
vm->stdout_write("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") ");
|
||||||
vm->_stdout(vm, fmt("[", sizeof(void*)*8, " bit] on ", PK_SYS_PLATFORM "\n"));
|
vm->stdout_write(fmt("[", sizeof(void*)*8, " bit] on ", PK_SYS_PLATFORM "\n"));
|
||||||
vm->_stdout(vm, "https://github.com/blueloveTH/pocketpy" "\n");
|
vm->stdout_write("https://github.com/blueloveTH/pocketpy" "\n");
|
||||||
vm->_stdout(vm, "Type \"exit()\" to exit." "\n");
|
vm->stdout_write("Type \"exit()\" to exit." "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool REPL::input(std::string line){
|
bool REPL::input(std::string line){
|
||||||
|
15
src/vm.cpp
15
src/vm.cpp
@ -5,13 +5,13 @@ namespace pkpy{
|
|||||||
VM::VM(bool enable_os) : heap(this), enable_os(enable_os) {
|
VM::VM(bool enable_os) : heap(this), enable_os(enable_os) {
|
||||||
this->vm = this;
|
this->vm = this;
|
||||||
this->_c.error = nullptr;
|
this->_c.error = nullptr;
|
||||||
_stdout = [](VM* vm, const Str& s) {
|
_stdout = [](VM* vm, const char* buf, int size) {
|
||||||
PK_UNUSED(vm);
|
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);
|
PK_UNUSED(vm);
|
||||||
std::cerr << s;
|
std::cerr.write(buf, size);
|
||||||
};
|
};
|
||||||
callstack.reserve(8);
|
callstack.reserve(8);
|
||||||
_main = nullptr;
|
_main = nullptr;
|
||||||
@ -99,13 +99,14 @@ namespace pkpy{
|
|||||||
#endif
|
#endif
|
||||||
return _exec(code, _module);
|
return _exec(code, _module);
|
||||||
}catch (const Exception& e){
|
}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
|
#if !PK_DEBUG_FULL_EXCEPTION
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
Str msg = "An std::exception occurred! It could be a bug.\n";
|
Str msg = "An std::exception occurred! It could be a bug.\n";
|
||||||
msg = msg + e.what();
|
msg = msg + e.what() + "\n";
|
||||||
_stderr(this, msg + "\n");
|
_stderr(this, msg.data, msg.size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
callstack.clear();
|
callstack.clear();
|
||||||
|
@ -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* pkpy_new_repl(pkpy_vm* vm) {
|
||||||
void* returnValue;
|
void* returnValue;
|
||||||
return returnValue;
|
return returnValue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user