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

+ 9 - 11
build.sh

@@ -1,9 +1,9 @@
 #!/bin/bash
 
-# Check if clang++ is installed
-if ! type -P clang++ >/dev/null 2>&1; then
-    echo "clang++ is required and not installed. Kindly install it."
-    echo "Run: sudo apt-get install libc++-dev libc++abi-dev clang"
+# Check if clang is installed
+if ! type -P clang >/dev/null 2>&1; then
+    echo "clang is required and not installed. Kindly install it."
+    echo "Run: sudo apt-get install clang"
     exit 1
 fi
 
@@ -18,13 +18,11 @@ if [ $? -ne 0 ]; then
     exit 1
 fi
 
-SRC_C=$(find src/ -name "*.c")
-SRC_CPP=$(find src/ -name "*.cpp")
-SRC="$SRC_C $SRC_CPP"
+SRC=$(find src/ -name "*.c")
 
 echo "> Compiling and linking source files... "
 
-FLAGS="-std=c++17 -O1 -stdlib=libc++ -frtti -Wfatal-errors -Iinclude"
+FLAGS="-std=c11 -O1 -Wfatal-errors -Iinclude"
 
 if [[ "$OSTYPE" == "darwin"* ]]; then
     LIB_EXTENSION=".dylib"
@@ -35,12 +33,12 @@ else
     LINK_FLAGS="-Wl,-rpath=."
 fi
 
-clang++ $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared
+clang $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared
 
 # compile main.cpp and link to libpocketpy.so
-echo "> Compiling main.cpp and linking to libpocketpy$LIB_EXTENSION..."
+echo "> Compiling main.c and linking to libpocketpy$LIB_EXTENSION..."
 
-clang++ $FLAGS -o main -O1 src2/main.cpp -L. -lpocketpy $LINK_FLAGS
+clang $FLAGS -o main -O1 src2/main.c -L. -lpocketpy $LINK_FLAGS
 
 if [ $? -eq 0 ]; then
     echo "Build completed. Type \"./main\" to enter REPL."

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

