blueloveTH 1 gadu atpakaļ
vecāks
revīzija
0871b627ed
4 mainītis faili ar 177 papildinājumiem un 70 dzēšanām
  1. 1 0
      include/pocketpy/interpreter/vm.h
  2. 56 23
      include/pocketpy/pocketpy.h
  3. 44 47
      src/interpreter/vm.c
  4. 76 0
      src/pocketpy.c

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

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

+ 56 - 23
include/pocketpy/pocketpy.h

@@ -48,27 +48,28 @@ int py_le(const py_Ref, const py_Ref);
 int py_hash(const py_Ref, int64_t* out);
 
 /* py_var */
-void py_new_int(py_Ref, int64_t);
-void py_new_float(py_Ref, double);
-void py_new_bool(py_Ref, bool);
-void py_new_str(py_Ref, const char*);
-void py_new_strn(py_Ref, const char*, int);
-void py_new_fstr(py_Ref, const char*, ...);
-void py_new_bytes(py_Ref, const uint8_t*, int);
-void py_new_none(py_Ref);
-void py_new_null(py_Ref);
-
-void py_new_tuple(PyVar, int);
+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_newnone(py_Ref);
+void py_newnull(py_Ref);
+
+void py_newtuple(py_Ref, int);
 
 // new style decl-based function
-void py_new_function(py_Ref, py_CFunction, const char* sig, BindType bt);
-void py_new_function2(py_Ref, py_CFunction, const char* sig, BindType bt, const char* docstring, const py_Ref userdata);
+void py_newfunction(py_Ref, py_CFunction, const char* sig, BindType bt);
+void py_newfunction2(py_Ref, py_CFunction, const char* sig, BindType bt, const char* docstring, const py_Ref userdata);
 // old style argc-based function
-void py_new_nativefunc(py_Ref, py_CFunction, int argc, BindType bt);
-void py_new_nativefunc2(py_Ref, py_CFunction, int argc, BindType bt, const char* docstring, const py_Ref userdata);
+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_new_module(const char* name);
+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)
@@ -84,19 +85,25 @@ 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);
 
-/// Sets the attribute of the object to the given value.
-/// This is equivalent to `self.name = val`.
+/// Equivalent to `self.name = val`.
 /// Returns 0 | err
 int py_setattr(py_Ref self, py_Name name, const py_Ref val);
 
-/// Gets the attribute of the object.
-/// This is equivalent to `self.name`.
+/// Equivalent to `self.name`.
 /// Returns 0 | err
 int py_getattr(const py_Ref self, py_Name name, py_Ref out);
 
-/// Returns a reference to the i-th object in the stack.
-/// For example, `py_stackref(-1)` refers to the top of the stack.
-py_Ref py_stackref(int i);
+/// 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);
+/// Prepares a push and returns an uninitialized reference.
+py_Ref py_push();
+
+
 /// Pushes the object to the stack.
 void py_pushref(const py_Ref src);
 /// Pops the object from the stack.
@@ -109,13 +116,39 @@ void py_copyref(const py_Ref src, py_Ref dst);
 py_Ref py_tuple__getitem(const py_Ref self, int i);
 void py_tuple__setitem(py_Ref self, int i, const py_Ref val);
 int py_tuple__len(const py_Ref self);
+bool py_tuple__contains(const py_Ref self, const py_Ref val);
+
+// unchecked functions, if self is not a list, the behavior is undefined
+py_Ref py_list__getitem(const py_Ref self, int i);
+void py_list__setitem(py_Ref self, int i, const py_Ref val);
+void py_list__delitem(py_Ref self, int i);
+int py_list__len(const py_Ref self);
+bool py_list__contains(const py_Ref self, const py_Ref val);
+void py_list__append(py_Ref self, const py_Ref val);
+void py_list__extend(py_Ref self, const py_Ref begin, const py_Ref end);
+void py_list__clear(py_Ref self);
+void py_list__insert(py_Ref self, int i, const py_Ref val);
+
+// unchecked functions, if self is not a dict, the behavior is undefined
+int py_dict__len(const py_Ref self);
+bool py_dict__contains(const py_Ref self, const py_Ref key);
+py_Ref py_dict__getitem(const py_Ref self, const py_Ref key);
+void py_dict__setitem(py_Ref self, const py_Ref key, const py_Ref val);
+void py_dict__delitem(py_Ref self, const py_Ref key);
+void py_dict__clear(py_Ref self);
 
 int py_str(const py_Ref, py_Str* out);
 int py_repr(const py_Ref, py_Str* out);
 
+int py_toint(py_Ref, int64_t* out);
+int py_tofloat(py_Ref, double* out);
 int py_tostr(py_Ref, py_Str** out);
 int py_tobool(py_Ref, bool* out);
 
