blueloveTH 1 год назад
Родитель
Сommit
5bdbec273e

+ 0 - 1
include/pocketpy/interpreter/vm.h

@@ -64,7 +64,6 @@ typedef struct pk_VM {
     PyVar last_retval;
     // registers
     PyVar reg[8];
-    PyVar sysreg[8];
 
     PyObject* __curr_class;
     PyObject* __cached_object_new;

+ 44 - 50
include/pocketpy/pocketpy.h

@@ -1,12 +1,9 @@
 #pragma once
 
-#include "stdint.h"
-#include "stdbool.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <stdint.h>
+#include <stdbool.h>
 
+/************* Public Types *************/
 typedef struct PyObject PyObject;
 typedef struct PyVar PyVar;
 typedef struct pk_VM pk_VM;
@@ -27,38 +24,28 @@ typedef enum BindType {
     BindType_CLASSMETHOD,
 } BindType;
 
-
-
 extern pk_VM* pk_current_vm;
 
-
+/************* Global VMs *************/
 void py_initialize();
-// void py_switch_vm(const char* name);
 void py_finalize();
 
-int py_exec_simple(const char*);
-int py_eval_simple(const char*, py_Ref);
-
-/* py_error */
-py_Error* py_getlasterror();
-void py_Error__print(py_Error*);
-
-int py_eq(const py_Ref, const py_Ref);
-int py_le(const py_Ref, const py_Ref);
-int py_hash(const py_Ref, int64_t* out);
+int py_exec(const char*);
+int py_eval(const char*);
 
-/* py_var */
+/************* Values Creation *************/
 void py_newint(py_Ref, int64_t);
 void py_newfloat(py_Ref, double);
 void py_newbool(py_Ref, bool);
 void py_newstr(py_Ref, const char*);
 void py_newstrn(py_Ref, const char*, int);
 // void py_newfstr(py_Ref, const char*, ...);
-void py_newbytes(py_Ref, const uint8_t*, int);
+// void py_newbytes(py_Ref, const uint8_t*, int);
 void py_newnone(py_Ref);
 void py_newnull(py_Ref);
 
 void py_newtuple(py_Ref, int);
+// void py_newlist(py_Ref);
 
 // new style decl-based function
 void py_newfunction(py_Ref, py_CFunction, const char* sig, BindType bt);
@@ -67,48 +54,55 @@ void py_newfunction2(py_Ref, py_CFunction, const char* sig, BindType bt, const c
 void py_newnativefunc(py_Ref, py_CFunction, int argc, BindType bt);
 void py_newnativefunc2(py_Ref, py_CFunction, int argc, BindType bt, const char* docstring, const py_Ref userdata);
 
-
-py_Ref py_newmodule(const char* name, const char* package);
-py_Ref py_getmodule(const char* name);
-const py_Ref py_import(const char* name);
-
-#define py_isnull(self) ((self)->type == 0)
-
-
-/// Sets the name of the object to the given value.
-void py_setdict(py_Ref self, py_Name name, const py_Ref val);
-/// Returns a reference to the name of the object.
+/************* References *************/
 py_Ref py_getdict(const py_Ref self, py_Name name);
+void py_setdict(py_Ref self, py_Name name, const py_Ref val);
 
-/// Sets the i-th slot of the object to the given value.
-void py_setslot(py_Ref self, int i, const py_Ref val);
-/// Returns a reference to the i-th slot of the object.
 py_Ref py_getslot(const py_Ref self, int i);
+void py_setslot(py_Ref self, int i, const py_Ref val);
 
-/// Equivalent to `self.name = val`.
-/// Returns 0 | err
-int py_setattr(py_Ref self, py_Name name, const py_Ref val);
+// int py_getattr(const py_Ref self, py_Name name, py_Ref out);
+// int py_setattr(py_Ref self, py_Name name, const py_Ref val);
 
-/// Equivalent to `self.name`.
-/// Returns 0 | err
-int py_getattr(const py_Ref self, py_Name name, py_Ref out);
+/// Copies src to dst.
+void py_copyref(const py_Ref src, py_Ref dst);
 
+/************* Stack Operations *************/
+py_Ref py_gettop();
+void py_settop(const py_Ref);
+py_Ref py_getsecond();
+void py_setsecond(const py_Ref);
 /// Returns a reference to the i-th object from the top of the stack.
 /// i should be negative, e.g. (-1) means TOS.
-py_Ref py_stack(int i);
-/// Returns a reference to the i-th register.
-py_Ref py_reg(int i);
-/// Returns a reference to the i-th system register.
-py_Ref py_sysreg(int i);
+py_Ref py_peek(int i);
 /// Prepares a push and returns an uninitialized reference.
 py_Ref py_push();
-
+/// Pops an object from the stack.
+void py_pop();
+void py_shrink(int n);
 
 /// Pushes the object to the stack.
 void py_pushref(const py_Ref src);
-/// Pops the object from the stack.
-void py_copyref(const py_Ref src, py_Ref dst);
 
+/// Get a temporary variable from the stack and returns the reference to it.
+py_Ref py_pushtmp();
+/// Free n temporary variable.
+void py_poptmp(int n);
+
+/************* Modules *************/
+py_Ref py_newmodule(const char* name, const char* package);
+py_Ref py_getmodule(const char* name);
+void py_import(const char* name, py_Ref out);
+
+/************* Errors *************/
+py_Error* py_getlasterror();
+void py_Error__print(py_Error*);
+
+int py_eq(const py_Ref, const py_Ref);
+int py_le(const py_Ref, const py_Ref);
+int py_hash(const py_Ref, int64_t* out);
+
+#define py_isnull(self) ((self)->type == 0)
 
 /* tuple */
 

+ 5 - 5
src/interpreter/vm.c

@@ -106,19 +106,19 @@ void pk_VM__ctor(pk_VM* self){
     ValueStack__ctor(&self->stack);
 
     self->True = (PyVar){.type=tp_bool, .is_ptr=true, .extra=1,
-        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 1),
+        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 0),
     };
     self->False = (PyVar){.type=tp_bool, .is_ptr=true, .extra=0,
-        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 1),
+        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 0),
     };
     self->None = (PyVar){.type=tp_none_type, .is_ptr=true,
-        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_none_type, 0, 1),
+        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_none_type, 0, 0),
     };
     self->NotImplemented = (PyVar){.type=tp_not_implemented_type, .is_ptr=true,
-        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_not_implemented_type, 0, 1),
+        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_not_implemented_type, 0, 0),
     };
     self->Ellipsis = (PyVar){.type=tp_ellipsis, .is_ptr=true,
-        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_ellipsis, 0, 1),
+        ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_ellipsis, 0, 0),
     };
 
     /* Init Builtin Types */

