tpy-lang 0.3.0.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. tpy_lang-0.3.0.dev0.dist-info/METADATA +151 -0
  2. tpy_lang-0.3.0.dev0.dist-info/RECORD +333 -0
  3. tpy_lang-0.3.0.dev0.dist-info/WHEEL +4 -0
  4. tpy_lang-0.3.0.dev0.dist-info/entry_points.txt +3 -0
  5. tpyc/__init__.py +104 -0
  6. tpyc/__main__.py +6 -0
  7. tpyc/_buildinfo.py +1 -0
  8. tpyc/_data/docs/LANGUAGE_FEATURES.md +6278 -0
  9. tpyc/_data/docs/STDLIB_ROADMAP.md +1258 -0
  10. tpyc/_data/docs/TPY_FOR_AGENTS.md +556 -0
  11. tpyc/_data/lib/tpy/_bindings/__init__.py +6 -0
  12. tpyc/_data/lib/tpy/_bindings/pcre2.py +173 -0
  13. tpyc/_data/lib/tpy/_bindings/posix_socket.py +161 -0
  14. tpyc/_data/lib/tpy/_functools_macros.py +80 -0
  15. tpyc/_data/lib/tpy/_macro_helpers.py +161 -0
  16. tpyc/_data/lib/tpy/argparse.py +2062 -0
  17. tpyc/_data/lib/tpy/asyncio/__init__.py +744 -0
  18. tpyc/_data/lib/tpy/asyncio/_executor.py +515 -0
  19. tpyc/_data/lib/tpy/base64.py +410 -0
  20. tpyc/_data/lib/tpy/bisect.py +39 -0
  21. tpyc/_data/lib/tpy/builtins.py +38 -0
  22. tpyc/_data/lib/tpy/dataclasses.py +354 -0
  23. tpyc/_data/lib/tpy/enum.py +23 -0
  24. tpyc/_data/lib/tpy/functools.py +33 -0
  25. tpyc/_data/lib/tpy/hashlib.py +206 -0
  26. tpyc/_data/lib/tpy/heapq.py +118 -0
  27. tpyc/_data/lib/tpy/io.py +395 -0
  28. tpyc/_data/lib/tpy/json.py +221 -0
  29. tpyc/_data/lib/tpy/math.py +406 -0
  30. tpyc/_data/lib/tpy/random.py +597 -0
  31. tpyc/_data/lib/tpy/re.py +467 -0
  32. tpyc/_data/lib/tpy/socket.py +379 -0
  33. tpyc/_data/lib/tpy/struct.py +178 -0
  34. tpyc/_data/lib/tpy/sys.py +40 -0
  35. tpyc/_data/lib/tpy/time.py +39 -0
  36. tpyc/_data/lib/tpy/tpy/__init__.py +78 -0
  37. tpyc/_data/lib/tpy/tpy/_bootstrap/__init__.py +10 -0
  38. tpyc/_data/lib/tpy/tpy/_bootstrap/_decorators.py +37 -0
  39. tpyc/_data/lib/tpy/tpy/_bootstrap/_extern.py +64 -0
  40. tpyc/_data/lib/tpy/tpy/_builtins/__init__.py +11 -0
  41. tpyc/_data/lib/tpy/tpy/_builtins/_bytes.py +378 -0
  42. tpyc/_data/lib/tpy/tpy/_builtins/_dict.py +151 -0
  43. tpyc/_data/lib/tpy/tpy/_builtins/_exceptions.py +125 -0
  44. tpyc/_data/lib/tpy/tpy/_builtins/_funcs.py +681 -0
  45. tpyc/_data/lib/tpy/tpy/_builtins/_io.py +97 -0
  46. tpyc/_data/lib/tpy/tpy/_builtins/_list.py +127 -0
  47. tpyc/_data/lib/tpy/tpy/_builtins/_range.py +52 -0
  48. tpyc/_data/lib/tpy/tpy/_builtins/_set.py +139 -0
  49. tpyc/_data/lib/tpy/tpy/_builtins/_super.py +11 -0
  50. tpyc/_data/lib/tpy/tpy/_builtins/_types.py +661 -0
  51. tpyc/_data/lib/tpy/tpy/_core/__init__.py +23 -0
  52. tpyc/_data/lib/tpy/tpy/_core/_bytes_view.py +129 -0
  53. tpyc/_data/lib/tpy/tpy/_core/_containers.py +137 -0
  54. tpyc/_data/lib/tpy/tpy/_core/_functions.py +40 -0
  55. tpyc/_data/lib/tpy/tpy/_core/_types.py +2061 -0
  56. tpyc/_data/lib/tpy/tpy/_typing/__init__.py +77 -0
  57. tpyc/_data/lib/tpy/tpy/_version.py +29 -0
  58. tpyc/_data/lib/tpy/tpy/bits.py +28 -0
  59. tpyc/_data/lib/tpy/tpy/coro/__init__.py +127 -0
  60. tpyc/_data/lib/tpy/tpy/extern.py +8 -0
  61. tpyc/_data/lib/tpy/tpy/mem.py +49 -0
  62. tpyc/_data/lib/tpy/tpy/unsafe.py +195 -0
  63. tpyc/_data/lib/tpy/tpy/version.py +21 -0
  64. tpyc/_data/lib/tpy/typing.py +13 -0
  65. tpyc/_data/runtime/cpp/include/tpy/any.hpp +461 -0
  66. tpyc/_data/runtime/cpp/include/tpy/as_ostream.hpp +117 -0
  67. tpyc/_data/runtime/cpp/include/tpy/async.hpp +76 -0
  68. tpyc/_data/runtime/cpp/include/tpy/bigint.hpp +1343 -0
  69. tpyc/_data/runtime/cpp/include/tpy/builtins.hpp +400 -0
  70. tpyc/_data/runtime/cpp/include/tpy/bytes_ops.hpp +469 -0
  71. tpyc/_data/runtime/cpp/include/tpy/container_ops.hpp +487 -0
  72. tpyc/_data/runtime/cpp/include/tpy/copy_iter.hpp +82 -0
  73. tpyc/_data/runtime/cpp/include/tpy/core.hpp +558 -0
  74. tpyc/_data/runtime/cpp/include/tpy/dict_ops.hpp +289 -0
  75. tpyc/_data/runtime/cpp/include/tpy/dunder.hpp +750 -0
  76. tpyc/_data/runtime/cpp/include/tpy/dynamic.hpp +44 -0
  77. tpyc/_data/runtime/cpp/include/tpy/enum.hpp +40 -0
  78. tpyc/_data/runtime/cpp/include/tpy/file.hpp +245 -0
  79. tpyc/_data/runtime/cpp/include/tpy/fixed_int.hpp +317 -0
  80. tpyc/_data/runtime/cpp/include/tpy/format.hpp +954 -0
  81. tpyc/_data/runtime/cpp/include/tpy/frame_slot.hpp +120 -0
  82. tpyc/_data/runtime/cpp/include/tpy/generator.hpp +47 -0
  83. tpyc/_data/runtime/cpp/include/tpy/iterable_ops.hpp +122 -0
  84. tpyc/_data/runtime/cpp/include/tpy/itertools.hpp +749 -0
  85. tpyc/_data/runtime/cpp/include/tpy/next_iter.hpp +82 -0
  86. tpyc/_data/runtime/cpp/include/tpy/ordered_map.hpp +518 -0
  87. tpyc/_data/runtime/cpp/include/tpy/ordered_set.hpp +337 -0
  88. tpyc/_data/runtime/cpp/include/tpy/own_iter.hpp +54 -0
  89. tpyc/_data/runtime/cpp/include/tpy/pascal_graph_sdl.hpp +192 -0
  90. tpyc/_data/runtime/cpp/include/tpy/printing.hpp +302 -0
  91. tpyc/_data/runtime/cpp/include/tpy/protocols.hpp +61 -0
  92. tpyc/_data/runtime/cpp/include/tpy/range.hpp +115 -0
  93. tpyc/_data/runtime/cpp/include/tpy/ranges.hpp +212 -0
  94. tpyc/_data/runtime/cpp/include/tpy/set_ops.hpp +265 -0
  95. tpyc/_data/runtime/cpp/include/tpy/slice.hpp +47 -0
  96. tpyc/_data/runtime/cpp/include/tpy/span_iter.hpp +42 -0
  97. tpyc/_data/runtime/cpp/include/tpy/stdlib/math.hpp +41 -0
  98. tpyc/_data/runtime/cpp/include/tpy/stdlib/pcre2_h.hpp +96 -0
  99. tpyc/_data/runtime/cpp/include/tpy/stdlib/random.hpp +25 -0
  100. tpyc/_data/runtime/cpp/include/tpy/stdlib/socket_h.hpp +145 -0
  101. tpyc/_data/runtime/cpp/include/tpy/stdlib/time.hpp +62 -0
  102. tpyc/_data/runtime/cpp/include/tpy/system.hpp +121 -0
  103. tpyc/_data/runtime/cpp/include/tpy/throwable.hpp +55 -0
  104. tpyc/_data/runtime/cpp/include/tpy/tpy.hpp +156 -0
  105. tpyc/_data/runtime/cpp/include/tpy/type_name.hpp +77 -0
  106. tpyc/_data/runtime/cpp/include/tpy/type_traits.hpp +240 -0
  107. tpyc/_data/runtime/cpp/include/tpy/uninit_array_storage.hpp +250 -0
  108. tpyc/_data/runtime/cpp/include/tpy/uninit_heap_storage.hpp +277 -0
  109. tpyc/_data/runtime/cpp/include/tpy/varargs.hpp +174 -0
  110. tpyc/_data/runtime/cpp/include/tpy/variant_ref.hpp +118 -0
  111. tpyc/_data/runtime/cpp/src/stdlib/socket_impl.cpp +104 -0
  112. tpyc/_data/runtime/cpp/third_party/README.md +58 -0
  113. tpyc/_data/runtime/cpp/third_party/pcre2/AUTHORS +36 -0
  114. tpyc/_data/runtime/cpp/third_party/pcre2/CMakeLists.txt +1233 -0
  115. tpyc/_data/runtime/cpp/third_party/pcre2/COPYING +5 -0
  116. tpyc/_data/runtime/cpp/third_party/pcre2/ChangeLog +3097 -0
  117. tpyc/_data/runtime/cpp/third_party/pcre2/HACKING +853 -0
  118. tpyc/_data/runtime/cpp/third_party/pcre2/INSTALL +368 -0
  119. tpyc/_data/runtime/cpp/third_party/pcre2/LICENCE +94 -0
  120. tpyc/_data/runtime/cpp/third_party/pcre2/NEWS +492 -0
  121. tpyc/_data/runtime/cpp/third_party/pcre2/NON-AUTOTOOLS-BUILD +430 -0
  122. tpyc/_data/runtime/cpp/third_party/pcre2/README +956 -0
  123. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/COPYING-CMAKE-SCRIPTS +22 -0
  124. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindEditline.cmake +16 -0
  125. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindPackageHandleStandardArgs.cmake +58 -0
  126. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindReadline.cmake +29 -0
  127. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config-version.cmake.in +15 -0
  128. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config.cmake.in +148 -0
  129. tpyc/_data/runtime/cpp/third_party/pcre2/config-cmake.h.in +56 -0
  130. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-16.pc.in +13 -0
  131. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-32.pc.in +13 -0
  132. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-8.pc.in +13 -0
  133. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-posix.pc.in +13 -0
  134. tpyc/_data/runtime/cpp/third_party/pcre2/pcre2-config.in +121 -0
  135. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h +483 -0
  136. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.generic +483 -0
  137. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.in +460 -0
  138. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h +1010 -0
  139. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.generic +1010 -0
  140. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.in +1010 -0
  141. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_auto_possess.c +1371 -0
  142. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c +196 -0
  143. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c.dist +196 -0
  144. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chkdint.c +96 -0
  145. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_compile.c +11001 -0
  146. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_config.c +252 -0
  147. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_context.c +510 -0
  148. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_convert.c +1189 -0
  149. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dfa_match.c +4119 -0
  150. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dftables.c +297 -0
  151. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_error.c +345 -0
  152. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_extuni.c +162 -0
  153. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_find_bracket.c +219 -0
  154. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_fuzzsupport.c +792 -0
  155. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_internal.h +2084 -0
  156. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_intmodedep.h +940 -0
  157. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_compile.c +14972 -0
  158. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_match.c +200 -0
  159. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_misc.c +234 -0
  160. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_neon_inc.h +354 -0
  161. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_simd_inc.h +2355 -0
  162. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_test.c +2528 -0
  163. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_maketables.c +165 -0
  164. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match.c +7777 -0
  165. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match_data.c +185 -0
  166. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_newline.c +243 -0
  167. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ord2utf.c +120 -0
  168. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_pattern_info.c +432 -0
  169. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_printint.c +886 -0
  170. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_script_run.c +344 -0
  171. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_serialize.c +286 -0
  172. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_string_utils.c +237 -0
  173. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_study.c +1915 -0
  174. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substitute.c +1009 -0
  175. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substring.c +550 -0
  176. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_tables.c +234 -0
  177. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucd.c +5460 -0
  178. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucp.h +396 -0
  179. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucptables.c +1533 -0
  180. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_valid_utf.c +398 -0
  181. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_xclass.c +308 -0
  182. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2demo.c +497 -0
  183. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2grep.c +4606 -0
  184. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.c +425 -0
  185. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.h +187 -0
  186. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix_test.c +209 -0
  187. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2test.c +9708 -0
  188. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c +137 -0
  189. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c +327 -0
  190. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c +89 -0
  191. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c +62 -0
  192. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c +40 -0
  193. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c +72 -0
  194. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c +172 -0
  195. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c +141 -0
  196. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c +102 -0
  197. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfig.h +142 -0
  198. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigCPU.h +188 -0
  199. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigInternal.h +907 -0
  200. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.c +3561 -0
  201. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.h +2466 -0
  202. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_32.c +4636 -0
  203. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_64.c +3491 -0
  204. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_T2_32.c +4302 -0
  205. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeLOONGARCH_64.c +3765 -0
  206. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_32.c +472 -0
  207. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_64.c +387 -0
  208. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_common.c +4259 -0
  209. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_32.c +485 -0
  210. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_64.c +719 -0
  211. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_common.c +3161 -0
  212. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_32.c +142 -0
  213. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_64.c +222 -0
  214. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_common.c +3121 -0
  215. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeS390X.c +4526 -0
  216. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_32.c +1685 -0
  217. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_64.c +1398 -0
  218. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_common.c +5001 -0
  219. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitSerialize.c +516 -0
  220. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitUtils.c +344 -0
  221. tpyc/_data/runtime/cpp/third_party/pcre2.sources.txt +54 -0
  222. tpyc/_data/runtime/cpp/third_party/pcre2.vendor.json +7 -0
  223. tpyc/build/__init__.py +7 -0
  224. tpyc/build/pcre2.py +122 -0
  225. tpyc/build/third_party.py +413 -0
  226. tpyc/cli.py +822 -0
  227. tpyc/codegen_cpp/__init__.py +18 -0
  228. tpyc/codegen_cpp/builtins.py +484 -0
  229. tpyc/codegen_cpp/context.py +2064 -0
  230. tpyc/codegen_cpp/expressions.py +5940 -0
  231. tpyc/codegen_cpp/functions.py +1913 -0
  232. tpyc/codegen_cpp/gen_async.py +3258 -0
  233. tpyc/codegen_cpp/gen_generators.py +657 -0
  234. tpyc/codegen_cpp/generator.py +2258 -0
  235. tpyc/codegen_cpp/match.py +1997 -0
  236. tpyc/codegen_cpp/param_const.py +172 -0
  237. tpyc/codegen_cpp/protocols.py +907 -0
  238. tpyc/codegen_cpp/records.py +1654 -0
  239. tpyc/codegen_cpp/resumable_cfg.py +1651 -0
  240. tpyc/codegen_cpp/statements.py +4963 -0
  241. tpyc/codegen_cpp/string_dispatch.py +76 -0
  242. tpyc/codegen_cpp/test_context.py +46 -0
  243. tpyc/codegen_cpp/test_param_const.py +113 -0
  244. tpyc/codegen_cpp/test_resumable_cfg.py +182 -0
  245. tpyc/codegen_cpp/type_resolution.py +53 -0
  246. tpyc/codegen_cpp/types.py +436 -0
  247. tpyc/codegen_cpp/variant_access.py +135 -0
  248. tpyc/coercions.py +749 -0
  249. tpyc/compilation_context.py +57 -0
  250. tpyc/compiler.py +3945 -0
  251. tpyc/cycle_detection.py +358 -0
  252. tpyc/diagnostics.py +135 -0
  253. tpyc/dump_types.py +353 -0
  254. tpyc/frontend_diagnostics.py +47 -0
  255. tpyc/frontend_ir/__init__.py +140 -0
  256. tpyc/frontend_ir/lower.py +1098 -0
  257. tpyc/frontend_ir/nodes.py +718 -0
  258. tpyc/frontend_ir/resolver_adapter.py +151 -0
  259. tpyc/frontend_plugin.py +209 -0
  260. tpyc/install_docs.py +81 -0
  261. tpyc/liveness.py +756 -0
  262. tpyc/macro_api.py +1724 -0
  263. tpyc/macro_loader.py +497 -0
  264. tpyc/module_names.py +64 -0
  265. tpyc/modules/__init__.py +31 -0
  266. tpyc/modules/defs.py +89 -0
  267. tpyc/modules/registry.py +36 -0
  268. tpyc/modules/resolver.py +192 -0
  269. tpyc/modules/type_resolution.py +629 -0
  270. tpyc/namespace.py +172 -0
  271. tpyc/parse/__init__.py +84 -0
  272. tpyc/parse/imports.py +490 -0
  273. tpyc/parse/nodes.py +1732 -0
  274. tpyc/parse/parser.py +4043 -0
  275. tpyc/parse/resolve_refs.py +466 -0
  276. tpyc/parse/type_resolver.py +1060 -0
  277. tpyc/prescan.py +254 -0
  278. tpyc/qnames.py +149 -0
  279. tpyc/repl.py +529 -0
  280. tpyc/repl_backends.py +848 -0
  281. tpyc/sema/__init__.py +21 -0
  282. tpyc/sema/analyzer.py +3625 -0
  283. tpyc/sema/bound_check.py +72 -0
  284. tpyc/sema/builder_trace.py +684 -0
  285. tpyc/sema/calls.py +5406 -0
  286. tpyc/sema/compatibility.py +2107 -0
  287. tpyc/sema/context.py +1243 -0
  288. tpyc/sema/expressions.py +3737 -0
  289. tpyc/sema/flow_facts.py +199 -0
  290. tpyc/sema/init_tracker.py +150 -0
  291. tpyc/sema/list_literals.py +69 -0
  292. tpyc/sema/literal_utils.py +27 -0
  293. tpyc/sema/local_deduction.py +1088 -0
  294. tpyc/sema/macros.py +179 -0
  295. tpyc/sema/match.py +1177 -0
  296. tpyc/sema/method_expansion.py +347 -0
  297. tpyc/sema/methods.py +2197 -0
  298. tpyc/sema/mutation_propagation.py +268 -0
  299. tpyc/sema/narrowing.py +857 -0
  300. tpyc/sema/numeric_lattice.py +160 -0
  301. tpyc/sema/operators.py +402 -0
  302. tpyc/sema/overloads.py +841 -0
  303. tpyc/sema/protocols.py +1209 -0
  304. tpyc/sema/reach_analysis.py +202 -0
  305. tpyc/sema/registration.py +3156 -0
  306. tpyc/sema/scope_tracker.py +193 -0
  307. tpyc/sema/statements.py +4426 -0
  308. tpyc/sema/type_ops.py +1879 -0
  309. tpyc/sema/value_range.py +181 -0
  310. tpyc/symbol_binding.py +259 -0
  311. tpyc/test_c3_mro.py +208 -0
  312. tpyc/test_cli_argv.py +52 -0
  313. tpyc/test_compiler.py +559 -0
  314. tpyc/test_contains_type_param.py +101 -0
  315. tpyc/test_cycle_detection.py +221 -0
  316. tpyc/test_dump_types.py +225 -0
  317. tpyc/test_install_docs.py +65 -0
  318. tpyc/test_local_cpp_form.py +135 -0
  319. tpyc/test_macro_loader.py +76 -0
  320. tpyc/test_method_expansion.py +254 -0
  321. tpyc/test_nominal_identity.py +182 -0
  322. tpyc/test_overloads.py +410 -0
  323. tpyc/test_parse.py +303 -0
  324. tpyc/test_parse_type_ref.py +506 -0
  325. tpyc/test_parse_version_info.py +58 -0
  326. tpyc/test_reach_analysis.py +72 -0
  327. tpyc/test_ref_type.py +216 -0
  328. tpyc/test_send_sync_substitution.py +276 -0
  329. tpyc/test_tuple_mutation_propagation.py +206 -0
  330. tpyc/test_type_def_registry.py +1729 -0
  331. tpyc/test_union_types.py +195 -0
  332. tpyc/type_def_registry.py +975 -0
  333. tpyc/typesys.py +5104 -0
