blueloveTH 1 rok temu
rodzic
commit
1d319c4ab6

+ 2 - 0
include/pocketpy/pocketpy.h

@@ -615,6 +615,8 @@ enum py_PredefinedTypes {
     tp_ellipsis,
     tp_generator,
     /* builtin exceptions */
+    tp_SystemExit,
+    tp_KeyboardInterrupt,
     tp_StopIteration,
     tp_SyntaxError,
     tp_StackOverflowError,

+ 16 - 40
src/interpreter/ceval.c

@@ -161,48 +161,13 @@ FrameResult VM__run_top_frame(VM* self) {
                 DISPATCH();
             }
             case OP_LOAD_NAME: {
+                assert(frame->is_dynamic);
                 py_Name name = byte.arg;
                 py_TValue* tmp;
-                if(!frame->is_dynamic) {
-                    // locals
-                    tmp = Frame__f_locals_try_get(frame, name);
-                    if(tmp != NULL) {
-                        if(py_isnil(tmp)) {
-                            UnboundLocalError(name);
-                            goto __ERROR;
-                        }
-                        PUSH(tmp);
-                        DISPATCH();
-                    }
-                    // closure
-                    tmp = Frame__f_closure_try_get(frame, name);
-                    if(tmp != NULL) {
-                        PUSH(tmp);
-                        DISPATCH();
-                    }
-                    // globals
-                    tmp = py_getdict(frame->module, name);
-                    if(tmp != NULL) {
-                        PUSH(tmp);
-                        DISPATCH();
-                    }
-                } else {
-                    py_newstr(SP()++, py_name2str(name));
-                    // locals
-                    if(!py_isnone(&frame->p0[1])) {
-                        if(py_getitem(&frame->p0[1], TOP())) {
-                            py_assign(TOP(), py_retval());
-                            DISPATCH();
-                        } else {
-                            if(py_matchexc(tp_KeyError)) {
-                                py_clearexc(NULL);
-                            } else {
-                                goto __ERROR;
-                            }
-                        }
-                    }
-                    // globals
-                    if(py_getitem(&frame->p0[0], TOP())) {
+                py_newstr(SP()++, py_name2str(name));
+                // locals
+                if(!py_isnone(&frame->p0[1])) {
+                    if(py_getitem(&frame->p0[1], TOP())) {
                         py_assign(TOP(), py_retval());
                         DISPATCH();
                     } else {
@@ -213,6 +178,17 @@ FrameResult VM__run_top_frame(VM* self) {
                         }
                     }
                 }
+                // globals
+                if(py_getitem(&frame->p0[0], TOP())) {
+                    py_assign(TOP(), py_retval());
+                    DISPATCH();
+                } else {
+                    if(py_matchexc(tp_KeyError)) {
+                        py_clearexc(NULL);
+                    } else {
+                        goto __ERROR;
+                    }
+                }
                 // builtins
                 tmp = py_getdict(&self->builtins, name);
                 if(tmp != NULL) {

+ 22 - 19
src/interpreter/vm.c

@@ -136,30 +136,33 @@ void VM__ctor(VM* self) {
     self->builtins = pk_builtins__register();
 
     // inject some builtin expections
-#define INJECT_BUILTIN_EXC(name)                                                                   \
+#define INJECT_BUILTIN_EXC(name, TBase)                                                            \
     do {                                                                                           \
-        py_Type type = pk_newtype(#name, tp_Exception, &self->builtins, NULL, false, true);        \
+        py_Type type = pk_newtype(#name, TBase, &self->builtins, NULL, false, true);               \
         py_setdict(&self->builtins, py_name(#name), py_tpobject(type));                            \
         validate(tp_##name, type);                                                                 \
     } while(0)
 
-    INJECT_BUILTIN_EXC(StopIteration);
-    INJECT_BUILTIN_EXC(SyntaxError);
-    INJECT_BUILTIN_EXC(StackOverflowError);
-    INJECT_BUILTIN_EXC(IOError);
-    INJECT_BUILTIN_EXC(OSError);
-    INJECT_BUILTIN_EXC(NotImplementedError);
-    INJECT_BUILTIN_EXC(TypeError);
-    INJECT_BUILTIN_EXC(IndexError);
-    INJECT_BUILTIN_EXC(ValueError);
-    INJECT_BUILTIN_EXC(RuntimeError);
-    INJECT_BUILTIN_EXC(ZeroDivisionError);
-    INJECT_BUILTIN_EXC(NameError);
-    INJECT_BUILTIN_EXC(UnboundLocalError);
-    INJECT_BUILTIN_EXC(AttributeError);
-    INJECT_BUILTIN_EXC(ImportError);
-    INJECT_BUILTIN_EXC(AssertionError);
-    INJECT_BUILTIN_EXC(KeyError);
+    INJECT_BUILTIN_EXC(SystemExit, tp_BaseException);
+    INJECT_BUILTIN_EXC(KeyboardInterrupt, tp_BaseException);
+
+    INJECT_BUILTIN_EXC(StopIteration, tp_Exception);
+    INJECT_BUILTIN_EXC(SyntaxError, tp_Exception);
+    INJECT_BUILTIN_EXC(StackOverflowError, tp_Exception);
+    INJECT_BUILTIN_EXC(IOError, tp_Exception);
+    INJECT_BUILTIN_EXC(OSError, tp_Exception);
+    INJECT_BUILTIN_EXC(NotImplementedError, tp_Exception);
+    INJECT_BUILTIN_EXC(TypeError, tp_Exception);
+    INJECT_BUILTIN_EXC(IndexError, tp_Exception);
+    INJECT_BUILTIN_EXC(ValueError, tp_Exception);
+    INJECT_BUILTIN_EXC(RuntimeError, tp_Exception);
+    INJECT_BUILTIN_EXC(ZeroDivisionError, tp_Exception);
+    INJECT_BUILTIN_EXC(NameError, tp_Exception);
+    INJECT_BUILTIN_EXC(UnboundLocalError, tp_Exception);
+    INJECT_BUILTIN_EXC(AttributeError, tp_Exception);
+    INJECT_BUILTIN_EXC(ImportError, tp_Exception);
+    INJECT_BUILTIN_EXC(AssertionError, tp_Exception);
+    INJECT_BUILTIN_EXC(KeyError, tp_Exception);
 
 #undef INJECT_BUILTIN_EXC
 #undef validate

+ 5 - 1
src/public/modules.c

@@ -169,9 +169,13 @@ static bool builtins_exit(int argc, py_Ref argv) {
         PY_CHECK_ARG_TYPE(0, tp_int);
         code = py_toint(argv);
     }
-    // return py_exception("SystemExit", "%d", code);
     exit(code);
     return false;
+    // py_TValue sso_code;
+    // py_newint(&sso_code, code);
+    // bool ok = py_tpcall(tp_SystemExit, 1, &sso_code);
+    // if(!ok) return false;
+    // return py_raise(py_retval());
 }
 
 static bool builtins_len(int argc, py_Ref argv) {

+ 4 - 1
tests/25_rfstring.py

@@ -127,4 +127,7 @@ assert f'{a:10}' == 'A         '
 
 assert f'{A()!r:10}' == 'A()       '
 assert f'{A():10}' == 'A         '
-assert f'{A():10}' == 'A         '
+assert f'{A():10}' == 'A         '
+
+a = ['1', '2', '3']
+assert f'a = {'\n'.join(a)}' == 'a = 1\n2\n3'