+ 0 - 122
src/pocketpy.c

@@ -5,135 +5,13 @@
 #include <assert.h>
 #include <stdlib.h>
 
-pk_VM* pk_current_vm;
-static pk_VM pk_default_vm;
 
-void py_initialize(){
-    Pools_initialize();
-    pk_StrName__initialize();
-    pk_current_vm = &pk_default_vm;
-    pk_VM__ctor(&pk_default_vm);
-}
 
-int 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->type;
-    if(res == RES_RETURN) return 0; // vm->last_retval;
-    assert(0);  // unreachable
-}
 
-py_Ref py_getmodule(const char *name){
-    pk_VM* vm = pk_current_vm;
-    return pk_NameDict__try_get(&vm->modules, py_name(name));
-}
 
-py_Ref py_newmodule(const char *name, const char *package){
-    pk_ManagedHeap* heap = &pk_current_vm->heap;
-    PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_module, -1, 0);
 
-    py_Ref r0 = py_sysreg(0);
-    py_Ref r1 = py_sysreg(1);
 
-    *r0 = PyVar__fromobj(obj);
 
-    py_newstr(r1, name);
-    py_setdict(r0, __name__, r1);
 
-    package = package ? package : "";
 
-    py_newstr(r1, package);
-    py_setdict(r0, __package__, r1);
 
-    // convert to fullname
-    if(package[0] != '\0'){
-        // package.name
-        char buf[256];
-        snprintf(buf, sizeof(buf), "%s.%s", package, name);
-        name = buf;
-    }
-
-    py_newstr(r1, name);
-    py_setdict(r0, __path__, r1);
-
-    // we do not allow override in order to avoid memory leak
-    // it is because Module objects are not garbage collected
-    bool exists = pk_NameDict__contains(&pk_current_vm->modules, py_name(name));
-    if(exists) abort();
-    pk_NameDict__set(&pk_current_vm->modules, py_name(name), *r0);
-    return py_getmodule(name);
-}
-
-py_Error* py_getlasterror(){
-    return pk_current_vm->last_error;
-}
-
-void py_Error__print(py_Error* self){
-    abort();
-}
-
-py_Ref py_reg(int i){
-    assert(i >= 0 && i < 8);
-    return &pk_current_vm->reg[i];
-}
-
-py_Ref py_sysreg(int i){
-    assert(i >= 0 && i < 8);
-    return &pk_current_vm->sysreg[i];
-}
-
-py_Ref py_stack(int i){
-    assert(i < 0);
-    return &pk_current_vm->stack.sp[i];
-}
-
-void py_finalize(){
-    pk_VM__dtor(&pk_default_vm);
-    pk_current_vm = NULL;
-    pk_StrName__finalize();
-    Pools_finalize();
-}
-
-void py_setdict(py_Ref self, py_Name name, const py_Ref val){
-    pk_NameDict__set(
-        PyObject__dict(self->_obj),
-        name,
-        *val
-    );
-}
-
-void py_newint(py_Ref self, int64_t val){
-    self->type = tp_int;
-    self->is_ptr = false;
-    self->_i64 = val;
-}
-
-void py_newfloat(py_Ref self, double val){
-    self->type = tp_float;
-    self->is_ptr = false;
-    self->_f64 = val;
-}
-
-void py_newbool(py_Ref self, bool val){
-    pk_VM* vm = pk_current_vm;
-    *self = val ? vm->True : vm->False;
-}
-
-void py_newstr(py_Ref self, const char* val){
-    pk_VM* vm = pk_current_vm;
-    PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_str, 0, sizeof(py_Str));
-    py_Str__ctor((py_Str*)PyObject__value(obj), val);
-    self->type = tp_str;
-    self->is_ptr = true;
-    self->_obj = obj;
-}

