mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 03:50:16 +00:00
add mappingproxy
This commit is contained in:
parent
b73029247b
commit
bcf607c6a0
4
src/gc.h
4
src/gc.h
@ -136,6 +136,10 @@ template<> inline void gc_mark<NameDict>(NameDict& t){
|
||||
}
|
||||
}
|
||||
|
||||
template<> inline void gc_mark<MappingProxy>(MappingProxy& t){
|
||||
OBJ_MARK(t.obj);
|
||||
}
|
||||
|
||||
template<> inline void gc_mark<BoundMethod>(BoundMethod& t){
|
||||
OBJ_MARK(t.self);
|
||||
OBJ_MARK(t.func);
|
||||
|
@ -158,6 +158,13 @@ struct Py_ final: PyObject {
|
||||
}
|
||||
};
|
||||
|
||||
struct MappingProxy{
|
||||
PyObject* obj;
|
||||
MappingProxy(PyObject* obj) : obj(obj) {}
|
||||
|
||||
NameDict& attr() noexcept { return obj->attr(); }
|
||||
};
|
||||
|
||||
#define OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
|
||||
#define OBJ_MARK(obj) if(!is_tagged(obj)) (obj)->_obj_gc_mark()
|
||||
|
||||
|
@ -190,15 +190,6 @@ inline void init_builtins(VM* _vm) {
|
||||
return VAR(ss.str());
|
||||
});
|
||||
|
||||
_vm->bind_method<1>("object", "__getattribute__", [](VM* vm, ArgsView args) {
|
||||
PyObject* self = args[0];
|
||||
if(is_tagged(self) || !self->is_attr_valid()) vm->TypeError("object has no attribute");
|
||||
StrName name = CAST(Str&, args[1]);
|
||||
PyObject* ret = self->attr().try_get(name);
|
||||
if(ret == nullptr) vm->AttributeError(name.sv());
|
||||
return ret;
|
||||
});
|
||||
|
||||
_vm->bind_method<1>("object", "__eq__", CPP_LAMBDA(VAR(args[0] == args[1])));
|
||||
_vm->bind_method<1>("object", "__ne__", CPP_LAMBDA(VAR(args[0] != args[1])));
|
||||
|
||||
@ -661,6 +652,58 @@ inline void init_builtins(VM* _vm) {
|
||||
ss << CAST(Str, vm->asRepr(self.step)) << ")";
|
||||
return VAR(ss.str());
|
||||
});
|
||||
|
||||
/************ MappingProxy ************/
|
||||
_vm->bind_method<0>("mappingproxy", "keys", [](VM* vm, ArgsView args) {
|
||||
MappingProxy& self = CAST(MappingProxy&, args[0]);
|
||||
List keys;
|
||||
for(StrName name : self.attr().keys()) keys.push_back(VAR(name.sv()));
|
||||
return VAR(std::move(keys));
|
||||
});
|
||||
|
||||
_vm->bind_method<0>("mappingproxy", "values", [](VM* vm, ArgsView args) {
|
||||
MappingProxy& self = CAST(MappingProxy&, args[0]);
|
||||
List values;
|
||||
for(auto& item : self.attr().items()) values.push_back(item.second);
|
||||
return VAR(std::move(values));
|
||||
});
|
||||
|
||||
_vm->bind_method<0>("mappingproxy", "items", [](VM* vm, ArgsView args) {
|
||||
MappingProxy& self = CAST(MappingProxy&, args[0]);
|
||||
List items;
|
||||
for(auto& item : self.attr().items()){
|
||||
PyObject* t = VAR(Tuple({VAR(item.first.sv()), item.second}));
|
||||
items.push_back(std::move(t));
|
||||
}
|
||||
return VAR(std::move(items));
|
||||
});
|
||||
|
||||
_vm->bind_method<0>("mappingproxy", "__len__", [](VM* vm, ArgsView args) {
|
||||
MappingProxy& self = CAST(MappingProxy&, args[0]);
|
||||
return VAR(self.attr().size());
|
||||
});
|
||||
|
||||
_vm->bind_method<1>("mappingproxy", "__getitem__", [](VM* vm, ArgsView args) {
|
||||
MappingProxy& self = CAST(MappingProxy&, args[0]);
|
||||
StrName key = CAST(Str&, args[1]);
|
||||
PyObject* ret = self.attr().try_get(key);
|
||||
if(ret == nullptr) vm->AttributeError(key.sv());
|
||||
return ret;
|
||||
});
|
||||
|
||||
_vm->bind_method<0>("mappingproxy", "__repr__", [](VM* vm, ArgsView args) {
|
||||
MappingProxy& self = CAST(MappingProxy&, args[0]);
|
||||
std::stringstream ss;
|
||||
ss << "mappingproxy({";
|
||||
bool first = true;
|
||||
for(auto& item : self.attr().items()){
|
||||
if(!first) ss << ", ";
|
||||
first = false;
|
||||
ss << item.first.escape() << ": " << CAST(Str, vm->asRepr(item.second));
|
||||
}
|
||||
ss << "})";
|
||||
return VAR(ss.str());
|
||||
});
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -914,6 +957,12 @@ inline void VM::post_init(){
|
||||
_t(tp_slice)->attr().set("step", property([](VM* vm, ArgsView args){
|
||||
return CAST(Slice&, args[0]).step;
|
||||
}));
|
||||
_t(tp_object)->attr().set("__dict__", property([](VM* vm, ArgsView args){
|
||||
if(is_tagged(args[0]) || !args[0]->is_attr_valid()){
|
||||
vm->AttributeError("__dict__");
|
||||
}
|
||||
return VAR(MappingProxy(args[0]));
|
||||
}));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
4
src/vm.h
4
src/vm.h
@ -102,7 +102,7 @@ public:
|
||||
Type tp_list, tp_tuple;
|
||||
Type tp_function, tp_native_func, tp_iterator, tp_bound_method;
|
||||
Type tp_slice, tp_range, tp_module;
|
||||
Type tp_super, tp_exception, tp_bytes;
|
||||
Type tp_super, tp_exception, tp_bytes, tp_mappingproxy;
|
||||
|
||||
const bool enable_os;
|
||||
|
||||
@ -430,6 +430,7 @@ DEF_NATIVE_2(Range, tp_range)
|
||||
DEF_NATIVE_2(Slice, tp_slice)
|
||||
DEF_NATIVE_2(Exception, tp_exception)
|
||||
DEF_NATIVE_2(Bytes, tp_bytes)
|
||||
DEF_NATIVE_2(MappingProxy, tp_mappingproxy)
|
||||
|
||||
#define PY_CAST_INT(T) \
|
||||
template<> inline T py_cast<T>(VM* vm, PyObject* obj){ \
|
||||
@ -864,6 +865,7 @@ inline void VM::init_builtin_types(){
|
||||
tp_super = _new_type_object("super");
|
||||
tp_exception = _new_type_object("Exception");
|
||||
tp_bytes = _new_type_object("bytes");
|
||||
tp_mappingproxy = _new_type_object("mappingproxy");
|
||||
|
||||
this->None = heap._new<Dummy>(_new_type_object("NoneType"), {});
|
||||
this->Ellipsis = heap._new<Dummy>(_new_type_object("ellipsis"), {});
|
||||
|
Loading…
x
Reference in New Issue
Block a user