py_mappingproxy.c 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "pocketpy/pocketpy.h"
  2. #include "pocketpy/objects/object.h"
  3. #include "pocketpy/interpreter/vm.h"
  4. #include <stdbool.h>
  5. void pk_mappingproxy__namedict(py_Ref out, py_Ref object) {
  6. py_newobject(out, tp_namedict, 1, 0);
  7. assert(object->is_ptr && object->_obj->slots == -1);
  8. py_setslot(out, 0, object);
  9. }
  10. static bool namedict__getitem__(int argc, py_Ref argv) {
  11. PY_CHECK_ARGC(2);
  12. PY_CHECK_ARG_TYPE(1, tp_str);
  13. py_Name name = py_namev(py_tosv(py_arg(1)));
  14. py_Ref res = py_getdict(py_getslot(argv, 0), name);
  15. if(!res) return KeyError(py_arg(1));
  16. py_assign(py_retval(), res);
  17. return true;
  18. }
  19. static bool namedict__get(int argc, py_Ref argv) {
  20. PY_CHECK_ARGC(3);
  21. PY_CHECK_ARG_TYPE(1, tp_str);
  22. py_Name name = py_namev(py_tosv(py_arg(1)));
  23. py_Ref res = py_getdict(py_getslot(argv, 0), name);
  24. py_assign(py_retval(), res ? res : py_arg(2));
  25. return true;
  26. }
  27. static bool namedict__setitem__(int argc, py_Ref argv) {
  28. PY_CHECK_ARGC(3);
  29. PY_CHECK_ARG_TYPE(1, tp_str);
  30. py_Name name = py_namev(py_tosv(py_arg(1)));
  31. py_setdict(py_getslot(argv, 0), name, py_arg(2));
  32. py_newnone(py_retval());
  33. return true;
  34. }
  35. static bool namedict__delitem__(int argc, py_Ref argv) {
  36. PY_CHECK_ARGC(2);
  37. PY_CHECK_ARG_TYPE(1, tp_str);
  38. py_Name name = py_namev(py_tosv(py_arg(1)));
  39. if(!py_deldict(py_getslot(argv, 0), name)) return KeyError(py_arg(1));
  40. py_newnone(py_retval());
  41. return true;
  42. }
  43. static bool namedict__contains__(int argc, py_Ref argv) {
  44. PY_CHECK_ARGC(2);
  45. PY_CHECK_ARG_TYPE(1, tp_str);
  46. py_Name name = py_namev(py_tosv(py_arg(1)));
  47. py_Ref res = py_getdict(py_getslot(argv, 0), name);
  48. py_newbool(py_retval(), res != NULL);
  49. return true;
  50. }
  51. static bool namedict_items(int argc, py_Ref argv) {
  52. PY_CHECK_ARGC(1);
  53. py_Ref object = py_getslot(argv, 0);
  54. NameDict* dict = PyObject__dict(object->_obj);
  55. py_newlist(py_retval());
  56. for(int i = 0; i < dict->capacity; i++) {
  57. NameDict_KV* kv = &dict->items[i];
  58. if(kv->key == NULL) continue;
  59. py_Ref slot = py_list_emplace(py_retval());
  60. py_Ref p = py_newtuple(slot, 2);
  61. p[0] = *py_name2ref(kv->key);
  62. p[1] = kv->value;
  63. }
  64. return true;
  65. }
  66. static bool namedict_clear(int argc, py_Ref argv) {
  67. PY_CHECK_ARGC(1);
  68. py_Ref object = py_getslot(argv, 0);
  69. py_cleardict(object);
  70. py_newnone(py_retval());
  71. return true;
  72. }
  73. py_Type pk_namedict__register() {
  74. py_Type type = pk_newtype("namedict", tp_object, NULL, NULL, false, true);
  75. py_bindmagic(type, __getitem__, namedict__getitem__);
  76. py_bindmagic(type, __setitem__, namedict__setitem__);
  77. py_bindmagic(type, __delitem__, namedict__delitem__);
  78. py_bindmagic(type, __contains__, namedict__contains__);
  79. py_setdict(py_tpobject(type), __hash__, py_None());
  80. py_bindmethod(type, "items", namedict_items);
  81. py_bindmethod(type, "clear", namedict_clear);
  82. py_bindmethod(type, "get", namedict__get);
  83. return type;
  84. }