+ 15 - 0
src/public/error.c

@@ -0,0 +1,15 @@
+#include "pocketpy/pocketpy.h"
+
+#include "pocketpy/common/utils.h"
+#include "pocketpy/objects/object.h"
+#include "pocketpy/interpreter/vm.h"
+
+
+py_Error* py_getlasterror(){
+    return pk_current_vm->last_error;
+}
+
+void py_Error__print(py_Error* self){
+    abort();
+}
+

+ 48 - 0
src/public/modules.c

@@ -0,0 +1,48 @@
+#include "pocketpy/pocketpy.h"
+
+#include "pocketpy/common/utils.h"
+#include "pocketpy/objects/object.h"
+#include "pocketpy/interpreter/vm.h"
+
+py_Ref py_getmodule(const char *name){
+    pk_VM* vm = pk_current_vm;
+    return pk_NameDict__try_get(&vm->modules, py_name(name));
+}
+
+py_Ref py_newmodule(const char *name, const char *package){
+    pk_ManagedHeap* heap = &pk_current_vm->heap;
+    PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_module, -1, 0);
+
+    py_Ref r0 = py_pushtmp();
+    py_Ref r1 = py_pushtmp();
+
+    *r0 = PyVar__fromobj(obj);
+
+    py_newstr(r1, name);
+    py_setdict(r0, __name__, r1);
+
+    package = package ? package : "";
+
+    py_newstr(r1, package);
+    py_setdict(r0, __package__, r1);
+
+    // convert to fullname
+    if(package[0] != '\0'){
+        // package.name
+        char buf[256];
+        snprintf(buf, sizeof(buf), "%s.%s", package, name);
+        name = buf;
+    }
+
+    py_newstr(r1, name);
+    py_setdict(r0, __path__, r1);
+
+    // we do not allow override in order to avoid memory leak
+    // it is because Module objects are not garbage collected
+    bool exists = pk_NameDict__contains(&pk_current_vm->modules, py_name(name));
+    if(exists) abort();
+    pk_NameDict__set(&pk_current_vm->modules, py_name(name), *r0);
+
+    py_poptmp(2);
+    return py_getmodule(name);
+}

+ 84 - 0
src/public/stackops.c

@@ -0,0 +1,84 @@
+#include "pocketpy/pocketpy.h"
+
+#include "pocketpy/common/utils.h"
+#include "pocketpy/objects/object.h"
+#include "pocketpy/interpreter/vm.h"
+
+py_Ref py_getdict(const py_Ref self, py_Name name){
+    assert(self && self->is_ptr);
+    return pk_NameDict__try_get(PyObject__dict(self->_obj), name);
+}
+
+void py_setdict(py_Ref self, py_Name name, const py_Ref val){
+    assert(self && self->is_ptr);
+    pk_NameDict__set(PyObject__dict(self->_obj), name, *val);
+}
+
+py_Ref py_getslot(const py_Ref self, int i){
+    assert(self && self->is_ptr);
+    assert(i >= 0 && i < self->_obj->slots);
+    return PyObject__slots(self->_obj) + i;
+}
+
+void py_setslot(py_Ref self, int i, const py_Ref val){
+    assert(self && self->is_ptr);
+    assert(i >= 0 && i < self->_obj->slots);
+    PyObject__slots(self->_obj)[i] = *val;
+}
+
+void py_copyref(const py_Ref src, py_Ref dst){
+    *dst = *src;
+}
+
+/* Stack References */
+py_Ref py_gettop(){
+    return pk_current_vm->stack.sp - 1;
+}
+
+void py_settop(const py_Ref val){
+    pk_current_vm->stack.sp[-1] = *val;
+}
+
+py_Ref py_getsecond(){
+    return pk_current_vm->stack.sp - 2;
+}
+
+void py_setsecond(const py_Ref val){
+    pk_current_vm->stack.sp[-2] = *val;
+}
+
+py_Ref py_peek(int i){
+    assert(i < 0);
+    return pk_current_vm->stack.sp + i;
+}
+
+py_Ref py_push(){
+    pk_VM* vm = pk_current_vm;
+    py_Ref top = vm->stack.sp;
+    vm->stack.sp++;
+    return top;
+}
+
+void py_pop(){
+    pk_VM* vm = pk_current_vm;
+    vm->stack.sp--;
+}
+
+void py_shrink(int n){
+    pk_VM* vm = pk_current_vm;
+    vm->stack.sp -= n;
+}
+
+void py_pushref(const py_Ref src){
+    *py_push() = *src;
+}
+
+py_Ref py_pushtmp(){
+    py_Ref r = py_push();
+    py_newnull(r);
+    return r;
+}
+
+void py_poptmp(int n){
+    py_shrink(n);
+}

