From 1d319c4ab67063ca19d02c9012d16b7a2c4ba1d8 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Thu, 15 Aug 2024 01:51:14 +0800 Subject: [PATCH] ... --- include/pocketpy/pocketpy.h | 2 ++ src/interpreter/ceval.c | 56 +++++++++++-------------------------- src/interpreter/vm.c | 41 ++++++++++++++------------- src/public/modules.c | 6 +++- tests/25_rfstring.py | 5 +++- 5 files changed, 49 insertions(+), 61 deletions(-) diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index ea8e5d4e..22c632de 100644 --- a/include/pocketpy/pocketpy.h +++ b/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, diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 715bc302..a0b89245 100644 --- a/src/interpreter/ceval.c +++ b/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) { diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 533d3820..626e939a 100644 --- a/src/interpreter/vm.c +++ b/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 diff --git a/src/public/modules.c b/src/public/modules.c index f3aa451f..5f58d4fa 100644 --- a/src/public/modules.c +++ b/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) { diff --git a/tests/25_rfstring.py b/tests/25_rfstring.py index f95b67cf..4aaf4ebf 100644 --- a/tests/25_rfstring.py +++ b/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 ' \ No newline at end of file +assert f'{A():10}' == 'A ' + +a = ['1', '2', '3'] +assert f'a = {'\n'.join(a)}' == 'a = 1\n2\n3' \ No newline at end of file