diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index f801c3c9..3ef1ddd3 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -101,6 +101,7 @@ void pk_number__register(); py_Type pk_str__register(); py_Type pk_str_iterator__register(); py_Type pk_bytes__register(); +py_Type pk_dict__register(); py_Type pk_list__register(); py_Type pk_tuple__register(); py_Type pk_array_iterator__register(); diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 31fb5850..04f7b10c 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -87,7 +87,6 @@ bool py_ismagicname(py_Name); // opaque types void py_newdict(py_Ref); -void py_newset(py_Ref); void py_newslice(py_Ref); // old style argc-based function void py_newnativefunc(py_Ref out, py_CFunction); diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 021b5930..dc340698 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -275,7 +275,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { } else { INSERT_THIRD(); // [?, a, b] *THIRD() = *magic; // [__getitem__, a, b] - vectorcall_opcall(1, 0); + if(!py_vectorcall(1, 0)) goto __ERROR; } DISPATCH(); } @@ -328,7 +328,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { *TOP() = self->last_retval; } else { *FOURTH() = *magic; // [__selitem__, a, b, val] - vectorcall_opcall(2, 0); + if(!py_vectorcall(2, 0)) goto __ERROR; POP(); // discard retval } DISPATCH(); @@ -399,7 +399,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { } else { INSERT_THIRD(); // [?, a, b] *THIRD() = *magic; // [__delitem__, a, b] - vectorcall_opcall(1, 0); + if(!py_vectorcall(1, 0)) goto __ERROR; POP(); // discard retval } DISPATCH(); @@ -427,7 +427,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { py_newnil(SP()++); // [complex, NULL] py_newint(SP()++, 0); // [complex, NULL, 0] *SP()++ = tmp; // [complex, NULL, 0, x] - vectorcall_opcall(2, 0); // [complex(x)] + if(!py_vectorcall(2, 0)) goto __ERROR; DISPATCH(); } case OP_BUILD_BYTES: { @@ -472,14 +472,19 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { } case OP_BUILD_SET: { py_TValue* begin = SP() - byte.arg; - py_Ref tmp = py_pushtmp(); - py_newset(tmp); + py_Ref typeobject_set = py_getdict(&self->builtins, py_name("set")); + assert(typeobject_set != NULL); + py_push(typeobject_set); + py_pushnil(); + if(!py_vectorcall(0, 0)) goto __ERROR; + py_push(py_retval()); // empty set py_Name id_add = py_name("add"); for(int i = 0; i < byte.arg; i++) { - if(!py_callmethod(tmp, id_add, 1, begin + i)) goto __ERROR; + if(!py_callmethod(TOP(), id_add, 1, begin + i)) goto __ERROR; } + py_TValue tmp = *TOP(); SP() = begin; - PUSH(tmp); + PUSH(&tmp); DISPATCH(); } case OP_BUILD_SLICE: { @@ -536,7 +541,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { } else { INSERT_THIRD(); // [?, b, a] *THIRD() = *magic; // [__contains__, a, b] - vectorcall_opcall(1, 0); + if(!py_vectorcall(1, 0)) goto __ERROR; } bool res = py_tobool(TOP()); if(byte.arg) py_newbool(TOP(), !res); diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index b2febc94..272bf1a4 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -116,7 +116,7 @@ void pk_VM__ctor(pk_VM* self) { validate(tp_bytes, pk_bytes__register()); validate(tp_mappingproxy, pk_newtype("mappingproxy", tp_object, NULL, NULL, false, true)); - validate(tp_dict, pk_newtype("dict", tp_object, NULL, NULL, false, false)); + validate(tp_dict, pk_dict__register()); validate(tp_property, pk_newtype("property", tp_object, NULL, NULL, false, true)); validate(tp_star_wrapper, pk_newtype("star_wrapper", tp_object, NULL, NULL, false, true)); diff --git a/src/public/py_dict.c b/src/public/py_dict.c index b4e2c5f3..f02310a6 100644 --- a/src/public/py_dict.c +++ b/src/public/py_dict.c @@ -4,10 +4,102 @@ #include "pocketpy/objects/object.h" #include "pocketpy/interpreter/vm.h" -void py_newdict(py_Ref out){ +typedef struct { + py_TValue key; + py_TValue val; +} DictEntry; + +typedef struct { + int length; + int capacity; + int* indices; + c11_vector /*T=DictEntry*/ entries; +} Dict; + +static void Dict__ctor(Dict* self) { + self->length = 0; + self->capacity = 16; + self->indices = malloc(self->capacity * sizeof(int)); + memset(self->indices, -1, self->capacity * sizeof(int)); + c11_vector__ctor(&self->entries, sizeof(DictEntry)); +} + +static void Dict__dtor(Dict* self) { + self->length = 0; + self->capacity = 0; + free(self->indices); + c11_vector__dtor(&self->entries); +} + +static bool Dict__probe(Dict* self, py_Ref key, DictEntry* out) { + py_i64 hash; + if(!py_hash(key, &hash)) return false; + int mask = self->capacity - 1; + for(int idx = hash & mask;; idx = (idx + 1) & mask) { + int idx2 = self->indices[idx]; + DictEntry* slot = c11__at(DictEntry, &self->entries, idx2); + if(slot){ + int res = py_eq(key, &slot->key); + if(res == -1) return false; + return res; + }else{ + + } + } +} + +static bool _py_dict__new__(int argc, py_Ref argv) { + py_newdict(py_retval()); + return true; +} + +static bool _py_dict__getitem__(int argc, py_Ref argv){ + PY_CHECK_ARGC(2); + py_i64 hash; + if(!py_hash(py_arg(1), &hash)) return false; + Dict* self = py_touserdata(argv); } -void py_newset(py_Ref out){ - -} \ No newline at end of file +static bool _py_dict__setitem__(int argc, py_Ref argv){ + PY_CHECK_ARGC(3); + py_i64 hash; + if(!py_hash(py_arg(1), &hash)) return false; +} + +static bool _py_dict__delitem__(int argc, py_Ref argv){ + PY_CHECK_ARGC(2); + py_i64 hash; + if(!py_hash(py_arg(1), &hash)) return false; +} + +static bool _py_dict__contains__(int argc, py_Ref argv){ + PY_CHECK_ARGC(2); + py_i64 hash; + if(!py_hash(py_arg(1), &hash)) return false; +} + +static bool _py_dict__len__(int argc, py_Ref argv){ + PY_CHECK_ARGC(1); + Dict* self = py_touserdata(argv); + py_newint(py_retval(), self->length); + return true; +} + +py_Type pk_dict__register() { + py_Type type = pk_newtype("dict", tp_object, NULL, (void (*)(void*))Dict__dtor, false, false); + + py_bindmagic(type, __new__, _py_dict__new__); + // py_bindmagic(type, __init__, _py_dict__init__); + py_bindmagic(type, __getitem__, _py_dict__getitem__); + py_bindmagic(type, __setitem__, _py_dict__setitem__); + py_bindmagic(type, __delitem__, _py_dict__delitem__); + py_bindmagic(type, __contains__, _py_dict__contains__); + py_bindmagic(type, __len__, _py_dict__len__); + return type; +} + +void py_newdict(py_Ref out) { + Dict* ud = py_newobject(out, tp_dict, 0, sizeof(Dict)); + Dict__ctor(ud); +} diff --git a/src/public/py_list.c b/src/public/py_list.c index be12da42..671bf6f4 100644 --- a/src/public/py_list.c +++ b/src/public/py_list.c @@ -8,13 +8,8 @@ typedef c11_vector List; void py_newlist(py_Ref out) { - pk_VM* vm = pk_current_vm; - PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_list, 0, sizeof(List)); - List* userdata = PyObject__userdata(obj); - c11_vector__ctor(userdata, sizeof(py_TValue)); - out->type = tp_list; - out->is_ptr = true; - out->_obj = obj; + List* ud = py_newobject(out, tp_list, 0, sizeof(List)); + c11_vector__ctor(ud, sizeof(py_TValue)); } void py_newlistn(py_Ref out, int n) {