py_method.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "pocketpy/pocketpy.h"
  2. #include "pocketpy/common/utils.h"
  3. #include "pocketpy/objects/object.h"
  4. #include "pocketpy/interpreter/vm.h"
  5. /* staticmethod */
  6. static bool staticmethod__new__(int argc, py_Ref argv) {
  7. PY_CHECK_ARGC(2);
  8. py_newobject(py_retval(), tp_staticmethod, 1, 0);
  9. py_setslot(py_retval(), 0, py_arg(1));
  10. return true;
  11. }
  12. py_Type pk_staticmethod__register() {
  13. py_Type type = pk_newtype("staticmethod", tp_object, NULL, NULL, false, true);
  14. py_bindmagic(type, __new__, staticmethod__new__);
  15. return type;
  16. }
  17. /* classmethod */
  18. static bool classmethod__new__(int argc, py_Ref argv) {
  19. PY_CHECK_ARGC(2);
  20. py_newobject(py_retval(), tp_classmethod, 1, 0);
  21. py_setslot(py_retval(), 0, py_arg(1));
  22. return true;
  23. }
  24. py_Type pk_classmethod__register() {
  25. py_Type type = pk_newtype("classmethod", tp_object, NULL, NULL, false, true);
  26. py_bindmagic(type, __new__, classmethod__new__);
  27. return type;
  28. }
  29. /* boundmethod */
  30. static bool boundmethod__self__(int argc, py_Ref argv) {
  31. PY_CHECK_ARGC(1);
  32. py_assign(py_retval(), py_getslot(argv, 0));
  33. return true;
  34. }
  35. static bool boundmethod__func__(int argc, py_Ref argv) {
  36. PY_CHECK_ARGC(1);
  37. py_assign(py_retval(), py_getslot(argv, 1));
  38. return true;
  39. }
  40. static bool boundmethod__eq__(int argc, py_Ref argv) {
  41. PY_CHECK_ARGC(2);
  42. if(!py_istype(py_arg(1), tp_boundmethod)) {
  43. py_newbool(py_retval(), false);
  44. return true;
  45. }
  46. for(int i = 0; i < 2; i++) {
  47. int res = py_equal(py_getslot(&argv[0], i), py_getslot(&argv[1], i));
  48. if(res == -1) return false;
  49. if(!res) {
  50. py_newbool(py_retval(), false);
  51. return true;
  52. }
  53. }
  54. py_newbool(py_retval(), true);
  55. return true;
  56. }
  57. static bool boundmethod__ne__(int argc, py_Ref argv) {
  58. bool ok = boundmethod__eq__(argc, argv);
  59. if(!ok) return false;
  60. bool res = py_tobool(py_retval());
  61. py_newbool(py_retval(), !res);
  62. return true;
  63. }
  64. py_Type pk_boundmethod__register() {
  65. py_Type type = pk_newtype("boundmethod", tp_object, NULL, NULL, false, true);
  66. py_bindproperty(type, "__self__", boundmethod__self__, NULL);
  67. py_bindproperty(type, "__func__", boundmethod__func__, NULL);
  68. py_bindmagic(type, __eq__, boundmethod__eq__);
  69. py_bindmagic(type, __ne__, boundmethod__ne__);
  70. return type;
  71. }