blueloveTH 1 년 전
부모
커밋
96d0c432c7
6개의 변경된 파일45개의 추가작업 그리고 25개의 파일을 삭제
  1. 18 6
      include/pocketpy/pocketpy.h
  2. 19 8
      src/interpreter/ceval.c
  3. 2 2
      src/public/cast.c
  4. 1 1
      src/public/py_ops.c
  5. 5 5
      src/public/vm.c
  6. 0 3
      src2/main.c

+ 18 - 6
include/pocketpy/pocketpy.h

@@ -34,10 +34,10 @@ void py_initialize();
 void py_finalize();
 
 /// Run a simple source string. Do not change the stack.
-int py_exec(const char*);
+bool py_exec(const char*);
 /// Eval a simple expression.
 /// The result will be set to `vm->last_retval`.
-int py_eval(const char*);
+bool py_eval(const char*);
 
 /************* Values Creation *************/
 void py_newint(py_Ref, int64_t);
@@ -90,7 +90,7 @@ double py_tofloat(const py_Ref);
 bool py_castfloat(const py_Ref, double* out);
 bool py_tobool(const py_Ref);
 const char* py_tostr(const py_Ref);
-const char* py_tostrn(const py_Ref, int* out);
+const char* py_tostrn(const py_Ref, int* size);
 
 void* py_touserdata(const py_Ref);
 
@@ -100,8 +100,8 @@ void* py_touserdata(const py_Ref);
 #define py_isstr(self) py_istype(self, tp_str)
 
 bool py_istype(const py_Ref, py_Type);
-// bool py_isinstance(const py_Ref obj, py_Type type);
-// bool py_issubclass(py_Type derived, py_Type base);
+bool py_isinstance(const py_Ref obj, py_Type type);
+bool py_issubclass(py_Type derived, py_Type base);
 
 /************* References *************/
 #define TypeError(x) false
@@ -125,11 +125,20 @@ void py_bindmethod(py_Type type, const char* name, py_CFunction f);
 void py_bindmethod2(py_Type type, const char* name, py_CFunction f, BindType bt);
 void py_bindnativefunc(py_Ref obj, const char* name, py_CFunction f);
 
+/// Get the reference to the i-th register.
+/// @lifespan: Permanent.
 py_Ref py_reg(int i);
 
+/// Get the reference of the object's `__dict__`.
+/// The object must have a `__dict__`.
+/// Returns a reference to the value or NULL if not found.
+/// @lifespan: Object.
 py_Ref py_getdict(const py_Ref self, py_Name name);
 void py_setdict(py_Ref self, py_Name name, const py_Ref val);
 
+/// Get the reference of the i-th slot of the object.
+/// The object must have slots and `i` must be in range.
+/// @lifespan: Object.
 py_Ref py_getslot(const py_Ref self, int i);
 void py_setslot(py_Ref self, int i, const py_Ref val);
 
@@ -209,7 +218,10 @@ py_Error* py_lasterror();
 void py_Error__print(py_Error*);
 
 /************* Operators *************/
-bool py_bool(const py_Ref);
+/// Equivalent to `bool(val)`.
+/// Returns 1 if `val` is truthy, otherwise 0.
+/// Returns -1 if an error occurred.
+int py_bool(const py_Ref val);
 
 int py_eq(const py_Ref, const py_Ref);
 int py_ne(const py_Ref, const py_Ref);

+ 19 - 8
src/interpreter/ceval.c

@@ -534,33 +534,43 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                 /*****************************************/
             case OP_JUMP_FORWARD: DISPATCH_JUMP((int16_t)byte.arg);
             case OP_POP_JUMP_IF_FALSE: {
-                bool res = py_bool(TOP());
+                int res = py_bool(TOP());
+                if(res < 0) goto __ERROR;
                 POP();
                 if(!res) DISPATCH_JUMP((int16_t)byte.arg);
                 DISPATCH();
             }
             case OP_POP_JUMP_IF_TRUE: {
-                bool res = py_bool(TOP());
+                int res = py_bool(TOP());
+                if(res < 0) goto __ERROR;
                 POP();
                 if(res) DISPATCH_JUMP((int16_t)byte.arg);
                 DISPATCH();
             }