@@ -93,6 +93,8 @@ int pk_arrayequal(py_TValue* lhs, int lhs_length, py_TValue* rhs, int rhs_length
 bool pk_arrayiter(py_Ref val);
 bool pk_arraycontains(py_Ref self, py_Ref val);
 
+bool pk_pushmethod(py_StackRef self, py_Name name);
+
 /// Assumes [a, b] are on the stack, performs a binary op.
 /// The result is stored in `self->last_retval`.
 /// The stack remains unchanged.

+ 5 - 5
include/pocketpy/pocketpy.h

@@ -178,17 +178,12 @@ bool py_deldict(py_Ref self, py_Name name);
 py_ObjectRef py_getslot(py_Ref self, int i);
 void py_setslot(py_Ref self, int i, py_Ref val);
 
-py_TmpRef py_getupvalue(py_StackRef argv);
-void py_setupvalue(py_StackRef argv, py_Ref val);
-
 /// Gets the attribute of the object.
 bool py_getattr(py_Ref self, py_Name name);
 /// Sets the attribute of the object.
 bool py_setattr(py_Ref self, py_Name name, py_Ref val);
 /// Deletes the attribute of the object.
 bool py_delattr(py_Ref self, py_Name name);
-/// Gets the unbound method of the object.
-bool py_getunboundmethod(py_Ref self, py_Name name, py_Ref out, py_Ref out_self);
 
 bool py_getitem(py_Ref self, py_Ref key);
 bool py_setitem(py_Ref self, py_Ref key, py_Ref val);
@@ -231,6 +226,11 @@ void py_pop();
 void py_shrink(int n);
 /// Get a temporary variable from the stack and returns the reference to it.
 py_StackRef py_pushtmp();
+/// Gets the unbound method of the object.
+/// Assumes the object is located at the top of the stack.
+/// If returns true:  [self] -> [unbound, self]
+/// If returns false: [self] -> [self] (no change)
+bool py_pushmethod(py_Name name);
 
 /************* Modules *************/
 py_TmpRef py_newmodule(const char* name, const char* package);

+ 5 - 8
src/interpreter/ceval.c

@@ -251,12 +251,9 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                 goto __ERROR;
             }
             case OP_LOAD_METHOD: {
-                // [self]
-                bool ok = py_getunboundmethod(TOP(), byte.arg, TOP(), SP());
-                if(ok) {
-                    // [unbound, self]
-                    SP()++;
-                } else {
+                // [self] -> [unbound, self]
+                bool ok = py_pushmethod(byte.arg);
+                if(!ok) {
                     // fallback to getattr
                     if(py_getattr(TOP(), byte.arg)) {
                         py_assign(TOP(), py_retval());
@@ -912,8 +909,8 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
         pk_print_stack(self, frame, (Bytecode){});
         py_BaseException__set_lineno(&self->curr_exception, Frame__lineno(frame), frame->co);
     __ERROR_RE_RAISE:
-
-        printf("error.op: %s, line: %d\n", pk_opname(byte.op), Frame__lineno(frame));
+        do {} while(0);
+        //printf("error.op: %s, line: %d\n", pk_opname(byte.op), Frame__lineno(frame));
         int lineno = py_BaseException__get_lineno(&self->curr_exception, frame->co);
         py_BaseException__stpush(&self->curr_exception,
                                  frame->co->src,

+ 2 - 2
src/interpreter/vm.c

@@ -478,7 +478,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
     }
 
     // handle `__call__` overload
-    if(py_getunboundmethod(p0, __call__, p0, p0 + 1)) {
+    if(pk_pushmethod(p0, __call__)) {
         // [__call__, self, args..., kwargs...]
         return pk_VM__vectorcall(self, argc, kwargc, opcall);
     }
@@ -557,7 +557,7 @@ void pk_ManagedHeap__mark(pk_ManagedHeap* self) {
 }
 
 void pk_print_stack(pk_VM* self, Frame* frame, Bytecode byte) {
-    // return;
+    return;
     if(frame == NULL) return;
 
     py_TValue* sp = self->stack.sp;

+ 10 - 12
src/public/modules.c

@@ -132,19 +132,17 @@ static bool _py_builtins__next(int argc, py_Ref argv) {
 static bool _py_builtins__sorted(int argc, py_Ref argv) {
     PY_CHECK_ARGC(3);
     // convert _0 to list object
-    if(!py_tpcall(tp_list, 1, argv)) return false;
-    py_Ref retval = py_pushtmp();
-    py_Ref sort = py_pushtmp();
-    py_Ref self = py_pushtmp();
-    py_Ref key = py_pushtmp();
-    py_Ref reverse = py_pushtmp();
-    *self = *retval = *py_retval();
-    bool ok = py_getunboundmethod(self, py_name("sort"), sort, self);
+    if(!py_tpcall(tp_list, 1, py_arg(0))) return false;
+    py_push(py_retval());                       // duptop
+    py_push(py_retval());                       // [| <list>]
+    bool ok = py_pushmethod(py_name("sort"));   // [| list.sort, <list>]
+    if(!ok) return false;
+    py_push(py_arg(1));                         // [| list.sort, <list>, key]
+    py_push(py_arg(2));                         // [| list.sort, <list>, key, reverse]
+    ok = py_vectorcall(2, 0);                   // [| ]
     if(!ok) return false;
-    *key = argv[1];
-    *reverse = argv[2];
-    if(!py_vectorcall(2, 0)) return false;
-    *py_retval() = *retval;
+    py_assign(py_retval(), py_peek(-1));
+    py_pop();
     return true;
 }
 

+ 1 - 1
src/public/py_exception.c

@@ -129,7 +129,7 @@ void py_printexc() {
 
 char* py_formatexc() {
     pk_VM* vm = pk_current_vm;
-    if(py_isnil(&vm->curr_exception)) { return NULL; }
+    if(py_isnil(&vm->curr_exception)) return NULL;
     c11_sbuf ss;
     c11_sbuf__ctor(&ss);
 

+ 12 - 7
src/public/vm.c

@@ -230,7 +230,11 @@ bool py_vectorcall(uint16_t argc, uint16_t kwargc) {
 
 py_Ref py_retval() { return &pk_current_vm->last_retval; }
 
-bool py_getunboundmethod(py_Ref self, py_Name name, py_Ref out, py_Ref out_self) {
+bool py_pushmethod(py_Name name){
+    return pk_pushmethod(py_peek(-1), name);
+}
+
+bool pk_pushmethod(py_StackRef self, py_Name name) {
     // NOTE: `out` and `out_self` may overlap with `self`
     py_Type type;
     // handle super() proxy
@@ -243,22 +247,23 @@ bool py_getunboundmethod(py_Ref self, py_Name name, py_Ref out, py_Ref out_self)
 
     py_Ref cls_var = py_tpfindname(type, name);
     if(cls_var != NULL) {
+        pk_current_vm->stack.sp++;
         switch(cls_var->type) {
             case tp_function:
             case tp_nativefunc: {
                 py_TValue self_bak = *self;
                 // `out` may overlap with `self`. If we assign `out`, `self` may be corrupted.
-                *out = *cls_var;
-                *out_self = self_bak;
+                self[0] = *cls_var;
+                self[1] = self_bak;
                 break;
             }
             case tp_staticmethod:
-                *out = *py_getslot(cls_var, 0);
-                py_newnil(out_self);
+                self[0] = *py_getslot(cls_var, 0);
+                self[1] = *py_NIL;
                 break;
             case tp_classmethod:
-                *out = *py_getslot(cls_var, 0);
-                *out_self = c11__getitem(pk_TypeInfo, &pk_current_vm->types, type).self;
+                self[0] = *py_getslot(cls_var, 0);
+                self[1] = c11__getitem(pk_TypeInfo, &pk_current_vm->types, type).self;
                 break;
             default: c11__unreachedable();
         }