values.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "pocketpy/common/str.h"
  2. #include "pocketpy/common/vector.h"
  3. #include "pocketpy/pocketpy.h"
  4. #include "pocketpy/common/utils.h"
  5. #include "pocketpy/objects/object.h"
  6. #include "pocketpy/interpreter/vm.h"
  7. #include "pocketpy/compiler/compiler.h"
  8. void py_newint(py_Ref out, int64_t val) {
  9. out->type = tp_int;
  10. out->is_ptr = false;
  11. out->_i64 = val;
  12. }
  13. void py_newfloat(py_Ref out, double val) {
  14. out->type = tp_float;
  15. out->is_ptr = false;
  16. out->_f64 = val;
  17. }
  18. void py_newbool(py_Ref out, bool val) {
  19. out->type = tp_bool;
  20. out->is_ptr = false;
  21. out->_bool = val;
  22. }
  23. void py_newnone(py_Ref out) {
  24. out->type = tp_NoneType;
  25. out->is_ptr = false;
  26. }
  27. void py_newnotimplemented(py_Ref out) {
  28. out->type = tp_NotImplementedType;
  29. out->is_ptr = false;
  30. }
  31. void py_newellipsis(py_Ref out) {
  32. out->type = tp_ellipsis;
  33. out->is_ptr = false;
  34. }
  35. void py_newnil(py_Ref out) { out->type = 0; }
  36. void py_newnativefunc(py_Ref out, py_CFunction f) {
  37. out->type = tp_nativefunc;
  38. out->is_ptr = false;
  39. out->_cfunc = f;
  40. }
  41. void py_bindmethod(py_Type type, const char* name, py_CFunction f) {
  42. py_TValue tmp;
  43. py_newnativefunc(&tmp, f);
  44. py_setdict(py_tpobject(type), py_name(name), &tmp);
  45. }
  46. void py_bindstaticmethod(py_Type type, const char* name, py_CFunction f) {
  47. py_TValue tmp;
  48. py_newnativefunc(&tmp, f);
  49. bool ok = py_tpcall(tp_staticmethod, 1, &tmp);
  50. if(!ok) {
  51. py_printexc();
  52. c11__abort("py_bindstaticmethod(): failed to create staticmethod");
  53. }
  54. py_setdict(py_tpobject(type), py_name(name), py_retval());
  55. }
  56. void py_bindfunc(py_Ref obj, const char* name, py_CFunction f) {
  57. py_TValue tmp;
  58. py_newnativefunc(&tmp, f);
  59. py_setdict(obj, py_name(name), &tmp);
  60. }
  61. void py_bindproperty(py_Type type, const char* name, py_CFunction getter, py_CFunction setter) {
  62. py_TValue tmp;
  63. py_newobject(&tmp, tp_property, 2, 0);
  64. py_newnativefunc(py_getslot(&tmp, 0), getter);
  65. if(setter) {
  66. py_newnativefunc(py_getslot(&tmp, 1), setter);
  67. } else {
  68. py_setslot(&tmp, 1, py_None());
  69. }
  70. py_setdict(py_tpobject(type), py_name(name), &tmp);
  71. }
  72. void py_bind(py_Ref obj, const char* sig, py_CFunction f) {
  73. py_TValue tmp;
  74. py_Name name = py_newfunction(&tmp, sig, f, NULL, 0);
  75. py_setdict(obj, name, &tmp);
  76. }
  77. py_Name
  78. py_newfunction(py_Ref out, const char* sig, py_CFunction f, const char* docstring, int slots) {
  79. char buffer[256];
  80. snprintf(buffer, sizeof(buffer), "def %s: pass", sig);
  81. // fn(a, b, *c, d=1) -> None
  82. CodeObject code;
  83. SourceData_ source = SourceData__rcnew(buffer, "<bind>", EXEC_MODE, false);
  84. Error* err = pk_compile(source, &code);
  85. if(err || code.func_decls.length != 1) {
  86. c11__abort("py_newfunction(): invalid signature '%s'", sig);
  87. }
  88. FuncDecl_ decl = c11__getitem(FuncDecl_, &code.func_decls, 0);
  89. decl->docstring = docstring;
  90. // construct the function
  91. Function* ud = py_newobject(out, tp_function, slots, sizeof(Function));
  92. Function__ctor(ud, decl, NULL, NULL);
  93. ud->cfunc = f;
  94. CodeObject__dtor(&code);
  95. PK_DECREF(source);
  96. assert(decl->rc.count == 1);
  97. py_Name decl_name = py_name(ud->decl->code.name->data);
  98. if(decl_name == __new__ || decl_name == __init__) {
  99. if(ud->decl->args.length == 0) {
  100. c11__abort("%s() should have at least one positional argument", py_name2str(decl_name));
  101. }
  102. }
  103. return decl_name;
  104. }
  105. void py_newboundmethod(py_Ref out, py_Ref self, py_Ref func) {
  106. py_newobject(out, tp_boundmethod, 2, 0);
  107. py_setslot(out, 0, self);
  108. py_setslot(out, 1, func);
  109. }
  110. void* py_newobject(py_Ref out, py_Type type, int slots, int udsize) {
  111. ManagedHeap* heap = &pk_current_vm->heap;
  112. PyObject* obj = ManagedHeap__gcnew(heap, type, slots, udsize);
  113. out->type = type;
  114. out->is_ptr = true;
  115. out->_obj = obj;
  116. return PyObject__userdata(obj);
  117. }