strname.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include "pocketpy/common/strname.h"
  2. #include "pocketpy/common/smallmap.h"
  3. #include "pocketpy/common/utils.h"
  4. #include "pocketpy/common/vector.h"
  5. #include <stdio.h>
  6. // TODO: use a more efficient data structure
  7. static c11_smallmap_s2n _interned;
  8. static c11_vector/*T=char* */ _r_interned;
  9. static bool _initialized = false;
  10. void pkpy_StrName__initialize(){
  11. if(_initialized) return;
  12. c11_smallmap_s2n__ctor(&_interned);
  13. for(int i=0; i<_r_interned.count; i++){
  14. free(c11__at(char*, &_r_interned, i));
  15. }
  16. c11_vector__ctor(&_r_interned, sizeof(c11_string));
  17. _initialized = true;
  18. // unary operators
  19. __repr__ = pkpy_StrName__map("__repr__");
  20. __str__ = pkpy_StrName__map("__str__");
  21. __hash__ = pkpy_StrName__map("__hash__");
  22. __len__ = pkpy_StrName__map("__len__");
  23. __iter__ = pkpy_StrName__map("__iter__");
  24. __next__ = pkpy_StrName__map("__next__");
  25. __neg__ = pkpy_StrName__map("__neg__");
  26. // logical operators
  27. __eq__ = pkpy_StrName__map("__eq__");
  28. __lt__ = pkpy_StrName__map("__lt__");
  29. __le__ = pkpy_StrName__map("__le__");
  30. __gt__ = pkpy_StrName__map("__gt__");
  31. __ge__ = pkpy_StrName__map("__ge__");
  32. __contains__ = pkpy_StrName__map("__contains__");
  33. // binary operators
  34. __add__ = pkpy_StrName__map("__add__");
  35. __radd__ = pkpy_StrName__map("__radd__");
  36. __sub__ = pkpy_StrName__map("__sub__");
  37. __rsub__ = pkpy_StrName__map("__rsub__");
  38. __mul__ = pkpy_StrName__map("__mul__");
  39. __rmul__ = pkpy_StrName__map("__rmul__");
  40. __truediv__ = pkpy_StrName__map("__truediv__");
  41. __floordiv__ = pkpy_StrName__map("__floordiv__");
  42. __mod__ = pkpy_StrName__map("__mod__");
  43. __pow__ = pkpy_StrName__map("__pow__");
  44. __matmul__ = pkpy_StrName__map("__matmul__");
  45. __lshift__ = pkpy_StrName__map("__lshift__");
  46. __rshift__ = pkpy_StrName__map("__rshift__");
  47. __and__ = pkpy_StrName__map("__and__");
  48. __or__ = pkpy_StrName__map("__or__");
  49. __xor__ = pkpy_StrName__map("__xor__");
  50. __invert__ = pkpy_StrName__map("__invert__");
  51. // indexer
  52. __getitem__ = pkpy_StrName__map("__getitem__");
  53. __setitem__ = pkpy_StrName__map("__setitem__");
  54. __delitem__ = pkpy_StrName__map("__delitem__");
  55. // specials
  56. __new__ = pkpy_StrName__map("__new__");
  57. __init__ = pkpy_StrName__map("__init__");
  58. __call__ = pkpy_StrName__map("__call__");
  59. __divmod__ = pkpy_StrName__map("__divmod__");
  60. __enter__ = pkpy_StrName__map("__enter__");
  61. __exit__ = pkpy_StrName__map("__exit__");
  62. __name__ = pkpy_StrName__map("__name__");
  63. __all__ = pkpy_StrName__map("__all__");
  64. __package__ = pkpy_StrName__map("__package__");
  65. __path__ = pkpy_StrName__map("__path__");
  66. __class__ = pkpy_StrName__map("__class__");
  67. __missing__ = pkpy_StrName__map("__missing__");
  68. pk_id_add = pkpy_StrName__map("add");
  69. pk_id_set = pkpy_StrName__map("set");
  70. pk_id_long = pkpy_StrName__map("long");
  71. pk_id_complex = pkpy_StrName__map("complex");
  72. }
  73. void pkpy_StrName__finalize(){
  74. if(!_initialized) return;
  75. c11_smallmap_s2n__dtor(&_interned);
  76. c11_vector__dtor(&_r_interned);
  77. }
  78. uint16_t pkpy_StrName__map(const char* name){
  79. return pkpy_StrName__map2((c11_string){name, strlen(name)});
  80. }
  81. uint16_t pkpy_StrName__map2(c11_string name){
  82. // TODO: PK_GLOBAL_SCOPE_LOCK()
  83. if(!_initialized){
  84. pkpy_StrName__initialize(); // lazy init
  85. }
  86. uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0);
  87. if(index != 0) return index;
  88. // generate new index
  89. if(_interned.count > 65530){
  90. PK_FATAL_ERROR("StrName index overflow\n");
  91. }
  92. // NOTE: we must allocate the string in the heap so iterators are not invalidated
  93. char* p = malloc(name.size + 1);
  94. memcpy(p, name.data, name.size);
  95. p[name.size] = '\0';
  96. c11_vector__push(char*, &_r_interned, p);
  97. index = _r_interned.count; // 1-based
  98. // save to _interned
  99. c11_smallmap_s2n__set(&_interned, (c11_string){p, name.size}, index);
  100. assert(_interned.count == _r_interned.count);
  101. return index;
  102. }
  103. const char* pkpy_StrName__rmap(uint16_t index){
  104. assert(_initialized);
  105. assert(index > 0 && index <= _interned.count);
  106. return c11__getitem(char*, &_r_interned, index - 1);
  107. }
  108. // unary operators
  109. uint16_t __repr__;
  110. uint16_t __str__;
  111. uint16_t __hash__;
  112. uint16_t __len__;
  113. uint16_t __iter__;
  114. uint16_t __next__;
  115. uint16_t __neg__;
  116. // logical operators
  117. uint16_t __eq__;
  118. uint16_t __lt__;
  119. uint16_t __le__;
  120. uint16_t __gt__;
  121. uint16_t __ge__;
  122. uint16_t __contains__;
  123. // binary operators
  124. uint16_t __add__;
  125. uint16_t __radd__;
  126. uint16_t __sub__;
  127. uint16_t __rsub__;
  128. uint16_t __mul__;
  129. uint16_t __rmul__;
  130. uint16_t __truediv__;
  131. uint16_t __floordiv__;
  132. uint16_t __mod__;
  133. uint16_t __pow__;
  134. uint16_t __matmul__;
  135. uint16_t __lshift__;
  136. uint16_t __rshift__;
  137. uint16_t __and__;
  138. uint16_t __or__;
  139. uint16_t __xor__;
  140. uint16_t __invert__;
  141. // indexer
  142. uint16_t __getitem__;
  143. uint16_t __setitem__;
  144. uint16_t __delitem__;
  145. // specials
  146. uint16_t __new__;
  147. uint16_t __init__;
  148. uint16_t __call__;
  149. uint16_t __divmod__;
  150. uint16_t __enter__;
  151. uint16_t __exit__;
  152. uint16_t __name__;
  153. uint16_t __all__;
  154. uint16_t __package__;
  155. uint16_t __path__;
  156. uint16_t __class__;
  157. uint16_t __missing__;
  158. uint16_t pk_id_add;
  159. uint16_t pk_id_set;
  160. uint16_t pk_id_long;
  161. uint16_t pk_id_complex;