diff --git a/include/pocketpy/interpreter/frame.h b/include/pocketpy/interpreter/frame.h index 118bf363..ce06e2c5 100644 --- a/include/pocketpy/interpreter/frame.h +++ b/include/pocketpy/interpreter/frame.h @@ -37,7 +37,7 @@ typedef struct Frame { struct Frame* f_back; // TODO: set this const Bytecode* ip; const CodeObject* co; - PyObject* module_; + PyObject* module; PyObject* function; // a function object or NULL (global scope) PyVar* p0; // unwinding base PyVar* locals; // locals base @@ -46,7 +46,7 @@ typedef struct Frame { } Frame; -Frame* Frame__new(Frame* f_back, const CodeObject* co, PyObject* module_, PyObject* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co); +Frame* Frame__new(const CodeObject* co, PyObject* module, PyObject* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co); void Frame__delete(Frame* self); PK_INLINE int Frame__ip(const Frame* self){ @@ -64,11 +64,11 @@ PK_INLINE int Frame__iblock(const Frame* self){ } PK_INLINE pk_NameDict* Frame__f_globals(Frame* self){ - return self->module_->dict; + return self->module->dict; } PK_INLINE PyVar* Frame__f_globals_try_get(Frame* self, StrName name){ - return pk_NameDict__try_get(self->module_->dict, name); + return pk_NameDict__try_get(self->module->dict, name); } PyVar* Frame__f_closure_try_get(Frame* self, StrName name); diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index 6ae7eb2b..903d5347 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -58,8 +58,11 @@ typedef struct pk_VM { // singleton objects PyVar True, False, None, NotImplemented, Ellipsis; + // last error + py_Error* last_error; + // last retval + PyVar last_retval; - PyObject* __last_exception; PyObject* __curr_class; PyObject* __cached_object_new; FuncDecl_ __dynamic_func_decl; @@ -74,6 +77,18 @@ typedef struct pk_VM { void pk_VM__ctor(pk_VM* self); void pk_VM__dtor(pk_VM* self); +void pk_VM__push_frame(pk_VM* self, Frame* frame); +void pk_VM__pop_frame(pk_VM* self); + +typedef enum pk_FrameResult{ + RES_ERROR, + RES_CALL, + RES_YIELD, + RES_RETURN +} pk_FrameResult; + +pk_FrameResult pk_VM__run_top_frame(pk_VM* self); + Type pk_VM__new_type(pk_VM* self, const char* name, Type base, PyObject* module, bool subclass_enabled); PyObject* pk_VM__new_module(pk_VM* self, const char* name, const char* package); diff --git a/include/pocketpy/objects/object.h b/include/pocketpy/objects/object.h index 10cd94d0..a906df06 100644 --- a/include/pocketpy/objects/object.h +++ b/include/pocketpy/objects/object.h @@ -22,7 +22,7 @@ static_assert(sizeof(PyObject) <= 16, "!(sizeof(PyObject) <= 16)"); #define PK_OBJ_SIZEOF(T) (sizeof(T) + 16) PyObject* PyObject__new(Type type, int size); -void PyObject__delete(PyObject* self); +void PyObject__delete(pk_VM* vm, PyObject* self); PK_INLINE PyVar PyVar__fromobj(PyObject* obj){ PyVar retval = { diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 1d2b451f..4531bb89 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -12,7 +12,7 @@ typedef struct py_Error py_Error; typedef int (*py_CFunction)(const PyVar*, int); -extern pk_VM* pk_vm; +extern pk_VM* pk_current_vm; void py_initialize(); // void py_switch_vm(const char* name); diff --git a/src/interpreter/frame.c b/src/interpreter/frame.c index 28714691..3521b97c 100644 --- a/src/interpreter/frame.c +++ b/src/interpreter/frame.c @@ -39,13 +39,13 @@ void UnwindTarget__delete(UnwindTarget* self){ free(self); } -Frame* Frame__new(Frame* f_back, const CodeObject* co, PyObject* module_, PyObject* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co){ +Frame* Frame__new(const CodeObject* co, PyObject* module, PyObject* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co){ static_assert(sizeof(Frame) <= kPoolFrameBlockSize, "!(sizeof(Frame) <= kPoolFrameBlockSize)"); Frame* self = PoolFrame_alloc(); - self->f_back = f_back; + self->f_back = NULL; self->ip = (Bytecode*)co->codes.data - 1; self->co = co; - self->module_ = module_; + self->module = module; self->function = function; self->p0 = p0; self->locals = locals; diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 6609cbba..b0089607 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -154,6 +154,22 @@ void pk_VM__dtor(pk_VM* self){ ValueStack__clear(&self->stack); } +void pk_VM__push_frame(pk_VM* self, Frame* frame){ + frame->f_back = self->top_frame; + self->top_frame = frame; +} + +void pk_VM__pop_frame(pk_VM* self){ + assert(self->top_frame); + Frame* frame = self->top_frame; + self->top_frame = frame->f_back; + Frame__delete(frame); +} + +pk_FrameResult pk_VM__run_top_frame(pk_VM* self){ + return RES_RETURN; +} + Type pk_VM__new_type(pk_VM* self, const char* name, Type base, PyObject* module, bool subclass_enabled){ Type type = self->types.count; pk_TypeInfo* ti = c11_vector__emplace(&self->types); @@ -165,7 +181,7 @@ Type pk_VM__new_type(pk_VM* self, const char* name, Type base, PyObject* module, /****************************************/ void PyObject__delete(PyObject *self){ - pk_TypeInfo* ti = c11__getitem(pk_TypeInfo*, &pk_vm->types, self->type); + pk_TypeInfo* ti = c11__getitem(pk_TypeInfo*, &pk_current_vm->types, self->type); if(ti->dtor) ti->dtor(PyObject__value_ptr(self)); if(self->dict) pk_NameDict__delete(self->dict); if(self->gc_is_large){ diff --git a/src/pocketpy.c b/src/pocketpy.c index f87bef30..afe4c94c 100644 --- a/src/pocketpy.c +++ b/src/pocketpy.c @@ -1,20 +1,40 @@ #include "pocketpy/pocketpy.h" #include "pocketpy/objects/object.h" #include "pocketpy/interpreter/vm.h" +#include +#include -pk_VM* pk_vm; +pk_VM* pk_current_vm; static pk_VM pk_default_vm; void py_initialize(){ Pools_initialize(); pk_StrName__initialize(); - pk_vm = &pk_default_vm; + pk_current_vm = &pk_default_vm; pk_VM__ctor(&pk_default_vm); } +py_Error* py_exec_simple(const char* source){ + CodeObject* co = NULL; + pk_VM* vm = pk_current_vm; + Frame* frame = Frame__new( + co, + vm->main, + NULL, + vm->stack.sp, + vm->stack.sp, + co + ); + pk_VM__push_frame(vm, frame); + pk_FrameResult res = pk_VM__run_top_frame(vm); + if(res == RES_ERROR) return vm->last_error; + if(res == RES_RETURN) return NULL; // vm->last_retval; + assert(0); // unreachable +} + void py_finalize(){ pk_VM__dtor(&pk_default_vm); - pk_vm = NULL; + pk_current_vm = NULL; pk_StrName__finalize(); Pools_finalize(); }