mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
40d6f1a19f
commit
45de08dd39
@ -51,7 +51,7 @@ typedef struct pk_VM {
|
||||
void (*_stderr)(const char*, ...);
|
||||
|
||||
py_TValue last_retval;
|
||||
bool has_error;
|
||||
py_TValue last_exception;
|
||||
bool is_stopiteration;
|
||||
|
||||
py_TValue reg[8]; // users' registers
|
||||
@ -114,6 +114,8 @@ py_Type pk_function__register();
|
||||
py_Type pk_nativefunc__register();
|
||||
py_Type pk_range__register();
|
||||
py_Type pk_range_iterator__register();
|
||||
py_Type pk_BaseException__register();
|
||||
py_Type pk_Exception__register();
|
||||
|
||||
py_TValue pk_builtins__register();
|
||||
|
||||
|
@ -13,12 +13,12 @@ extern "C" {
|
||||
// pk_SourceData_ src;
|
||||
// int lineno;
|
||||
// const char* cursor;
|
||||
// py_Str name;
|
||||
// c11_string* name;
|
||||
// } pkpy_ExceptionFrame;
|
||||
|
||||
// typedef struct pkpy_Exception {
|
||||
// py_Name type;
|
||||
// py_Str msg;
|
||||
// c11_string* msg;
|
||||
// bool is_re;
|
||||
|
||||
// int _ip_on_error;
|
||||
|
@ -409,6 +409,7 @@ enum py_PredefinedTypes {
|
||||
tp_nativefunc,
|
||||
tp_bound_method,
|
||||
tp_super, // 1 slot + py_Type
|
||||
tp_base_exception,
|
||||
tp_exception,
|
||||
tp_bytes,
|
||||
tp_mappingproxy,
|
||||
|
@ -83,7 +83,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
__NEXT_STEP:
|
||||
byte = *frame->ip;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
for(py_Ref p = self->stack.begin; p != SP(); p++) {
|
||||
@ -777,7 +777,6 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
// 1. Exception can be handled inside the current frame
|
||||
// 2. Exception need to be propagated to the upper frame
|
||||
printf("error.op: %s, line: %d\n", pk_opname(byte.op), Frame__lineno(frame));
|
||||
assert(false);
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
self->_stderr = pk_default_stderr;
|
||||
|
||||
self->last_retval = PY_NIL;
|
||||
self->has_error = false;
|
||||
self->last_exception = PY_NIL;
|
||||
self->is_stopiteration = false;
|
||||
|
||||
self->__curr_class = PY_NIL;
|
||||
@ -112,7 +112,8 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
validate(tp_bound_method, pk_VM__new_type(self, "bound_method", tp_object, NULL, false));
|
||||
|
||||
validate(tp_super, pk_VM__new_type(self, "super", tp_object, NULL, false));
|
||||
validate(tp_exception, pk_VM__new_type(self, "Exception", tp_object, NULL, true));
|
||||
validate(tp_base_exception, pk_BaseException__register());
|
||||
validate(tp_exception, pk_Exception__register());
|
||||
validate(tp_bytes, pk_bytes__register());
|
||||
validate(tp_mappingproxy, pk_VM__new_type(self, "mappingproxy", tp_object, NULL, false));
|
||||
|
||||
@ -148,6 +149,7 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
tp_bytes,
|
||||
tp_dict,
|
||||
tp_property,
|
||||
tp_base_exception,
|
||||
tp_exception,
|
||||
tp_stop_iteration,
|
||||
tp_syntax_error};
|
||||
|
@ -4,24 +4,25 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
void py_printexc(){
|
||||
void py_printexc() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
if(vm->has_error){
|
||||
assert(vm->last_retval.type == tp_exception);
|
||||
}else{
|
||||
if(py_isnil(&vm->last_exception)) {
|
||||
vm->_stdout("NoneType: None\n");
|
||||
} else {
|
||||
const char* name = py_tpname(vm->last_exception.type);
|
||||
bool ok = py_str(&vm->last_exception);
|
||||
if(!ok) abort();
|
||||
const char* message = py_tostr(py_retval());
|
||||
vm->_stdout("%s: %s\n", name, message);
|
||||
}
|
||||
}
|
||||
|
||||
void py_formatexc(char* out) {}
|
||||
|
||||
void py_formatexc(char *out){
|
||||
|
||||
}
|
||||
|
||||
bool py_exception(const char* name, const char* fmt, ...){
|
||||
bool py_exception(const char* name, const char* fmt, ...) {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
assert(!vm->has_error); // an error is already set
|
||||
vm->has_error = true;
|
||||
// an error is already set
|
||||
assert(py_isnil(&vm->last_exception));
|
||||
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
@ -31,8 +32,14 @@ bool py_exception(const char* name, const char* fmt, ...){
|
||||
va_end(args);
|
||||
|
||||
c11_string* res = c11_sbuf__submit(&buf);
|
||||
// vm->last_retval = py_newexception(name, res->data);
|
||||
vm->_stderr("%s: %s\n", name, res->data);
|
||||
py_Ref message = py_pushtmp();
|
||||
py_newstrn(message, res->data, res->size);
|
||||
c11_string__delete(res);
|
||||
py_pop();
|
||||
|
||||
bool ok = py_tpcall(tp_exception, 1, message);
|
||||
if(!ok) abort();
|
||||
vm->last_exception = *py_retval();
|
||||
|
||||
return false;
|
||||
}
|
81
src/public/py_exception.c
Normal file
81
src/public/py_exception.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include "pocketpy/pocketpy.h"
|
||||
|
||||
#include "pocketpy/common/utils.h"
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include "pocketpy/common/sstream.h"
|
||||
|
||||
typedef struct BaseExceptionFrame {
|
||||
pk_SourceData_ src;
|
||||
int lineno;
|
||||
c11_string* name;
|
||||
} BaseExceptionFrame;
|
||||
|
||||
typedef struct BaseException {
|
||||
int ip_backup;
|
||||
CodeObject* code_backup;
|
||||
c11_vector /*T=BaseExceptionFrame*/ stacktrace;
|
||||
} BaseException;
|
||||
|
||||
static bool _py_BaseException__new__(int argc, py_Ref argv) {
|
||||
py_Type cls = py_totype(argv);
|
||||
BaseException* ud = py_newobject(py_retval(), cls, 1, sizeof(BaseException));
|
||||
ud->ip_backup = -1;
|
||||
ud->code_backup = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_BaseException__init__(int argc, py_Ref argv) {
|
||||
if(argc == 1 + 0) { return true; }
|
||||
if(argc == 1 + 1) {
|
||||
py_setslot(py_arg(0), 0, py_arg(1));
|
||||
return true;
|
||||
}
|
||||
return TypeError("__init__() takes at most 2 arguments but %d were given", argc);
|
||||
}
|
||||
|
||||
static bool _py_BaseException__repr__(int argc, py_Ref argv) {
|
||||
c11_sbuf ss;
|
||||
c11_sbuf__ctor(&ss);
|
||||
pk_sprintf(&ss, "%t(", argv->type);
|
||||
py_Ref arg = py_getslot(argv, 0);
|
||||
if(!py_isnil(arg)) {
|
||||
if(!py_repr(arg)) return false;
|
||||
c11_sbuf__write_sv(&ss, py_tosv(py_retval()));
|
||||
}
|
||||
c11_sbuf__write_char(&ss, ')');
|
||||
c11_string* res = c11_sbuf__submit(&ss);
|
||||
py_newstrn(py_retval(), res->data, res->size);
|
||||
c11_string__delete(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_BaseException__str__(int argc, py_Ref argv) {
|
||||
c11_sbuf ss;
|
||||
c11_sbuf__ctor(&ss);
|
||||
py_Ref arg = py_getslot(argv, 0);
|
||||
if(!py_isnil(arg)) {
|
||||
if(!py_str(arg)) return false;
|
||||
c11_sbuf__write_sv(&ss, py_tosv(py_retval()));
|
||||
}
|
||||
c11_string* res = c11_sbuf__submit(&ss);
|
||||
py_newstrn(py_retval(), res->data, res->size);
|
||||
c11_string__delete(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_BaseException__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "BaseException", tp_object, NULL, true);
|
||||
py_bindmagic(type, __new__, _py_BaseException__new__);
|
||||
py_bindmagic(type, __init__, _py_BaseException__init__);
|
||||
py_bindmagic(type, __repr__, _py_BaseException__repr__);
|
||||
py_bindmagic(type, __str__, _py_BaseException__str__);
|
||||
return type;
|
||||
}
|
||||
|
||||
py_Type pk_Exception__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "Exception", tp_base_exception, NULL, true);
|
||||
return type;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
def f(a, b):
|
||||
return a+b
|
||||
|
||||
assert f(1, 2) == 3
|
Loading…
x
Reference in New Issue
Block a user