py_mappingproxy.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "pocketpy/pocketpy.h"
  2. #include "pocketpy/common/utils.h"
  3. #include "pocketpy/objects/object.h"
  4. #include "pocketpy/interpreter/vm.h"
  5. #include "pocketpy/common/sstream.h"
  6. void pk_mappingproxy__namedict(py_Ref out, py_Ref object) {
  7. py_newobject(out, tp_namedict, 1, 0);
  8. assert(object->is_ptr && object->_obj->slots == -1);
  9. py_setslot(out, 0, object);
  10. }
  11. static bool namedict__getitem__(int argc, py_Ref argv) {
  12. PY_CHECK_ARGC(2);
  13. PY_CHECK_ARG_TYPE(1, tp_str);
  14. py_Name name = py_namev(py_tosv(py_arg(1)));
  15. py_Ref res = py_getdict(py_getslot(argv, 0), name);
  16. if(!res) return KeyError(py_arg(1));
  17. py_assign(py_retval(), res);
  18. return true;
  19. }
  20. static bool namedict__setitem__(int argc, py_Ref argv) {
  21. PY_CHECK_ARGC(3);
  22. PY_CHECK_ARG_TYPE(1, tp_str);
  23. py_Name name = py_namev(py_tosv(py_arg(1)));
  24. py_setdict(py_getslot(argv, 0), name, py_arg(2));
  25. py_newnone(py_retval());
  26. return true;
  27. }
  28. static bool namedict__delitem__(int argc, py_Ref argv) {
  29. PY_CHECK_ARGC(2);
  30. PY_CHECK_ARG_TYPE(1, tp_str);
  31. py_Name name = py_namev(py_tosv(py_arg(1)));
  32. if(!py_deldict(py_getslot(argv, 0), name)) return KeyError(py_arg(1));
  33. py_newnone(py_retval());
  34. return true;
  35. }
  36. static bool namedict__contains__(int argc, py_Ref argv) {
  37. PY_CHECK_ARGC(2);
  38. PY_CHECK_ARG_TYPE(1, tp_str);
  39. py_Name name = py_namev(py_tosv(py_arg(1)));
  40. py_Ref res = py_getdict(py_getslot(argv, 0), name);
  41. py_newbool(py_retval(), res != NULL);
  42. return true;
  43. }
  44. static bool namedict_items(int argc, py_Ref argv) {
  45. PY_CHECK_ARGC(1);
  46. py_Ref object = py_getslot(argv, 0);
  47. NameDict* dict = PyObject__dict(object->_obj);
  48. py_newtuple(py_retval(), dict->count);
  49. for(int i = 0; i < dict->count; i++) {
  50. py_Ref slot = py_tuple_getitem(py_retval(), i);
  51. py_newtuple(slot, 2);
  52. NameDict_KV* kv = c11__at(NameDict_KV, dict, i);
  53. py_newstr(py_tuple_getitem(slot, 0), py_name2str(kv->key));
  54. py_assign(py_tuple_getitem(slot, 1), &kv->value);
  55. }
  56. return true;
  57. }
  58. py_Type pk_namedict__register() {
  59. py_Type type = pk_newtype("namedict", tp_object, NULL, NULL, false, true);
  60. py_bindmagic(type, __getitem__, namedict__getitem__);
  61. py_bindmagic(type, __setitem__, namedict__setitem__);
  62. py_bindmagic(type, __delitem__, namedict__delitem__);
  63. py_bindmagic(type, __contains__, namedict__contains__);
  64. py_bindmethod(type, "items", namedict_items);
  65. return type;
  66. }
  67. //////////////////////
  68. void pk_mappingproxy__locals(py_Ref out, Frame* frame) {
  69. assert(frame->has_function && !frame->is_dynamic);
  70. Frame** ud = py_newobject(out, tp_locals, 0, sizeof(Frame*));
  71. *ud = frame;
  72. }
  73. static bool locals__getitem__(int argc, py_Ref argv) {
  74. PY_CHECK_ARGC(2);
  75. PY_CHECK_ARG_TYPE(1, tp_str);
  76. Frame** ud = py_touserdata(argv);
  77. py_Name name = py_namev(py_tosv(py_arg(1)));
  78. py_Ref slot = Frame__f_locals_try_get(*ud, name);
  79. if(!slot || py_isnil(slot)) return KeyError(py_arg(1));
  80. py_assign(py_retval(), slot);
  81. return true;
  82. }
  83. static bool locals__setitem__(int argc, py_Ref argv) {
  84. PY_CHECK_ARGC(3);
  85. PY_CHECK_ARG_TYPE(1, tp_str);
  86. Frame** ud = py_touserdata(argv);
  87. py_Name name = py_namev(py_tosv(py_arg(1)));
  88. py_Ref slot = Frame__f_locals_try_get(*ud, name);
  89. if(!slot) return KeyError(py_arg(1));
  90. py_assign(slot, py_arg(2));
  91. py_newnone(py_retval());
  92. return true;
  93. }
  94. static bool locals__delitem__(int argc, py_Ref argv) {
  95. PY_CHECK_ARGC(2);
  96. PY_CHECK_ARG_TYPE(1, tp_str);
  97. Frame** ud = py_touserdata(argv);
  98. py_Name name = py_namev(py_tosv(py_arg(1)));
  99. py_Ref res = Frame__f_locals_try_get(*ud, name);
  100. if(!res || py_isnil(res)) return KeyError(py_arg(1));
  101. py_newnil(res);
  102. py_newnone(py_retval());
  103. return true;
  104. }
  105. static bool locals__contains__(int argc, py_Ref argv) {
  106. PY_CHECK_ARGC(2);
  107. PY_CHECK_ARG_TYPE(1, tp_str);
  108. Frame** ud = py_touserdata(argv);
  109. py_Name name = py_namev(py_tosv(py_arg(1)));
  110. py_Ref slot = Frame__f_locals_try_get(*ud, name);
  111. py_newbool(py_retval(), slot && !py_isnil(slot));
  112. return true;
  113. }
  114. py_Type pk_locals__register() {
  115. py_Type type = pk_newtype("locals", tp_locals, NULL, NULL, false, true);
  116. py_bindmagic(type, __getitem__, locals__getitem__);
  117. py_bindmagic(type, __setitem__, locals__setitem__);
  118. py_bindmagic(type, __delitem__, locals__delitem__);
  119. py_bindmagic(type, __contains__, locals__contains__);
  120. return type;
  121. }