mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 13:00:17 +00:00
...
This commit is contained in:
parent
0e7936341b
commit
145782b789
@ -489,12 +489,18 @@ void py_list_append(py_Ref self, py_Ref val);
|
||||
void py_list_clear(py_Ref self);
|
||||
void py_list_insert(py_Ref self, int i, py_Ref val);
|
||||
|
||||
py_TmpRef py_dict_getitem(py_Ref self, py_Ref key) PY_RAISE;
|
||||
void py_dict_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE;
|
||||
void py_dict_delitem(py_Ref self, py_Ref key) PY_RAISE;
|
||||
bool py_dict_contains(py_Ref self, py_Ref key) PY_RAISE;
|
||||
int py_dict_len(py_Ref self);
|
||||
/// -1: error, 0: not found, 1: found
|
||||
int py_dict_getitem(py_Ref self, py_Ref key) PY_RAISE;
|
||||
/// true: success, false: error
|
||||
bool py_dict_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE;
|
||||
/// -1: error, 0: not found, 1: found (and deleted)
|
||||
int py_dict_delitem(py_Ref self, py_Ref key) PY_RAISE;
|
||||
/// -1: error, 0: not found, 1: found
|
||||
int py_dict_contains(py_Ref self, py_Ref key) PY_RAISE;
|
||||
/// true: success, false: error
|
||||
bool py_dict_apply(py_Ref self, bool (*f)(py_Ref key, py_Ref val, void* ctx), void* ctx) PY_RAISE;
|
||||
/// noexcept
|
||||
int py_dict_len(py_Ref self);
|
||||
|
||||
/************* Others *************/
|
||||
|
||||
|
@ -87,14 +87,9 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
__NEXT_STEP:
|
||||
byte = *frame->ip;
|
||||
|
||||
#if PK_DEBUG
|
||||
pk_print_stack(self, frame, byte);
|
||||
|
||||
// #if PK_DEBUG
|
||||
// if(py_checkexc()) {
|
||||
// py_printexc();
|
||||
// c11__abort("unhandled exception!");
|
||||
// }
|
||||
// #endif
|
||||
#endif
|
||||
|
||||
switch((Opcode)byte.op) {
|
||||
case OP_NO_OP: DISPATCH();
|
||||
@ -506,8 +501,8 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
py_Ref tmp = py_pushtmp();
|
||||
py_newdict(tmp);
|
||||
for(int i = 0; i < byte.arg * 2; i += 2) {
|
||||
py_dict_setitem(tmp, begin + i, begin + i + 1);
|
||||
if(py_checkexc()) goto __ERROR;
|
||||
bool ok = py_dict_setitem(tmp, begin + i, begin + i + 1);
|
||||
if(!ok) goto __ERROR;
|
||||
}
|
||||
SP() = begin;
|
||||
PUSH(tmp);
|
||||
@ -760,8 +755,8 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
case OP_DICT_ADD: {
|
||||
// [dict, iter, key, value]
|
||||
py_dict_setitem(FOURTH(), SECOND(), TOP());
|
||||
if(py_checkexc()) goto __ERROR;
|
||||
bool ok = py_dict_setitem(FOURTH(), SECOND(), TOP());
|
||||
if(!ok) goto __ERROR;
|
||||
STACK_SHRINK(2);
|
||||
DISPATCH();
|
||||
}
|
||||
@ -917,6 +912,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
case OP_END_CLASS: {
|
||||
// [cls or decorated]
|
||||
// TODO: if __eq__ is defined, check __ne__ and provide a default implementation
|
||||
py_Name name = byte.arg;
|
||||
// set into f_globals
|
||||
py_setdict(frame->module, name, TOP());
|
||||
|
@ -389,9 +389,9 @@ static bool
|
||||
py_Ref tmp = py_pushtmp();
|
||||
c11_sv key_sv = py_name2sv(key);
|
||||
py_newstrn(tmp, key_sv.data, key_sv.size);
|
||||
py_dict_setitem(&buffer[decl->starred_kwarg], tmp, &p1[2 * j + 1]);
|
||||
bool ok = py_dict_setitem(&buffer[decl->starred_kwarg], tmp, &p1[2 * j + 1]);
|
||||
py_pop();
|
||||
if(py_checkexc()) return false;
|
||||
if(!ok) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ bool py_callcfunc(py_CFunction f, int argc, py_Ref argv) {
|
||||
c11__abort(
|
||||
"py_CFunction returns nothing! Did you forget to call `py_newnone(py_retval())`?");
|
||||
}
|
||||
// if(py_checkexc()) { c11__abort("py_CFunction returns `true` but an exception is set!"); }
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -617,11 +617,8 @@ static bool function__closure__getter(int argc, py_Ref argv) {
|
||||
c11__foreach(NameDict_KV, ud->closure, it) {
|
||||
// printf("%s -> %s\n", py_name2str(it->key), py_tpname(it->value.type));
|
||||
py_newstr(r0, py_name2str(it->key));
|
||||
py_dict_setitem(retval, r0, &it->value);
|
||||
if(py_checkexc()) {
|
||||
py_shrink(2);
|
||||
return false;
|
||||
}
|
||||
bool ok = py_dict_setitem(retval, r0, &it->value);
|
||||
if(!ok) return false;
|
||||
}
|
||||
py_assign(py_retval(), retval);
|
||||
py_shrink(2);
|
||||
|
@ -164,12 +164,10 @@ static bool Dict__set(Dict* self, py_TValue* key, py_TValue* val) {
|
||||
}
|
||||
|
||||
/// Delete an entry from the dict.
|
||||
/// If the key is found, `py_retval()` is set to the value.
|
||||
/// If the key is not found, `py_retval()` is set to `nil`.
|
||||
/// Returns false on error.
|
||||
static bool Dict__pop(Dict* self, py_Ref key) {
|
||||
/// -1: error, 0: not found, 1: found and deleted
|
||||
static int Dict__pop(Dict* self, py_Ref key) {
|
||||
py_i64 hash;
|
||||
if(!py_hash(key, &hash)) return false;
|
||||
if(!py_hash(key, &hash)) return -1;
|
||||
int idx = hash & (self->capacity - 1);
|
||||
for(int i = 0; i < PK_DICT_MAX_COLLISION; i++) {
|
||||
int idx2 = self->indices[idx]._[i];
|
||||
@ -182,12 +180,11 @@ static bool Dict__pop(Dict* self, py_Ref key) {
|
||||
self->indices[idx]._[i] = -1;
|
||||
self->length--;
|
||||
if(self->length < self->entries.count / 2) Dict__compact_entries(self);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
if(res == -1) return false; // error
|
||||
if(res == -1) return -1; // error
|
||||
}
|
||||
py_newnil(py_retval());
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DictIterator__ctor(DictIterator* self, Dict* dict) {
|
||||
@ -262,8 +259,13 @@ static bool dict__setitem__(int argc, py_Ref argv) {
|
||||
static bool dict__delitem__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
Dict* self = py_touserdata(argv);
|
||||
if(!Dict__pop(self, py_arg(1))) return false;
|
||||
return true;
|
||||
int res = Dict__pop(self, py_arg(1));
|
||||
if(res == 1) {
|
||||
py_newnone(py_retval());
|
||||
return true;
|
||||
}
|
||||
if(res == 0) return KeyError(py_arg(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool dict__contains__(int argc, py_Ref argv) {
|
||||
@ -396,10 +398,11 @@ static bool dict_get(int argc, py_Ref argv) {
|
||||
|
||||
static bool dict_pop(int argc, py_Ref argv) {
|
||||
Dict* self = py_touserdata(argv);
|
||||
if(argc < 2 || argc > 3) return TypeError("pop() takes 2 or 3 arguments (%d given)", argc);
|
||||
if(argc < 2 || argc > 3) return TypeError("pop() takes 1 or 2 arguments (%d given)", argc - 1);
|
||||
py_Ref default_val = argc == 3 ? py_arg(2) : py_None;
|
||||
if(!Dict__pop(self, py_arg(1))) return false;
|
||||
if(py_isnil(py_retval())) *py_retval() = *default_val;
|
||||
int res = Dict__pop(self, py_arg(1));
|
||||
if(res == -1) return false;
|
||||
if(res == 0) { py_assign(py_retval(), default_val); }
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -506,33 +509,37 @@ py_Type pk_dict_items__register() {
|
||||
|
||||
//////////////////////////
|
||||
|
||||
py_Ref py_dict_getitem(py_Ref self, py_Ref key) {
|
||||
int py_dict_getitem(py_Ref self, py_Ref key) {
|
||||
assert(py_isdict(self));
|
||||
Dict* ud = py_touserdata(self);
|
||||
DictEntry* entry;
|
||||
if(!Dict__try_get(ud, key, &entry)) return NULL;
|
||||
if(entry) return &entry->val;
|
||||
return NULL;
|
||||
if(!Dict__try_get(ud, key, &entry)) return -1;
|
||||
if(entry) {
|
||||
py_assign(py_retval(), &entry->val);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void py_dict_delitem(py_Ref self, py_Ref key) {
|
||||
int py_dict_delitem(py_Ref self, py_Ref key) {
|
||||
assert(py_isdict(self));
|
||||
Dict* ud = py_touserdata(self);
|
||||
Dict__pop(ud, key);
|
||||
return Dict__pop(ud, key);
|
||||
}
|
||||
|
||||
void py_dict_setitem(py_Ref self, py_Ref key, py_Ref val) {
|
||||
bool py_dict_setitem(py_Ref self, py_Ref key, py_Ref val) {
|
||||
assert(py_isdict(self));
|
||||
Dict* ud = py_touserdata(self);
|
||||
Dict__set(ud, key, val);
|
||||
return Dict__set(ud, key, val);
|
||||
}
|
||||
|
||||
bool py_dict_contains(py_Ref self, py_Ref key) {
|
||||
int py_dict_contains(py_Ref self, py_Ref key) {
|
||||
assert(py_isdict(self));
|
||||
Dict* ud = py_touserdata(self);
|
||||
DictEntry* entry;
|
||||
bool ok = Dict__try_get(ud, key, &entry);
|
||||
return ok && entry != NULL;
|
||||
if(!ok) return -1;
|
||||
return entry ? 1 : 0;
|
||||
}
|
||||
|
||||
int py_dict_len(py_Ref self) {
|
||||
|
@ -66,7 +66,7 @@ static bool _py_BaseException__init__(int argc, py_Ref argv) {
|
||||
py_setslot(py_arg(0), 0, py_arg(1));
|
||||
return true;
|
||||
}
|
||||
return TypeError("__init__() takes at most 2 arguments but %d were given", argc);
|
||||
return TypeError("__init__() takes at most 1 arguments but %d were given", argc - 1);
|
||||
}
|
||||
|
||||
static bool _py_BaseException__repr__(int argc, py_Ref argv) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user