@@ -0,0 +1,265 @@
1
+ /**
2
+ * TurboPython Runtime - Set Operations
3
+ *
4
+ * Set-specific helpers: remove (panicking), pop, set algebra operations,
5
+ * constructors from iterables, and SetPrinter.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <cstdint>
11
+ #include <iostream>
12
+ #include <ranges>
13
+ #include <sstream>
14
+
15
+ #include "core.hpp"
16
+ #include "next_iter.hpp"
17
+ #include "ordered_set.hpp"
18
+ #include "printing.hpp"
19
+
20
+ namespace tpy {
21
+
22
+ // -- Constructors -----------------------------------------------------------
23
+
24
+ // set(native_iterable) -- construct from range
25
+ template<typename T, std::ranges::input_range R>
26
+ ordered_set<T> set_from_range(R&& range) {
27
+ ordered_set<T> result;
28
+ for (auto&& elem : range) {
29
+ result.insert(elem);
30
+ }
31
+ return result;
32
+ }
33
+
34
+ // set(iterator) -- construct from user-defined iterator
35
+ template<typename T, typename Iter>
36
+ ordered_set<T> set_collect(Iter&& iter) {
37
+ ordered_set<T> result;
38
+ for (;;) {
39
+ auto __r = iter.__next__();
40
+ if (!__r.has_value()) break;
41
+ result.insert(unwrap_ref(*__r));
42
+ }
43
+ return result;
44
+ }
45
+
46
+ // set_construct -- unified set construction from any iterable.
47
+ // Uses begin/end for std::ranges::input_range, __next__() otherwise.
48
+ template<typename T, typename Arg>
49
+ ordered_set<T> set_construct(Arg&& arg) {
50
+ if constexpr (std::ranges::input_range<std::remove_cvref_t<Arg>>) {
51
+ return set_from_range<T>(std::forward<Arg>(arg));
52
+ } else {
53
+ return set_collect<T>(std::forward<Arg>(arg));
54
+ }
55
+ }
56
+
57
+ // -- Copy -------------------------------------------------------------------
58
+
59
+ template<typename T>
60
+ ordered_set<T> set_copy(const ordered_set<T>& s) {
61
+ return ordered_set<T>(s);
62
+ }
63
+
64
+ // -- Methods ----------------------------------------------------------------
65
+
66
+ // s.remove(value) -- throws KeyError if not present
67
+ template<typename T>
68
+ void set_remove(ordered_set<T>& s, const T& value) {
69
+ if (!s.erase(value)) {
70
+ raise_key_error("KeyError");
71
+ }
72
+ }
73
+
74
+ // s.pop() -- remove and return first element (insertion order); throws KeyError if empty
75
+ template<typename T>
76
+ T set_pop(ordered_set<T>& s) {
77
+ if (s.empty()) {
78
+ raise_key_error("pop from an empty set");
79
+ }
80
+ T result = s.front();
81
+ s.pop_front();
82
+ return result;
83
+ }
84
+
85
+ // -- Set algebra ------------------------------------------------------------
86
+
87
+ template<typename T>
88
+ ordered_set<T> set_union(const ordered_set<T>& a, const ordered_set<T>& b) {
89
+ ordered_set<T> result(a);
90
+ for (auto& v : b) {
91
+ result.insert(v);
92
+ }
93
+ return result;
94
+ }
95
+
96
+ template<typename T>
97
+ ordered_set<T> set_intersection(const ordered_set<T>& a, const ordered_set<T>& b) {
98
+ ordered_set<T> result;
99
+ for (auto& v : a) {
100
+ if (b.contains(v)) result.insert(v);
101
+ }
102
+ return result;
103
+ }
104
+
105
+ template<typename T>
106
+ ordered_set<T> set_difference(const ordered_set<T>& a, const ordered_set<T>& b) {
107
+ ordered_set<T> result;
108
+ for (auto& v : a) {
109
+ if (!b.contains(v)) result.insert(v);
110
+ }
111
+ return result;
112
+ }
113
+
114
+ template<typename T>
115
+ ordered_set<T> set_symmetric_difference(const ordered_set<T>& a, const ordered_set<T>& b) {
116
+ ordered_set<T> result;
117
+ for (auto& v : a) {
118
+ if (!b.contains(v)) result.insert(v);
119
+ }
120
+ for (auto& v : b) {
121
+ if (!a.contains(v)) result.insert(v);
122
+ }
123
+ return result;
124
+ }
125
+
126
+ template<typename T>
127
+ bool set_issubset(const ordered_set<T>& a, const ordered_set<T>& b) {
128
+ if (a.size() > b.size()) return false;
129
+ for (auto& v : a) {
130
+ if (!b.contains(v)) return false;
131
+ }
132
+ return true;
133
+ }
134
+
135
+ template<typename T>
136
+ bool set_issuperset(const ordered_set<T>& a, const ordered_set<T>& b) {
137
+ return set_issubset(b, a);
138
+ }
139
+
140
+ template<typename T>
141
+ bool set_strict_subset(const ordered_set<T>& a, const ordered_set<T>& b) {
142
+ return a.size() < b.size() && set_issubset(a, b);
143
+ }
144
+
145
+ template<typename T>
146
+ bool set_strict_superset(const ordered_set<T>& a, const ordered_set<T>& b) {
147
+ return a.size() > b.size() && set_issubset(b, a);
148
+ }
149
+
150
+ template<typename T>
151
+ bool set_isdisjoint(const ordered_set<T>& a, const ordered_set<T>& b) {
152
+ const auto& smaller = (a.size() <= b.size()) ? a : b;
153
+ const auto& larger = (a.size() <= b.size()) ? b : a;
154
+ for (auto& v : smaller) {
155
+ if (larger.contains(v)) return false;
156
+ }
157
+ return true;
158
+ }
159
+
160
+ // -- In-place updates -------------------------------------------------------
161
+
162
+ template<typename T>
163
+ void set_update(ordered_set<T>& s, const ordered_set<T>& other) {
164
+ for (auto& v : other) {
165
+ s.insert(v);
166
+ }
167
+ }
168
+
169
+ template<typename T>
170
+ void set_intersection_update(ordered_set<T>& s, const ordered_set<T>& other) {
171
+ ordered_set<T> result;
172
+ for (auto& v : s) {
173
+ if (other.contains(v)) result.insert(v);
174
+ }
175
+ s = std::move(result);
176
+ }
177
+
178
+ template<typename T>
179
+ void set_difference_update(ordered_set<T>& s, const ordered_set<T>& other) {
180
+ if (&s == &other) { s.clear(); return; }
181
+ for (auto& v : other) {
182
+ s.erase(v);
183
+ }
184
+ }
185
+
186
+ template<typename T>
187
+ void set_symmetric_difference_update(ordered_set<T>& s, const ordered_set<T>& other) {
188
+ if (&s == &other) { s.clear(); return; }
189
+ for (auto& v : other) {
190
+ if (!s.erase(v)) {
191
+ s.insert(v);
192
+ }
193
+ }
194
+ }
195
+
196
+ // -- ordered_set::__iter__() definition (deferred -- needs native_iterator) -
197
+
198
+ template<typename T>
199
+ auto ordered_set<T>::__iter__() const {
200
+ return native_iterator<const_iterator, T>{begin(), end()};
201
+ }
202
+
203
+ // -- Dunder overloads -------------------------------------------------------
204
+
205
+ template<typename T>
206
+ int32_t __len__(const ordered_set<T>& s) {
207
+ return s.size();
208
+ }
209
+
210
+ template<typename T>
211
+ bool __bool__(const ordered_set<T>& s) {
212
+ return !s.empty();
213
+ }
214
+
215
+ // -- Printing ---------------------------------------------------------------
216
+
217
+ namespace detail {
218
+ // Forward declaration -- defined in printing.hpp
219
+ template <typename T> void print_element(std::ostream& os, const T& elem);
220
+ } // namespace detail
221
+
222
+ template<typename T>
223
+ struct SetPrinter {
224
+ const ordered_set<T>& value;
225
+ explicit SetPrinter(const ordered_set<T>& v) : value(v) {}
226
+ };
227
+
228
+ template<typename T>
229
+ std::ostream& operator<<(std::ostream& os, const SetPrinter<T>& p) {
230
+ if (p.value.empty()) {
231
+ return os << "set()";
232
+ }
233
+ os << '{';
234
+ bool first = true;
235
+ for (auto& v : p.value) {
236
+ if (!first) os << ", ";
237
+ first = false;
238
+ detail::print_element(os, v);
239
+ }
240
+ os << '}';
241
+ return os;
242
+ }
243
+
244
+ template<typename T>
245
+ std::string set_to_str(const ordered_set<T>& s) {
246
+ std::ostringstream oss;
247
+ oss << SetPrinter<T>(s);
248
+ return oss.str();
249
+ }
250
+
251
+ // Nested container support
252
+ namespace detail {
253
+ template<typename T>
254
+ void print_element(std::ostream& os, const ordered_set<T>& elem) {
255
+ os << SetPrinter<T>(elem);
256
+ }
257
+ } // namespace detail
258
+
259
+ // ValuePrinter specialization so sets inside generic containers print correctly
260
+ template<typename T>
261
+ std::ostream& operator<<(std::ostream& os, const ValuePrinter<ordered_set<T>>& p) {
262
+ return os << SetPrinter<T>(p.value);
263
+ }
264
+
265
+ } // namespace tpy
@@ -0,0 +1,47 @@
1
+ // tpy::BasicSlice / tpy::Slice -- built-in slice types for subscript ranges.
2
+ // BasicSlice has start/stop only (for a[1:3] syntax).
3
+ // Slice adds step (for a[1:3:2] syntax).
4
+ #pragma once
5
+
6
+ #include <cstdint>
7
+ #include <optional>
8
+ #include <ostream>
9
+
10
+ namespace tpy {
11
+
12
+ struct BasicSlice {
13
+ std::optional<int32_t> start;
14
+ std::optional<int32_t> stop;
15
+ };
16
+
17
+ struct Slice {
18
+ std::optional<int32_t> start;
19
+ std::optional<int32_t> stop;
20
+ std::optional<int32_t> step;
21
+
22
+ Slice() = default;
23
+ Slice(std::optional<int32_t> s, std::optional<int32_t> e, std::optional<int32_t> st)
24
+ : start(s), stop(e), step(st) {}
25
+ // Implicit conversion from BasicSlice (basic_slice coerces to slice)
26
+ Slice(const BasicSlice& bs) : start(bs.start), stop(bs.stop), step(std::nullopt) {}
27
+ };
28
+
29
+ inline std::ostream& operator<<(std::ostream& os, const BasicSlice& s) {
30
+ os << "basic_slice(";
31
+ if (s.start) os << *s.start; else os << "None";
32
+ os << ", ";
33
+ if (s.stop) os << *s.stop; else os << "None";
34
+ return os << ")";
35
+ }
36
+
37
+ inline std::ostream& operator<<(std::ostream& os, const Slice& s) {
38
+ os << "slice(";
39
+ if (s.start) os << *s.start; else os << "None";
40
+ os << ", ";
41
+ if (s.stop) os << *s.stop; else os << "None";
42
+ os << ", ";
43
+ if (s.step) os << *s.step; else os << "None";
44
+ return os << ")";
45
+ }
46
+
47
+ } // namespace tpy
@@ -0,0 +1,42 @@
1
+ /**
2
+ * TurboPython Runtime - SpanIter
3
+ *
4
+ * Lightweight iterator over a contiguous span. Wraps std::span<T> and exposes
5
+ * both C++ range (begin/end) and Iterator (__next__/__iter__) interfaces.
6
+ *
7
+ * SpanIter<T> holds span<T> and yields T& (mutable elements).
8
+ * SpanIter<const T> holds span<const T> and yields const T& (readonly elements).
9
+ * Use SpanIter<const T> when iterating from a const/readonly context.
10
+ */
11
+
12
+ #pragma once
13
+
14
+ #include "core.hpp"
15
+
16
+ #include <expected>
17
+ #include <span>
18
+ #include <type_traits>
19
+
20
+ namespace tpy {
21
+
22
+ template<typename T>
23
+ struct SpanIter {
24
+ std::span<T> span_;
25
+ size_t index_ = 0;
26
+
27
+ explicit SpanIter(std::span<T> s) : span_(s) {}
28
+
29
+ // NativeIterable: zero-cost iteration via begin/end.
30
+ auto begin() const { return span_.begin() + static_cast<std::ptrdiff_t>(index_); }
31
+ auto end() const { return span_.end(); }
32
+
33
+ // Iterator protocol
34
+ std::expected<std::remove_const_t<T>, StopIteration> __next__() {
35
+ if (index_ >= span_.size()) return tpy::make_unexpected(StopIteration{});
36
+ return span_[index_++];
37
+ }
38
+
39
+ SpanIter& __iter__() { return *this; }
40
+ };
41
+
42
+ } // namespace tpy
@@ -0,0 +1,41 @@
1
+ #pragma once
2
+
3
+ #include <cmath>
4
+ #include <cstdint>
5
+ #include <limits>
6
+ #include <tuple>
7
+
8
+ namespace tpy::stdlib::math {
9
+
10
+ inline std::tuple<double, double> modf(double x) {
11
+ double int_part;
12
+ double frac = std::modf(x, &int_part);
13
+ return {frac, int_part};
14
+ }
15
+
16
+ // Exponent template parameter. For IEEE 754 double, std::frexp normalizes
17
+ // |m| to [0.5, 1), so exp is in [-1073, 1024] (the lower bound comes from
18
+ // subnormals: smallest positive denormal is 2^-1074 -> m=0.5, exp=-1073;
19
+ // upper bound from max finite double just under 2^1024). Safely fits in
20
+ // any 16+ bit signed int. Caller picks the int type (defaults to
21
+ // DefaultInt on the Python side); `T(exp)` uses the target's constructor
22
+ // so BigInt also works.
23
+ template<typename T>
24
+ inline std::tuple<double, T> frexp(double x) {
25
+ int exp;
26
+ double m = std::frexp(x, &exp);
27
+ return {m, T(exp)};
28
+ }
29
+
30
+ // Unit in the Last Place: distance to the next representable double > |x|.
31
+ // Matches CPython math.ulp: ulp(nan)=nan, ulp(+-inf)=inf, ulp(0)=smallest
32
+ // subnormal, else nextafter(|x|, inf) - |x|.
33
+ inline double ulp(double x) {
34
+ if (std::isnan(x)) return x;
35
+ if (std::isinf(x)) return std::numeric_limits<double>::infinity();
36
+ if (x == 0.0) return std::numeric_limits<double>::denorm_min();
37
+ double ax = std::fabs(x);
38
+ return std::nextafter(ax, std::numeric_limits<double>::infinity()) - ax;
39
+ }
40
+
41
+ } // namespace tpy::stdlib::math
@@ -0,0 +1,96 @@
1
+ #pragma once
2
+ // Hand-written PCRE2 facade for TPy bindings.
3
+ //
4
+ // We deliberately do NOT `#include <pcre2.h>` here. PCRE2's header
5
+ // `#define`s a large set of `PCRE2_*` macros that would collide with
6
+ // TPy module-level constants of the same name (the preprocessor expands
7
+ // the macro at every TPy `inline constexpr uint32_t PCRE2_CASELESS = ...;`
8
+ // declaration site, producing a syntax error). By instead manually
9
+ // mirroring the symbols and types we need, pcre2.h never enters any
10
+ // TPy-generated translation unit -- its macros never get a chance to fire.
11
+ //
12
+ // All names match upstream pcre2.h exactly and live at global scope (same
13
+ // as the real header), so generated TPy code that references e.g.
14
+ // `pcre2_code_8*` or `PCRE2_SPTR8` resolves directly without any namespace
15
+ // qualification.
16
+ //
17
+ // PCRE2's ABI is stable, so this mirror is low-maintenance. Bumping the
18
+ // vendored PCRE2 version doesn't require touching this file unless the
19
+ // upstream API surface we use changes shape.
20
+ //
21
+ // Linker connects our extern "C" declarations to the symbols defined by
22
+ // the vendored PCRE2 .c files (compiled separately into their own .o
23
+ // files; their TUs include the real pcre2.h).
24
+
25
+ #include <cstddef>
26
+ #include <cstdint>
27
+
28
+ // ---- Type aliases (8-bit code unit) ----
29
+ // Upstream pcre2.h has `typedef size_t PCRE2_SIZE`. We use `std::uint64_t`
30
+ // instead because the TPy bindings (lib/tpy/_bindings/pcre2.py) type the
31
+ // matching pointer params as `Ptr[UInt64]` -- on Linux x86_64 `size_t` and
32
+ // `uint64_t` are both `unsigned long`, but on macOS `size_t` is
33
+ // `unsigned long` while `uint64_t` is `unsigned long long`, so the pointer
34
+ // types don't implicitly convert. Both are 8-byte unsigned on every 64-bit
35
+ // Unix target we support, so this matches PCRE2's actual ABI byte-for-byte;
36
+ // the linker only resolves the `extern "C"` symbol name, not param types.
37
+ using PCRE2_SIZE = std::uint64_t;
38
+ using PCRE2_SPTR8 = const std::uint8_t*;
39
+ using PCRE2_UCHAR8 = std::uint8_t;
40
+
41
+ // ---- Opaque handle types ----
42
+ // Forward declarations only -- we only ever pass pointers around, never
43
+ // dereference or sizeof the underlying structs in TPy-generated code.
44
+ struct pcre2_real_code_8;
45
+ struct pcre2_real_match_data_8;
46
+ struct pcre2_real_match_context_8;
47
+ struct pcre2_real_general_context_8;
48
+ struct pcre2_real_compile_context_8;
49
+
50
+ using pcre2_code_8 = pcre2_real_code_8;
51
+ using pcre2_match_data_8 = pcre2_real_match_data_8;
52
+ using pcre2_match_context_8 = pcre2_real_match_context_8;
53
+ using pcre2_general_context_8 = pcre2_real_general_context_8;
54
+ using pcre2_compile_context_8 = pcre2_real_compile_context_8;
55
+
56
+ // ---- Function declarations ----
57
+ extern "C" {
58
+
59
+ pcre2_code_8* pcre2_compile_8(PCRE2_SPTR8 pattern, PCRE2_SIZE length,
60
+ std::uint32_t options, int* errorcode,
61
+ PCRE2_SIZE* erroffset,
62
+ pcre2_compile_context_8* ccontext);
63
+
64
+ void pcre2_code_free_8(pcre2_code_8* code);
65
+
66
+ int pcre2_jit_compile_8(pcre2_code_8* code, std::uint32_t options);
67
+
68
+ int pcre2_get_error_message_8(int errorcode, PCRE2_UCHAR8* buffer,
69
+ PCRE2_SIZE bufflen);
70
+
71
+ pcre2_match_context_8* pcre2_match_context_create_8(
72
+ pcre2_general_context_8* gcontext);
73
+ void pcre2_match_context_free_8(pcre2_match_context_8* mcontext);
74
+
75
+ pcre2_match_data_8* pcre2_match_data_create_from_pattern_8(
76
+ const pcre2_code_8* code, pcre2_general_context_8* gcontext);
77
+ void pcre2_match_data_free_8(pcre2_match_data_8* md);
78
+
79
+ int pcre2_match_8(const pcre2_code_8* code, PCRE2_SPTR8 subject,
80
+ PCRE2_SIZE length, PCRE2_SIZE startoffset,
81
+ std::uint32_t options, pcre2_match_data_8* match_data,
82
+ pcre2_match_context_8* mcontext);
83
+
84
+ PCRE2_SIZE* pcre2_get_ovector_pointer_8(pcre2_match_data_8* md);
85
+
86
+ int pcre2_pattern_info_8(const pcre2_code_8* code, std::uint32_t what,
87
+ void* where);
88
+
89
+ int pcre2_substitute_8(const pcre2_code_8* code, PCRE2_SPTR8 subject,
90
+ PCRE2_SIZE length, PCRE2_SIZE startoffset,
91
+ std::uint32_t options, pcre2_match_data_8* match_data,
92
+ pcre2_match_context_8* mcontext,
93
+ PCRE2_SPTR8 replacement, PCRE2_SIZE rlength,
94
+ PCRE2_UCHAR8* outputbuffer, PCRE2_SIZE* outlengthptr);
95
+
96
+ } // extern "C"
@@ -0,0 +1,25 @@
1
+ #pragma once
2
+
3
+ #include <cstdint>
4
+ #include <random>
5
+
6
+ namespace tpy::stdlib::random {
7
+
8
+ // Returns a uint32 sourced from the OS entropy pool. Backed by
9
+ // std::random_device, which uses /dev/urandom on Linux, getentropy /
10
+ // arc4random on BSD/macOS, and BCryptGenRandom on Windows. Each call
11
+ // returns fresh entropy; instance is held in a function-local static
12
+ // since opening the entropy source can be expensive on some platforms.
13
+ //
14
+ // Thread safety: C++11 guarantees the static initialization is
15
+ // thread-safe. Concurrent rd() calls are thread-safe in practice on
16
+ // libstdc++ / libc++ / MSVC (all read from OS primitives) but the
17
+ // language standard does not contract this. When TPy gains threading,
18
+ // callers needing multi-thread safety should serialize or construct
19
+ // per-thread Random instances.
20
+ inline uint32_t os_entropy_uint32() {
21
+ static std::random_device rd;
22
+ return rd();
23
+ }
24
+
25
+ } // namespace tpy::stdlib::random
@@ -0,0 +1,145 @@
1
+ #pragma once
2
+ // Hand-written POSIX-sockets facade for TPy bindings.
3
+ //
4
+ // We deliberately do NOT `#include <sys/socket.h>`, `<netinet/in.h>`,
5
+ // `<netdb.h>`, etc. here. Those headers `#define` a large set of macros
6
+ // (`AF_INET`, `SOCK_STREAM`, `SO_REUSEADDR`, ...) that would collide with
7
+ // TPy module-level constants of the same name: the preprocessor would
8
+ // expand `AF_INET` inside a generated `inline constexpr int32_t AF_INET
9
+ // = 2;` declaration, producing a syntax error. By manually mirroring the
10
+ // libc symbols + the one struct we need, the system headers never enter
11
+ // any TPy-generated translation unit.
12
+ //
13
+ // All names match upstream POSIX exactly and live at global scope (same
14
+ // as the real headers), so generated TPy code that references
15
+ // `sockaddr_in` or calls `::socket` resolves directly.
16
+ //
17
+ // sockaddr_in's layout is POSIX-stable (16 bytes, defined field order)
18
+ // across Linux, *BSD, macOS; safe to mirror. struct addrinfo is NOT
19
+ // stable (ai_addr and ai_canonname are swapped on BSD/macOS), which is
20
+ // why we provide `tpy_resolve_ipv4` below -- the helper hides addrinfo
21
+ // entirely behind a flat C signature.
22
+ //
23
+ // Linker connects our extern "C" declarations to the actual libc
24
+ // implementations; no vendoring, no third-party lib.
25
+
26
+ #include <cstddef>
27
+ #include <cstdint>
28
+
29
+ // On macOS, libc's `<sys/_endian.h>` is pulled in transitively by libc++'s
30
+ // base headers (`<cstdint>`, `<string>`, ...) and `#define`s the byte-order
31
+ // helpers as preprocessor macros expanding to inline asm. The macros then
32
+ // fire inside our `extern "C"` decls below and inside any generated code
33
+ // that names them (`::htons(x)` becomes `::((uint16_t)(...))`, a syntax
34
+ // error). Real linker symbols for these helpers exist on every supported
35
+ // platform (Linux glibc/musl, macOS libSystem), so undef'ing the macros
36
+ // here lets us keep the upstream names end-to-end and bind directly.
37
+ #undef htons
38
+ #undef ntohs
39
+ #undef htonl
40
+ #undef ntohl
41
+
42
+ extern "C" {
43
+
44
+ // ---- sockaddr_in (POSIX-stable 16-byte layout) ----
45
+ // Field widths chosen to match struct sockaddr_in on any POSIX system:
46
+ // sa_family_t is 16-bit unsigned;
47
+ // in_port_t is 16-bit unsigned (network order);
48
+ // in_addr.s_addr is 32-bit unsigned (network order);
49
+ // sin_zero is 8 bytes of padding (required for cast-compat with sockaddr).
50
+ struct sockaddr_in {
51
+ std::uint16_t sin_family;
52
+ std::uint16_t sin_port;
53
+ std::uint32_t sin_addr;
54
+ std::uint8_t sin_zero[8];
55
+ };
56
+
57
+ } // extern "C" (close for static_asserts, reopen below)
58
+
59
+ // We `reinterpret_cast<sockaddr*>(&our_sockaddr_in)` at every kernel-boundary
60
+ // call, so the layout must match the system's struct exactly. Any toolchain
61
+ // that inserts padding or reorders fields must fail at compile time, not at
62
+ // runtime where it would silently corrupt addresses.
63
+ static_assert(sizeof(sockaddr_in) == 16,
64
+ "sockaddr_in must be exactly 16 bytes to match POSIX layout");
65
+ static_assert(offsetof(sockaddr_in, sin_family) == 0,
66
+ "sin_family must be at offset 0");
67
+ static_assert(offsetof(sockaddr_in, sin_port) == 2,
68
+ "sin_port must be at offset 2");
69
+ static_assert(offsetof(sockaddr_in, sin_addr) == 4,
70
+ "sin_addr must be at offset 4");
71
+ static_assert(offsetof(sockaddr_in, sin_zero) == 8,
72
+ "sin_zero must be at offset 8");
73
+
74
+ extern "C" {
75
+
76
+ // ---- Raw libc bindings ----
77
+ // sockaddr arguments are declared `void*` to avoid forward-declaring
78
+ // `struct sockaddr` (unused name in TPy land). Pointer ABI is identical.
79
+ // `socklen_t` is `unsigned int` on Linux (glibc + musl), FreeBSD, and
80
+ // macOS -- stable enough to hardcode. `ssize_t` is `long` on every 64-bit
81
+ // *nix target TPy runs on.
82
+
83
+ int socket(int domain, int type, int protocol);
84
+ int bind(int sockfd, const void* addr, unsigned int addrlen);
85
+ int connect(int sockfd, const void* addr, unsigned int addrlen);
86
+ int listen(int sockfd, int backlog);
87
+ int accept(int sockfd, void* addr, unsigned int* addrlen);
88
+ int close(int fd);
89
+ int shutdown(int sockfd, int how);
90
+
91
+ long send(int sockfd, const void* buf, unsigned long len, int flags);
92
+ long recv(int sockfd, void* buf, unsigned long len, int flags);
93
+
94
+ int setsockopt(int sockfd, int level, int optname,
95
+ const void* optval, unsigned int optlen);
96
+ int getsockname(int sockfd, void* addr, unsigned int* addrlen);
97
+ int getpeername(int sockfd, void* addr, unsigned int* addrlen);
98
+ int socketpair(int domain, int type, int protocol, int sv[2]);
99
+
100
+ std::uint16_t htons(std::uint16_t hostshort);
101
+ std::uint16_t ntohs(std::uint16_t netshort);
102
+ // `inet_pton` and `inet_ntop` -- we use uint8_t* instead of char* for the
103
+ // IP-text buffers so TPy bindings can use Ptr[UInt8] naturally (matches
104
+ // the re module's convention for string-like byte buffers). uint8_t* and
105
+ // char* have identical ABI; libc's real decls use char*, linker resolves.
106
+ int inet_pton(int af, const std::uint8_t* src, void* dst);
107
+ std::uint8_t* inet_ntop(int af, const void* src, std::uint8_t* dst,
108
+ unsigned int size);
109
+
110
+ // strerror is intentionally NOT declared here: libc's `char* strerror(int)`
111
+ // is transitively pulled in via `<cstring>` (from tpy.hpp's PCH chain),
112
+ // and declaring a different const-qualification here conflicts. TPy
113
+ // binding references `strerror` directly against the libc decl.
114
+
115
+ // ---- Runtime helpers (implemented in runtime/cpp/src/stdlib/socket_impl.cpp) ----
116
+
117
+ // Resolve a hostname to a single IPv4 address via getaddrinfo().
118
+ // `host` + `host_len` are a non-null-terminated byte span (matches TPy's
119
+ // str = std::string_view convention); the helper copies into a local
120
+ // std::string before calling getaddrinfo. Writes 4 bytes of the first
121
+ // A-record address to `out` in network byte order on success. Returns
122
+ // 0 on success, -1 on failure (caller checks tpy_last_resolve_error()
123
+ // for a human-readable message).
124
+ //
125
+ // Rationale for not exposing getaddrinfo directly: struct addrinfo's
126
+ // field order differs between Linux (ai_addr before ai_canonname) and
127
+ // BSD/macOS (swapped), so we cannot declare it portably at @native level.
128
+ // This helper keeps the struct walking on the C++ side where <netdb.h>
129
+ // is available.
130
+ int tpy_resolve_ipv4(const std::uint8_t* host, std::uint64_t host_len,
131
+ std::uint8_t out[4]);
132
+
133
+ // Returns `errno` at the point of call. Indirection needed because the
134
+ // errno symbol resolves differently per platform (__errno_location on
135
+ // Linux glibc, __error on macOS); the TPy binding shouldn't care.
136
+ int tpy_errno();
137
+
138
+ // Returns a human-readable description of the most recent failure from
139
+ // tpy_resolve_ipv4. Pointer is valid until the next tpy_resolve_ipv4
140
+ // call on the same thread. Used by TPy-side error reporting to turn
141
+ // getaddrinfo errors (EAI_*) into messages via gai_strerror without
142
+ // exposing the error-code namespace.
143
+ const char* tpy_last_resolve_error();
144
+
145
+ } // extern "C"