diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index a9bb2b8c..8fc4257b 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -41,9 +41,7 @@ typedef struct VM { py_TValue builtins; // builtins module py_TValue main; // __main__ module - void (*ceval_on_step)(Frame*, Bytecode); - char* (*import_file)(const char*); - void (*print)(const char*); + py_Callbacks callbacks; py_TValue last_retval; py_TValue curr_exception; diff --git a/include/pocketpy/objects/codeobject.h b/include/pocketpy/objects/codeobject.h index 949d0e86..220cb8cc 100644 --- a/include/pocketpy/objects/codeobject.h +++ b/include/pocketpy/objects/codeobject.h @@ -120,15 +120,6 @@ void FuncDecl__add_arg(FuncDecl* self, py_Name name); void FuncDecl__add_kwarg(FuncDecl* self, py_Name name, const py_TValue* value); void FuncDecl__add_starred_arg(FuncDecl* self, py_Name name); void FuncDecl__add_starred_kwarg(FuncDecl* self, py_Name name); -FuncDecl_ FuncDecl__build(c11_sv name, - c11_sv* args, - int argc, - c11_sv starred_arg, - c11_sv* kwargs, - int kwargc, - py_Ref kwdefaults, // a tuple contains default values - c11_sv starred_kwarg, - const char* docstring); // runtime function typedef struct Function { diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index dbcd6871..2a0a47a5 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -34,6 +34,14 @@ typedef struct c11_sv { int size; } c11_sv; +/// A struct contains the callbacks of the VM. +typedef struct py_Callbacks { + /// Used by `__import__` to load source code of a module. + char* (*importfile)(const char*); + /// Used by `print` to output a string. + void (*print)(const char*); +} py_Callbacks; + #define PY_RAISE #define PY_RETURN @@ -84,6 +92,8 @@ PK_EXPORT int py_currentvm(); PK_EXPORT void py_switchvm(int index); /// Set `sys.argv`. Used for storing command-line arguments. PK_EXPORT void py_sys_setargv(int argc, char** argv); +/// Setup the callbacks for the current VM. +PK_EXPORT py_Callbacks* py_callbacks(); /// Run a source string. /// @param source source string. diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 93c1ad87..142196db 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -120,8 +120,8 @@ FrameResult VM__run_top_frame(VM* self) { if(TOP()->type != tp_NoneType) { bool ok = py_repr(TOP()); if(!ok) goto __ERROR; - self->print(py_tostr(&self->last_retval)); - self->print("\n"); + self->callbacks.print(py_tostr(&self->last_retval)); + self->callbacks.print("\n"); } POP(); DISPATCH(); diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 06e59f89..08d4fb38 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -9,7 +9,7 @@ #include "pocketpy/pocketpy.h" #include -static char* pk_default_import_file(const char* path) { +static char* pk_default_importfile(const char* path) { #if PK_ENABLE_OS FILE* f = fopen(path, "rb"); if(f == NULL) return NULL; @@ -61,9 +61,8 @@ void VM__ctor(VM* self) { self->builtins = *py_NIL; self->main = *py_NIL; - self->ceval_on_step = NULL; - self->import_file = pk_default_import_file; - self->print = pk_default_print; + self->callbacks.importfile = pk_default_importfile; + self->callbacks.print = pk_default_print; self->last_retval = *py_NIL; self->curr_exception = *py_NIL; diff --git a/src/modules/dis.c b/src/modules/dis.c index def8b0ed..7d1c936a 100644 --- a/src/modules/dis.c +++ b/src/modules/dis.c @@ -105,8 +105,8 @@ static void disassemble(CodeObject* co) { } c11_string* output = c11_sbuf__submit(&ss); - pk_current_vm->print(output->data); - pk_current_vm->print("\n"); + pk_current_vm->callbacks.print(output->data); + pk_current_vm->callbacks.print("\n"); c11_string__delete(output); c11_vector__dtor(&jumpTargets); } diff --git a/src/public/internal.c b/src/public/internal.c index e2b9bbcd..45817dab 100644 --- a/src/public/internal.c +++ b/src/public/internal.c @@ -76,6 +76,9 @@ void py_sys_setargv(int argc, char** argv) { } } +py_Callbacks* py_getcallbacks() { return &pk_current_vm->callbacks; } + + const char* pk_opname(Opcode op) { const static char* OP_NAMES[] = { #define OPCODE(name) #name, diff --git a/src/public/modules.c b/src/public/modules.c index 5f58d4fa..d9d628f4 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -130,12 +130,12 @@ int py_import(const char* path_cstr) { goto __SUCCESS; } - data = vm->import_file(filename->data); + data = vm->callbacks.importfile(filename->data); if(data != NULL) goto __SUCCESS; c11_string__delete(filename); filename = c11_string__new3("%s/__init__.py", slashed_path->data); - data = vm->import_file(filename->data); + data = vm->callbacks.importfile(filename->data); if(data != NULL) goto __SUCCESS; c11_string__delete(filename); @@ -290,7 +290,7 @@ static bool builtins_print(int argc, py_Ref argv) { } c11_sbuf__write_sv(&buf, end); c11_string* res = c11_sbuf__submit(&buf); - pk_current_vm->print(res->data); + pk_current_vm->callbacks.print(res->data); c11_string__delete(res); py_newnone(py_retval()); return true; diff --git a/src/public/py_exception.c b/src/public/py_exception.c index 50b82c7e..f76fc4b0 100644 --- a/src/public/py_exception.c +++ b/src/public/py_exception.c @@ -160,8 +160,8 @@ void py_clearexc(py_StackRef p0) { void py_printexc() { char* msg = py_formatexc(); if(!msg) return; - pk_current_vm->print(msg); - pk_current_vm->print("\n"); + pk_current_vm->callbacks.print(msg); + pk_current_vm->callbacks.print("\n"); free(msg); }