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.
- tpy_lang-0.3.0.dev0.dist-info/METADATA +151 -0
- tpy_lang-0.3.0.dev0.dist-info/RECORD +333 -0
- tpy_lang-0.3.0.dev0.dist-info/WHEEL +4 -0
- tpy_lang-0.3.0.dev0.dist-info/entry_points.txt +3 -0
- tpyc/__init__.py +104 -0
- tpyc/__main__.py +6 -0
- tpyc/_buildinfo.py +1 -0
- tpyc/_data/docs/LANGUAGE_FEATURES.md +6278 -0
- tpyc/_data/docs/STDLIB_ROADMAP.md +1258 -0
- tpyc/_data/docs/TPY_FOR_AGENTS.md +556 -0
- tpyc/_data/lib/tpy/_bindings/__init__.py +6 -0
- tpyc/_data/lib/tpy/_bindings/pcre2.py +173 -0
- tpyc/_data/lib/tpy/_bindings/posix_socket.py +161 -0
- tpyc/_data/lib/tpy/_functools_macros.py +80 -0
- tpyc/_data/lib/tpy/_macro_helpers.py +161 -0
- tpyc/_data/lib/tpy/argparse.py +2062 -0
- tpyc/_data/lib/tpy/asyncio/__init__.py +744 -0
- tpyc/_data/lib/tpy/asyncio/_executor.py +515 -0
- tpyc/_data/lib/tpy/base64.py +410 -0
- tpyc/_data/lib/tpy/bisect.py +39 -0
- tpyc/_data/lib/tpy/builtins.py +38 -0
- tpyc/_data/lib/tpy/dataclasses.py +354 -0
- tpyc/_data/lib/tpy/enum.py +23 -0
- tpyc/_data/lib/tpy/functools.py +33 -0
- tpyc/_data/lib/tpy/hashlib.py +206 -0
- tpyc/_data/lib/tpy/heapq.py +118 -0
- tpyc/_data/lib/tpy/io.py +395 -0
- tpyc/_data/lib/tpy/json.py +221 -0
- tpyc/_data/lib/tpy/math.py +406 -0
- tpyc/_data/lib/tpy/random.py +597 -0
- tpyc/_data/lib/tpy/re.py +467 -0
- tpyc/_data/lib/tpy/socket.py +379 -0
- tpyc/_data/lib/tpy/struct.py +178 -0
- tpyc/_data/lib/tpy/sys.py +40 -0
- tpyc/_data/lib/tpy/time.py +39 -0
- tpyc/_data/lib/tpy/tpy/__init__.py +78 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/__init__.py +10 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/_decorators.py +37 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/_extern.py +64 -0
- tpyc/_data/lib/tpy/tpy/_builtins/__init__.py +11 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_bytes.py +378 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_dict.py +151 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_exceptions.py +125 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_funcs.py +681 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_io.py +97 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_list.py +127 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_range.py +52 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_set.py +139 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_super.py +11 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_types.py +661 -0
- tpyc/_data/lib/tpy/tpy/_core/__init__.py +23 -0
- tpyc/_data/lib/tpy/tpy/_core/_bytes_view.py +129 -0
- tpyc/_data/lib/tpy/tpy/_core/_containers.py +137 -0
- tpyc/_data/lib/tpy/tpy/_core/_functions.py +40 -0
- tpyc/_data/lib/tpy/tpy/_core/_types.py +2061 -0
- tpyc/_data/lib/tpy/tpy/_typing/__init__.py +77 -0
- tpyc/_data/lib/tpy/tpy/_version.py +29 -0
- tpyc/_data/lib/tpy/tpy/bits.py +28 -0
- tpyc/_data/lib/tpy/tpy/coro/__init__.py +127 -0
- tpyc/_data/lib/tpy/tpy/extern.py +8 -0
- tpyc/_data/lib/tpy/tpy/mem.py +49 -0
- tpyc/_data/lib/tpy/tpy/unsafe.py +195 -0
- tpyc/_data/lib/tpy/tpy/version.py +21 -0
- tpyc/_data/lib/tpy/typing.py +13 -0
- tpyc/_data/runtime/cpp/include/tpy/any.hpp +461 -0
- tpyc/_data/runtime/cpp/include/tpy/as_ostream.hpp +117 -0
- tpyc/_data/runtime/cpp/include/tpy/async.hpp +76 -0
- tpyc/_data/runtime/cpp/include/tpy/bigint.hpp +1343 -0
- tpyc/_data/runtime/cpp/include/tpy/builtins.hpp +400 -0
- tpyc/_data/runtime/cpp/include/tpy/bytes_ops.hpp +469 -0
- tpyc/_data/runtime/cpp/include/tpy/container_ops.hpp +487 -0
- tpyc/_data/runtime/cpp/include/tpy/copy_iter.hpp +82 -0
- tpyc/_data/runtime/cpp/include/tpy/core.hpp +558 -0
- tpyc/_data/runtime/cpp/include/tpy/dict_ops.hpp +289 -0
- tpyc/_data/runtime/cpp/include/tpy/dunder.hpp +750 -0
- tpyc/_data/runtime/cpp/include/tpy/dynamic.hpp +44 -0
- tpyc/_data/runtime/cpp/include/tpy/enum.hpp +40 -0
- tpyc/_data/runtime/cpp/include/tpy/file.hpp +245 -0
- tpyc/_data/runtime/cpp/include/tpy/fixed_int.hpp +317 -0
- tpyc/_data/runtime/cpp/include/tpy/format.hpp +954 -0
- tpyc/_data/runtime/cpp/include/tpy/frame_slot.hpp +120 -0
- tpyc/_data/runtime/cpp/include/tpy/generator.hpp +47 -0
- tpyc/_data/runtime/cpp/include/tpy/iterable_ops.hpp +122 -0
- tpyc/_data/runtime/cpp/include/tpy/itertools.hpp +749 -0
- tpyc/_data/runtime/cpp/include/tpy/next_iter.hpp +82 -0
- tpyc/_data/runtime/cpp/include/tpy/ordered_map.hpp +518 -0
- tpyc/_data/runtime/cpp/include/tpy/ordered_set.hpp +337 -0
- tpyc/_data/runtime/cpp/include/tpy/own_iter.hpp +54 -0
- tpyc/_data/runtime/cpp/include/tpy/pascal_graph_sdl.hpp +192 -0
- tpyc/_data/runtime/cpp/include/tpy/printing.hpp +302 -0
- tpyc/_data/runtime/cpp/include/tpy/protocols.hpp +61 -0
- tpyc/_data/runtime/cpp/include/tpy/range.hpp +115 -0
- tpyc/_data/runtime/cpp/include/tpy/ranges.hpp +212 -0
- tpyc/_data/runtime/cpp/include/tpy/set_ops.hpp +265 -0
- tpyc/_data/runtime/cpp/include/tpy/slice.hpp +47 -0
- tpyc/_data/runtime/cpp/include/tpy/span_iter.hpp +42 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/math.hpp +41 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/pcre2_h.hpp +96 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/random.hpp +25 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/socket_h.hpp +145 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/time.hpp +62 -0
- tpyc/_data/runtime/cpp/include/tpy/system.hpp +121 -0
- tpyc/_data/runtime/cpp/include/tpy/throwable.hpp +55 -0
- tpyc/_data/runtime/cpp/include/tpy/tpy.hpp +156 -0
- tpyc/_data/runtime/cpp/include/tpy/type_name.hpp +77 -0
- tpyc/_data/runtime/cpp/include/tpy/type_traits.hpp +240 -0
- tpyc/_data/runtime/cpp/include/tpy/uninit_array_storage.hpp +250 -0
- tpyc/_data/runtime/cpp/include/tpy/uninit_heap_storage.hpp +277 -0
- tpyc/_data/runtime/cpp/include/tpy/varargs.hpp +174 -0
- tpyc/_data/runtime/cpp/include/tpy/variant_ref.hpp +118 -0
- tpyc/_data/runtime/cpp/src/stdlib/socket_impl.cpp +104 -0
- tpyc/_data/runtime/cpp/third_party/README.md +58 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/AUTHORS +36 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/CMakeLists.txt +1233 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/COPYING +5 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/ChangeLog +3097 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/HACKING +853 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/INSTALL +368 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/LICENCE +94 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/NEWS +492 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/NON-AUTOTOOLS-BUILD +430 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/README +956 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/COPYING-CMAKE-SCRIPTS +22 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindEditline.cmake +16 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindPackageHandleStandardArgs.cmake +58 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindReadline.cmake +29 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config-version.cmake.in +15 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config.cmake.in +148 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/config-cmake.h.in +56 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-16.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-32.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-8.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-posix.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/pcre2-config.in +121 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h +483 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.generic +483 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.in +460 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.generic +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.in +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_auto_possess.c +1371 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c +196 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c.dist +196 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chkdint.c +96 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_compile.c +11001 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_config.c +252 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_context.c +510 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_convert.c +1189 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dfa_match.c +4119 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dftables.c +297 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_error.c +345 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_extuni.c +162 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_find_bracket.c +219 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_fuzzsupport.c +792 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_internal.h +2084 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_intmodedep.h +940 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_compile.c +14972 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_match.c +200 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_misc.c +234 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_neon_inc.h +354 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_simd_inc.h +2355 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_test.c +2528 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_maketables.c +165 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match.c +7777 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match_data.c +185 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_newline.c +243 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ord2utf.c +120 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_pattern_info.c +432 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_printint.c +886 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_script_run.c +344 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_serialize.c +286 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_string_utils.c +237 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_study.c +1915 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substitute.c +1009 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substring.c +550 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_tables.c +234 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucd.c +5460 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucp.h +396 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucptables.c +1533 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_valid_utf.c +398 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_xclass.c +308 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2demo.c +497 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2grep.c +4606 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.c +425 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.h +187 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix_test.c +209 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2test.c +9708 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c +137 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c +327 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c +89 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c +62 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c +40 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c +72 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c +172 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c +141 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c +102 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfig.h +142 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigCPU.h +188 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigInternal.h +907 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.c +3561 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.h +2466 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_32.c +4636 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_64.c +3491 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_T2_32.c +4302 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeLOONGARCH_64.c +3765 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_32.c +472 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_64.c +387 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_common.c +4259 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_32.c +485 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_64.c +719 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_common.c +3161 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_32.c +142 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_64.c +222 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_common.c +3121 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeS390X.c +4526 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_32.c +1685 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_64.c +1398 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_common.c +5001 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitSerialize.c +516 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitUtils.c +344 -0
- tpyc/_data/runtime/cpp/third_party/pcre2.sources.txt +54 -0
- tpyc/_data/runtime/cpp/third_party/pcre2.vendor.json +7 -0
- tpyc/build/__init__.py +7 -0
- tpyc/build/pcre2.py +122 -0
- tpyc/build/third_party.py +413 -0
- tpyc/cli.py +822 -0
- tpyc/codegen_cpp/__init__.py +18 -0
- tpyc/codegen_cpp/builtins.py +484 -0
- tpyc/codegen_cpp/context.py +2064 -0
- tpyc/codegen_cpp/expressions.py +5940 -0
- tpyc/codegen_cpp/functions.py +1913 -0
- tpyc/codegen_cpp/gen_async.py +3258 -0
- tpyc/codegen_cpp/gen_generators.py +657 -0
- tpyc/codegen_cpp/generator.py +2258 -0
- tpyc/codegen_cpp/match.py +1997 -0
- tpyc/codegen_cpp/param_const.py +172 -0
- tpyc/codegen_cpp/protocols.py +907 -0
- tpyc/codegen_cpp/records.py +1654 -0
- tpyc/codegen_cpp/resumable_cfg.py +1651 -0
- tpyc/codegen_cpp/statements.py +4963 -0
- tpyc/codegen_cpp/string_dispatch.py +76 -0
- tpyc/codegen_cpp/test_context.py +46 -0
- tpyc/codegen_cpp/test_param_const.py +113 -0
- tpyc/codegen_cpp/test_resumable_cfg.py +182 -0
- tpyc/codegen_cpp/type_resolution.py +53 -0
- tpyc/codegen_cpp/types.py +436 -0
- tpyc/codegen_cpp/variant_access.py +135 -0
- tpyc/coercions.py +749 -0
- tpyc/compilation_context.py +57 -0
- tpyc/compiler.py +3945 -0
- tpyc/cycle_detection.py +358 -0
- tpyc/diagnostics.py +135 -0
- tpyc/dump_types.py +353 -0
- tpyc/frontend_diagnostics.py +47 -0
- tpyc/frontend_ir/__init__.py +140 -0
- tpyc/frontend_ir/lower.py +1098 -0
- tpyc/frontend_ir/nodes.py +718 -0
- tpyc/frontend_ir/resolver_adapter.py +151 -0
- tpyc/frontend_plugin.py +209 -0
- tpyc/install_docs.py +81 -0
- tpyc/liveness.py +756 -0
- tpyc/macro_api.py +1724 -0
- tpyc/macro_loader.py +497 -0
- tpyc/module_names.py +64 -0
- tpyc/modules/__init__.py +31 -0
- tpyc/modules/defs.py +89 -0
- tpyc/modules/registry.py +36 -0
- tpyc/modules/resolver.py +192 -0
- tpyc/modules/type_resolution.py +629 -0
- tpyc/namespace.py +172 -0
- tpyc/parse/__init__.py +84 -0
- tpyc/parse/imports.py +490 -0
- tpyc/parse/nodes.py +1732 -0
- tpyc/parse/parser.py +4043 -0
- tpyc/parse/resolve_refs.py +466 -0
- tpyc/parse/type_resolver.py +1060 -0
- tpyc/prescan.py +254 -0
- tpyc/qnames.py +149 -0
- tpyc/repl.py +529 -0
- tpyc/repl_backends.py +848 -0
- tpyc/sema/__init__.py +21 -0
- tpyc/sema/analyzer.py +3625 -0
- tpyc/sema/bound_check.py +72 -0
- tpyc/sema/builder_trace.py +684 -0
- tpyc/sema/calls.py +5406 -0
- tpyc/sema/compatibility.py +2107 -0
- tpyc/sema/context.py +1243 -0
- tpyc/sema/expressions.py +3737 -0
- tpyc/sema/flow_facts.py +199 -0
- tpyc/sema/init_tracker.py +150 -0
- tpyc/sema/list_literals.py +69 -0
- tpyc/sema/literal_utils.py +27 -0
- tpyc/sema/local_deduction.py +1088 -0
- tpyc/sema/macros.py +179 -0
- tpyc/sema/match.py +1177 -0
- tpyc/sema/method_expansion.py +347 -0
- tpyc/sema/methods.py +2197 -0
- tpyc/sema/mutation_propagation.py +268 -0
- tpyc/sema/narrowing.py +857 -0
- tpyc/sema/numeric_lattice.py +160 -0
- tpyc/sema/operators.py +402 -0
- tpyc/sema/overloads.py +841 -0
- tpyc/sema/protocols.py +1209 -0
- tpyc/sema/reach_analysis.py +202 -0
- tpyc/sema/registration.py +3156 -0
- tpyc/sema/scope_tracker.py +193 -0
- tpyc/sema/statements.py +4426 -0
- tpyc/sema/type_ops.py +1879 -0
- tpyc/sema/value_range.py +181 -0
- tpyc/symbol_binding.py +259 -0
- tpyc/test_c3_mro.py +208 -0
- tpyc/test_cli_argv.py +52 -0
- tpyc/test_compiler.py +559 -0
- tpyc/test_contains_type_param.py +101 -0
- tpyc/test_cycle_detection.py +221 -0
- tpyc/test_dump_types.py +225 -0
- tpyc/test_install_docs.py +65 -0
- tpyc/test_local_cpp_form.py +135 -0
- tpyc/test_macro_loader.py +76 -0
- tpyc/test_method_expansion.py +254 -0
- tpyc/test_nominal_identity.py +182 -0
- tpyc/test_overloads.py +410 -0
- tpyc/test_parse.py +303 -0
- tpyc/test_parse_type_ref.py +506 -0
- tpyc/test_parse_version_info.py +58 -0
- tpyc/test_reach_analysis.py +72 -0
- tpyc/test_ref_type.py +216 -0
- tpyc/test_send_sync_substitution.py +276 -0
- tpyc/test_tuple_mutation_propagation.py +206 -0
- tpyc/test_type_def_registry.py +1729 -0
- tpyc/test_union_types.py +195 -0
- tpyc/type_def_registry.py +975 -0
- 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"
|