-            case OP_JUMP_IF_TRUE_OR_POP:
-                if(py_bool(TOP())) {
+            case OP_JUMP_IF_TRUE_OR_POP: {
+                int res = py_bool(TOP());
+                if(res < 0) goto __ERROR;
+                if(res) {
                     DISPATCH_JUMP((int16_t)byte.arg);
                 } else {
                     POP();
                     DISPATCH();
                 }
-            case OP_JUMP_IF_FALSE_OR_POP:
-                if(!py_bool(TOP())) {
+            }
+            case OP_JUMP_IF_FALSE_OR_POP: {
+                int res = py_bool(TOP());
+                if(res < 0) goto __ERROR;
+                if(!res) {
                     DISPATCH_JUMP((int16_t)byte.arg);
                 } else {
                     POP();
                     DISPATCH();
                 }
-            case OP_SHORTCUT_IF_FALSE_OR_POP:
-                if(!py_bool(TOP())) {    // [b, False]
+            }
+            case OP_SHORTCUT_IF_FALSE_OR_POP: {
+                int res = py_bool(TOP());
+                if(res < 0) goto __ERROR;
+                if(!res) {               // [b, False]
                     STACK_SHRINK(2);     // []
                     PUSH(&self->False);  // [False]
                     DISPATCH_JUMP((int16_t)byte.arg);
@@ -568,6 +578,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                     POP();  // [b]
                     DISPATCH();
                 }
+            }
             case OP_LOOP_CONTINUE:
                 // just an alias of OP_JUMP_FORWARD
                 DISPATCH_JUMP((int16_t)byte.arg);

+ 2 - 2
src/public/cast.c

@@ -38,10 +38,10 @@ const char* py_tostr(const py_Ref self){
     return py_Str__data(ud);
 }
 
-const char* py_tostrn(const py_Ref self, int* out){
+const char* py_tostrn(const py_Ref self, int* size){
     assert(self->type == tp_str);
     py_Str* ud = PyObject__value(self->_obj);
-    *out = ud->size;
+    *size = ud->size;
     return py_Str__data(ud);
 }
 

+ 1 - 1
src/public/py_ops.c

@@ -6,7 +6,7 @@ bool py_isidentical(const py_Ref lhs, const py_Ref rhs) {
     return false;
 }
 
-bool py_bool(const py_Ref val) { return 0; }
+int py_bool(const py_Ref val) { return 1; }
 
 bool py_hash(const py_Ref val, int64_t* out) { return 0; }
 

+ 5 - 5
src/public/vm.c

@@ -23,15 +23,15 @@ void py_finalize() {
     pk_MemoryPools__finalize();
 }
 
-int py_exec(const char* source) { PK_UNREACHABLE(); }
+bool py_exec(const char* source) { PK_UNREACHABLE(); }
 
-int py_eval(const char* source) {
+bool py_eval(const char* source) {
     CodeObject co;
     pk_SourceData_ src = pk_SourceData__rcnew(source, "main.py", EVAL_MODE, false);
     Error* err = pk_compile(src, &co);
     if(err) {
         PK_DECREF(src);
-        return -1;
+        return false;
     }
     pk_VM* vm = pk_current_vm;
     Frame* frame = Frame__new(&co, &vm->main, NULL, vm->stack.sp, vm->stack.sp, &co);
@@ -39,8 +39,8 @@ int py_eval(const char* source) {
     pk_FrameResult res = pk_VM__run_top_frame(vm);
     CodeObject__dtor(&co);
     PK_DECREF(src);
-    if(res == RES_ERROR) return vm->last_error->type;
-    if(res == RES_RETURN) return 0;
+    if(res == RES_ERROR) return false;
+    if(res == RES_RETURN) return true;
     PK_UNREACHABLE();
 }
 

+ 0 - 3
src2/main.c

@@ -29,9 +29,6 @@ int main(int argc, char** argv) {
     const char* source = "1 < 2";
 
     if(py_eval(source)) {
-        py_Error* err = py_lasterror();
-        py_Error__print(err);
-    } else {
         // handle the result
         bool _L0 = py_tobool(py_lastretval());
         printf("%d\n", _L0);