experimental support for try..except..as

This commit is contained in:
blueloveTH 2023-12-04 18:06:02 +08:00
parent 34f3ac32e7
commit f6942e0caf
6 changed files with 43 additions and 5 deletions

View File

@ -61,7 +61,9 @@ struct Exception {
Exception(StrName type, Str msg):
type(type), msg(msg), is_re(true), _ip_on_error(-1), _code_on_error(nullptr) {}
bool match_type(StrName t) const { return this->type == t;}
bool match_type(StrName t) const {
return this->type==t || t.sv()=="Exception";
}
template<typename... Args>
void st_push(Args&&... args){

View File

@ -258,7 +258,6 @@ def help(obj):
class Exception: pass
class classmethod:
def __init__(self, f):
self.f = f

View File

@ -677,14 +677,24 @@ __EAT_DOTS_END:
};
ctx()->exit_block();
do {
StrName as_name;
consume(TK("except"));
if(match(TK("@id"))){
ctx()->emit_(OP_EXCEPTION_MATCH, StrName(prev().sv()).index, prev().line);
if(match(TK("as"))){
consume(TK("@id"));
as_name = StrName(prev().sv());
}
}else{
ctx()->emit_(OP_LOAD_TRUE, BC_NOARG, BC_KEEPLINE);
}
int patch = ctx()->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
// pop the exception on match
// on match
if(!as_name.empty()){
ctx()->emit_(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
ctx()->emit_store_name(name_scope(), as_name, BC_KEEPLINE);
}
// pop the exception
ctx()->emit_(OP_POP_EXCEPTION, BC_NOARG, BC_KEEPLINE);
compile_block_body();
patches.push_back(ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE));

View File

@ -1318,6 +1318,17 @@ void init_builtins(VM* _vm) {
// return args[0];
// });
// Exception
_vm->bind__repr__(_vm->tp_exception, [](VM* vm, PyObject* obj) {
Exception& self = _CAST(Exception&, obj);
return VAR(fmt(self.type.sv(), '(', self.msg.escape(), ')'));
});
_vm->bind__str__(_vm->tp_exception, [](VM* vm, PyObject* obj) {
Exception& self = _CAST(Exception&, obj);
return VAR(self.msg);
});
RangeIter::register_class(_vm, _vm->builtins);
ArrayIter::register_class(_vm, _vm->builtins);
StringIter::register_class(_vm, _vm->builtins);

View File

@ -724,7 +724,7 @@ void VM::init_builtin_types(){
tp_native_func = _new_type_object("native_func");
tp_bound_method = _new_type_object("bound_method");
tp_super = _new_type_object("super");
tp_exception = _new_type_object("Exception");
tp_exception = _new_type_object("_Exception");
tp_bytes = _new_type_object("bytes");
tp_mappingproxy = _new_type_object("mappingproxy");
tp_dict = _new_type_object("dict");

View File

@ -82,3 +82,19 @@ def f(a: list):
a = [0]
f(a)
assert a == [1]
try:
a = [][3]
except IndexError as e:
assert str(e) == '3 not in [0, 0)'
assert repr(e).startswith('IndexError(')
try:
a = {}[2]
except IndexError as e:
exit(1)
except Exception as e:
assert str(e) == '2'
assert repr(e).startswith('KeyError(')
except:
exit(1)