+ 73 - 0
src/public/values.c

@@ -0,0 +1,73 @@
+#include "pocketpy/pocketpy.h"
+
+#include "pocketpy/common/utils.h"
+#include "pocketpy/objects/object.h"
+#include "pocketpy/interpreter/vm.h"
+
+void py_newint(py_Ref self, int64_t val){
+    self->type = tp_int;
+    self->is_ptr = false;
+    self->_i64 = val;
+}
+
+void py_newfloat(py_Ref self, double val){
+    self->type = tp_float;
+    self->is_ptr = false;
+    self->_f64 = val;
+}
+
+void py_newbool(py_Ref self, bool val){
+    pk_VM* vm = pk_current_vm;
+    *self = val ? vm->True : vm->False;
+}
+
+void py_newstr(py_Ref self, const char* data){
+    pk_ManagedHeap* heap = &pk_current_vm->heap;
+    PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str));
+    py_Str__ctor((py_Str*)PyObject__value(obj), data);
+    self->type = tp_str;
+    self->is_ptr = true;
+    self->_obj = obj;
+}
+
+void py_newstrn(py_Ref self, const char* data, int size){
+    pk_ManagedHeap* heap = &pk_current_vm->heap;
+    PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str));
+    py_Str__ctor2((py_Str*)PyObject__value(obj), data, size);
+    self->type = tp_str;
+    self->is_ptr = true;
+    self->_obj = obj;
+}
+
+void py_newnone(py_Ref self){
+    pk_VM* vm = pk_current_vm;
+    *self = vm->None;
+}
+
+void py_newnull(py_Ref self){
+    self->type = 0;
+}
+
+void py_newtuple(py_Ref self, int n){
+    pk_VM* vm = pk_current_vm;
+    PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_tuple, n, 0);
+    self->type = tp_tuple;
+    self->is_ptr = true;
+    self->_obj = obj;
+}
+
+void py_newfunction(py_Ref self, py_CFunction f, const char* sig, BindType bt){
+    py_newfunction2(self, f, sig, bt, NULL, NULL);
+}
+
+void py_newfunction2(py_Ref self, py_CFunction f, const char *sig, BindType bt, const char *docstring, const py_Ref userdata){
+
+}
+
+void py_newnativefunc(py_Ref self, py_CFunction f, int argc, BindType bt){
+    py_newnativefunc2(self, f, argc, bt, NULL, NULL);
+}
+
+void py_newnativefunc2(py_Ref self, py_CFunction f, int argc, BindType bt, const char *docstring, const py_Ref userdata){
+
+}

+ 40 - 0
src/public/vm.c

@@ -0,0 +1,40 @@
+#include "pocketpy/pocketpy.h"
+
+#include "pocketpy/common/utils.h"
+#include "pocketpy/objects/object.h"
+#include "pocketpy/interpreter/vm.h"
+
+pk_VM* pk_current_vm;
+static pk_VM pk_default_vm;
+
+void py_initialize(){
+    Pools_initialize();
+    pk_StrName__initialize();
+    pk_current_vm = &pk_default_vm;
+    pk_VM__ctor(&pk_default_vm);
+}
+
+void py_finalize(){
+    pk_VM__dtor(&pk_default_vm);
+    pk_current_vm = NULL;
+    pk_StrName__finalize();
+    Pools_finalize();
+}
+
+int py_exec(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->type;
+    if(res == RES_RETURN) return 0; // vm->last_retval;
+    assert(0);  // unreachable
+}

+ 2 - 2
src2/main.c

@@ -1,7 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
+
 #include "pocketpy.h"
-#include "pocketpy/pocketpy.h"
 
 char* read_file(const char* path) {
     FILE* file = fopen(path, "r");
@@ -28,7 +28,7 @@ int main(int argc, char** argv) {
     char* source = read_file(argv[1]);
     py_initialize();
 
-    if(py_exec_simple(source)){
+    if(py_exec(source)){
         py_Error* err = py_getlasterror();
         py_Error__print(err);
     }