+bool py_istype(const py_Ref, Type);
+bool py_isinstance(const py_Ref obj, Type type);
+bool py_issubclass(Type derived, Type base);
+
 #ifdef __cplusplus
 }
 #endif

+ 44 - 47
src/interpreter/vm.c

@@ -34,53 +34,50 @@ void pk_TypeInfo__dtor(pk_TypeInfo *self){
     c11_vector__dtor(&self->annotated_fields);
 }
 
-static int _hello(const py_Ref args, int argc){
-    return 0;
-}
-
-// print(*args, sep=' ', end='\n')
-static int _py_print(const py_Ref args, int argc){
-    int length = py_tuple__len(args+0);
-    py_Str* sep;
-    py_Str* end;
-
-    int err;
-    err = py_tostr(args+1, &sep);
-    if(err) return err;
-    err = py_tostr(args+2, &end);
-    if(err) return err;
-
-    pk_SStream ss;
-    pk_SStream__ctor(&ss);
-
-    for(int i=0; i<length; i++){
-        const py_Ref item = py_tuple__getitem(args+0, i);
-        py_Str tmp;
-        int err = py_str(item, &tmp);
-        if(!err){
-            pk_SStream__write_Str(&ss, &tmp);
-            py_Str__dtor(&tmp);
-            if(i != length-1){
-                pk_SStream__write_Str(&ss, sep);
-            }
-        }else{
-            py_Str__dtor(&tmp);
-            pk_SStream__dtor(&ss);
-            return err;
-        }
-    }
-    pk_SStream__write_Str(&ss, end);
-    py_Str out = pk_SStream__submit(&ss);
-    pk_current_vm->_stdout(py_Str__data(&out));
-    py_Str__dtor(&out);
-    return 0;
-}
+// static int _py_print(const py_Ref args, int argc){
+//     int length = py_tuple__len(args+0);
+//     py_Str* sep;
+//     py_Str* end;
+
+//     int err;
+//     err = py_tostr(args+1, &sep);
+//     if(err) return err;
+//     err = py_tostr(args+2, &end);
+//     if(err) return err;
+
+//     pk_SStream ss;
+//     pk_SStream__ctor(&ss);
+
+//     for(int i=0; i<length; i++){
+//         const py_Ref item = py_tuple__getitem(args+0, i);
+//         py_Str tmp;
+//         int err = py_str(item, &tmp);
+//         if(!err){
+//             pk_SStream__write_Str(&ss, &tmp);
+//             py_Str__dtor(&tmp);
+//             if(i != length-1){
+//                 pk_SStream__write_Str(&ss, sep);
+//             }
+//         }else{
+//             py_Str__dtor(&tmp);
+//             pk_SStream__dtor(&ss);
+//             return err;
+//         }
+//     }
+//     pk_SStream__write_Str(&ss, end);
+//     py_Str out = pk_SStream__submit(&ss);
+//     pk_current_vm->_stdout(py_Str__data(&out));
+//     py_Str__dtor(&out);
+//     return 0;
+// }
 
 static void do_builtin_bindings(){
-    pk_VM* vm = pk_current_vm;
-
-    py_new_nativefunc(&vm->reg[0], _hello, 2, BindType_FUNCTION);
-    py_setdict(&vm->builtins, py_name("hello"), &vm->reg[0]);
+    // py_Ref builtins = py_getmodule("builtins");
+    // py_newfunction(py_reg(0), _py_print,
+    //     "print(*args, sep=' ', end='\\n')",
+    //     BindType_FUNCTION
+    // );
+    // py_setdict(builtins, py_name("hello"), py_reg(0));
 }
 
 void pk_VM__ctor(pk_VM* self){
@@ -172,7 +169,7 @@ void pk_VM__ctor(pk_VM* self){
     #undef validate
 
     self->StopIteration = c11__at(pk_TypeInfo, &self->types, tp_stop_iteration)->self;
-    self->builtins = *py_new_module("builtins");
+    self->builtins = *py_newmodule("builtins", NULL);
     
     /* Setup Public Builtin Types */
     Type public_types[] = {
@@ -193,7 +190,7 @@ void pk_VM__ctor(pk_VM* self){
 
     /* Do Buildin Bindings*/
     do_builtin_bindings();
-    self->main = *py_new_module("__main__");
+    self->main = *py_newmodule("__main__", NULL);
 }
 
 void pk_VM__dtor(pk_VM* self){

+ 76 - 0
src/pocketpy.c

@@ -1,4 +1,5 @@
 #include "pocketpy/pocketpy.h"
+#include "pocketpy/common/utils.h"
 #include "pocketpy/objects/object.h"
 #include "pocketpy/interpreter/vm.h"
 #include <assert.h>
@@ -32,6 +33,47 @@ int py_exec_simple(const char* source){
     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;
 }
@@ -40,6 +82,21 @@ 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;
@@ -61,3 +118,22 @@ void py_newint(py_Ref self, int64_t val){
     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;
+}