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,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Collection Printing
|
|
3
|
+
*
|
|
4
|
+
* Python-style printing for containers: [a, b, c]
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include <array>
|
|
10
|
+
#include <cstddef>
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
#include <iostream>
|
|
13
|
+
#include <optional>
|
|
14
|
+
#include <ranges>
|
|
15
|
+
#include <span>
|
|
16
|
+
#include <sstream>
|
|
17
|
+
#include <string>
|
|
18
|
+
#include <string_view>
|
|
19
|
+
#include <tuple>
|
|
20
|
+
#include <type_traits>
|
|
21
|
+
#include <variant>
|
|
22
|
+
#include <vector>
|
|
23
|
+
|
|
24
|
+
#include "bigint.hpp"
|
|
25
|
+
#include "dunder.hpp"
|
|
26
|
+
#include "format.hpp"
|
|
27
|
+
|
|
28
|
+
namespace tpy {
|
|
29
|
+
|
|
30
|
+
// Forward declarations for nested container printing
|
|
31
|
+
template<typename T> class ordered_set;
|
|
32
|
+
template<typename K, typename V> class ordered_map;
|
|
33
|
+
|
|
34
|
+
// --- Collection printing (Python-style: [a, b, c]) ---
|
|
35
|
+
|
|
36
|
+
template <typename T>
|
|
37
|
+
struct ListPrinter {
|
|
38
|
+
const T& value;
|
|
39
|
+
explicit ListPrinter(const T& v) : value(v) {}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
namespace detail {
|
|
43
|
+
|
|
44
|
+
// Forward declare for recursive nested container support
|
|
45
|
+
template <typename Iter>
|
|
46
|
+
void print_list_contents(std::ostream& os, Iter begin, Iter end);
|
|
47
|
+
|
|
48
|
+
// Forward declare tuple overload so nested containers (e.g. list[tuple]) resolve correctly
|
|
49
|
+
template <typename... Ts>
|
|
50
|
+
void print_element(std::ostream& os, const std::tuple<Ts...>& t);
|
|
51
|
+
|
|
52
|
+
// Forward declare ordered_set overload (defined in set_ops.hpp)
|
|
53
|
+
template <typename T>
|
|
54
|
+
void print_element(std::ostream& os, const ordered_set<T>& elem);
|
|
55
|
+
|
|
56
|
+
// Forward declare ordered_map overload (defined in dict_ops.hpp)
|
|
57
|
+
template <typename K, typename V>
|
|
58
|
+
void print_element(std::ostream& os, const ordered_map<K, V>& elem);
|
|
59
|
+
|
|
60
|
+
// Forward declare Any overload (defined in any.hpp). The forward decl
|
|
61
|
+
// must precede the generic `print_element<T>` template so two-phase
|
|
62
|
+
// lookup picks the non-template Any overload at template-definition
|
|
63
|
+
// time even when any.hpp is included after dict_ops.hpp / set_ops.hpp.
|
|
64
|
+
} // namespace detail
|
|
65
|
+
struct Any;
|
|
66
|
+
namespace detail {
|
|
67
|
+
void print_element(std::ostream& os, const ::tpy::Any& a);
|
|
68
|
+
|
|
69
|
+
// Container element printing goes through tpy::repr_of so containers emit
|
|
70
|
+
// the repr form (Python: `print([rec])` uses __repr__, not __str__).
|
|
71
|
+
// Specific overloads above cover bool/double/string/BigInt; this generic
|
|
72
|
+
// is the fallback for user records and other types.
|
|
73
|
+
template <typename T>
|
|
74
|
+
void print_element(std::ostream& os, const T& elem) {
|
|
75
|
+
os << ::tpy::repr_of(elem);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
inline void print_element(std::ostream& os, bool elem) {
|
|
79
|
+
os << (elem ? "True" : "False");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
inline void print_element(std::ostream& os, double elem) {
|
|
83
|
+
os << format_float(elem);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
inline void print_element(std::ostream& os, const std::string& elem) {
|
|
87
|
+
os << repr_quote_string(elem);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
inline void print_element(std::ostream& os, std::string_view elem) {
|
|
91
|
+
os << repr_quote_string(elem);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
inline void print_element(std::ostream& os, const BigInt& elem) {
|
|
95
|
+
os << elem.to_string();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// std::vector<bool> uses proxy refs so the bool overload won't match via iterators
|
|
99
|
+
inline void print_element(std::ostream& os, const std::vector<bool>& elem) {
|
|
100
|
+
os << '[';
|
|
101
|
+
for (std::size_t i = 0; i < elem.size(); ++i) {
|
|
102
|
+
if (i > 0) os << ", ";
|
|
103
|
+
print_element(os, static_cast<bool>(elem[i]));
|
|
104
|
+
}
|
|
105
|
+
os << ']';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Forward declarations for variant/optional (defined after all other overloads)
|
|
109
|
+
template <typename... Ts>
|
|
110
|
+
void print_element(std::ostream& os, const std::variant<Ts...>& elem);
|
|
111
|
+
template <typename T>
|
|
112
|
+
void print_element(std::ostream& os, const std::optional<T>& elem);
|
|
113
|
+
inline void print_element(std::ostream& os, std::monostate);
|
|
114
|
+
|
|
115
|
+
// Overloads for nested containers
|
|
116
|
+
template <typename T>
|
|
117
|
+
void print_element(std::ostream& os, const std::vector<T>& elem) {
|
|
118
|
+
print_list_contents(os, elem.begin(), elem.end());
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
template <typename T, std::size_t N>
|
|
122
|
+
void print_element(std::ostream& os, const std::array<T, N>& elem) {
|
|
123
|
+
print_list_contents(os, elem.begin(), elem.end());
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
template <typename Iter>
|
|
127
|
+
void print_list_contents(std::ostream& os, Iter begin, Iter end) {
|
|
128
|
+
os << '[';
|
|
129
|
+
bool first = true;
|
|
130
|
+
for (auto it = begin; it != end; ++it) {
|
|
131
|
+
if (!first) os << ", ";
|
|
132
|
+
first = false;
|
|
133
|
+
print_element(os, *it);
|
|
134
|
+
}
|
|
135
|
+
os << ']';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Definitions for variant/optional/monostate (after all other print_element
|
|
139
|
+
// overloads so std::visit can find container overloads during instantiation).
|
|
140
|
+
template <typename... Ts>
|
|
141
|
+
void print_element(std::ostream& os, const std::variant<Ts...>& elem) {
|
|
142
|
+
std::visit([&os](const auto& v) { print_element(os, v); }, elem);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
inline void print_element(std::ostream& os, std::monostate) {
|
|
146
|
+
os << "None";
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
template <typename T>
|
|
150
|
+
void print_element(std::ostream& os, const std::optional<T>& elem) {
|
|
151
|
+
if (elem.has_value()) {
|
|
152
|
+
print_element(os, *elem);
|
|
153
|
+
} else {
|
|
154
|
+
os << "None";
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
} // namespace detail
|
|
159
|
+
|
|
160
|
+
template <typename T>
|
|
161
|
+
std::ostream& operator<<(std::ostream& os, const ListPrinter<std::vector<T>>& p) {
|
|
162
|
+
detail::print_list_contents(os, p.value.begin(), p.value.end());
|
|
163
|
+
return os;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// std::vector<bool> uses proxy refs, so the generic iterator path won't pick up
|
|
167
|
+
// the bool overload of print_element. Handle it explicitly.
|
|
168
|
+
inline std::ostream& operator<<(std::ostream& os, const ListPrinter<std::vector<bool>>& p) {
|
|
169
|
+
os << '[';
|
|
170
|
+
for (std::size_t i = 0; i < p.value.size(); ++i) {
|
|
171
|
+
if (i > 0) os << ", ";
|
|
172
|
+
detail::print_element(os, static_cast<bool>(p.value[i]));
|
|
173
|
+
}
|
|
174
|
+
os << ']';
|
|
175
|
+
return os;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
template <typename T, std::size_t N>
|
|
179
|
+
std::ostream& operator<<(std::ostream& os, const ListPrinter<std::array<T, N>>& p) {
|
|
180
|
+
detail::print_list_contents(os, p.value.begin(), p.value.end());
|
|
181
|
+
return os;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
template <typename T>
|
|
185
|
+
std::ostream& operator<<(std::ostream& os, const ListPrinter<std::span<T>>& p) {
|
|
186
|
+
detail::print_list_contents(os, p.value.begin(), p.value.end());
|
|
187
|
+
return os;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Generic fallback for any iterable container (e.g. repeat_range)
|
|
191
|
+
template <typename C>
|
|
192
|
+
requires std::ranges::input_range<C>
|
|
193
|
+
&& (!requires { typename std::tuple_size<C>::type; }) // exclude array
|
|
194
|
+
std::ostream& operator<<(std::ostream& os, const ListPrinter<C>& p) {
|
|
195
|
+
detail::print_list_contents(os, std::ranges::begin(p.value), std::ranges::end(p.value));
|
|
196
|
+
return os;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// --- Generic value printing for type parameters ---
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* ValuePrinter<T> - Prints values handling both scalars and containers.
|
|
203
|
+
*
|
|
204
|
+
* Used for generic type parameters where T might be a value type (int32_t)
|
|
205
|
+
* or a container type (std::vector). Uses ListPrinter for ranges.
|
|
206
|
+
*/
|
|
207
|
+
template<typename T>
|
|
208
|
+
struct ValuePrinter {
|
|
209
|
+
const T& value;
|
|
210
|
+
explicit ValuePrinter(const T& v) : value(v) {}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
template<typename T>
|
|
214
|
+
std::ostream& operator<<(std::ostream& os, const ValuePrinter<T>& p) {
|
|
215
|
+
// String types are ranges but should print as strings, not char lists
|
|
216
|
+
if constexpr (std::is_same_v<T, std::string_view> ||
|
|
217
|
+
std::is_same_v<T, std::string> ||
|
|
218
|
+
std::is_same_v<T, const char*>) {
|
|
219
|
+
return os << p.value;
|
|
220
|
+
} else if constexpr (std::is_same_v<T, bool>) {
|
|
221
|
+
return os << (p.value ? "True" : "False");
|
|
222
|
+
} else if constexpr (std::is_same_v<T, double>) {
|
|
223
|
+
return os << format_float(p.value);
|
|
224
|
+
} else if constexpr (std::ranges::range<T>) {
|
|
225
|
+
return os << ListPrinter(p.value);
|
|
226
|
+
} else {
|
|
227
|
+
return os << p.value;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// --- Tuple printing (Python-style: (a, b) or (a,) for single-element) ---
|
|
232
|
+
|
|
233
|
+
namespace detail {
|
|
234
|
+
|
|
235
|
+
template <typename Tuple, std::size_t... Is>
|
|
236
|
+
void print_tuple_elements(std::ostream& os, const Tuple& t, std::index_sequence<Is...>) {
|
|
237
|
+
((Is == 0 ? (void)(os) : (void)(os << ", "),
|
|
238
|
+
print_element(os, std::get<Is>(t))), ...);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
template <typename... Ts>
|
|
242
|
+
void print_element(std::ostream& os, const std::tuple<Ts...>& t) {
|
|
243
|
+
os << '(';
|
|
244
|
+
print_tuple_elements(os, t, std::index_sequence_for<Ts...>{});
|
|
245
|
+
if constexpr (sizeof...(Ts) == 1) {
|
|
246
|
+
os << ',';
|
|
247
|
+
}
|
|
248
|
+
os << ')';
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
} // namespace detail
|
|
252
|
+
|
|
253
|
+
template <typename... Ts>
|
|
254
|
+
struct TuplePrinter {
|
|
255
|
+
const std::tuple<Ts...>& value;
|
|
256
|
+
explicit TuplePrinter(const std::tuple<Ts...>& v) : value(v) {}
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// Deduction guide
|
|
260
|
+
template <typename... Ts>
|
|
261
|
+
TuplePrinter(const std::tuple<Ts...>&) -> TuplePrinter<Ts...>;
|
|
262
|
+
|
|
263
|
+
template <typename... Ts>
|
|
264
|
+
std::ostream& operator<<(std::ostream& os, const TuplePrinter<Ts...>& p) {
|
|
265
|
+
os << '(';
|
|
266
|
+
detail::print_tuple_elements(os, p.value, std::index_sequence_for<Ts...>{});
|
|
267
|
+
if constexpr (sizeof...(Ts) == 1) {
|
|
268
|
+
os << ',';
|
|
269
|
+
}
|
|
270
|
+
os << ')';
|
|
271
|
+
return os;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// --- to_str helpers for str()/repr()/f-string on containers ---
|
|
275
|
+
|
|
276
|
+
template <typename T>
|
|
277
|
+
std::string list_to_str(const T& c) {
|
|
278
|
+
std::ostringstream oss;
|
|
279
|
+
oss << ListPrinter(c);
|
|
280
|
+
return oss.str();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
template <typename... Ts>
|
|
284
|
+
std::string tuple_to_str(const std::tuple<Ts...>& t) {
|
|
285
|
+
std::ostringstream oss;
|
|
286
|
+
oss << TuplePrinter(t);
|
|
287
|
+
return oss.str();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// --- __str__ / __repr__ overloads for std::tuple ---
|
|
291
|
+
|
|
292
|
+
template <typename... Ts>
|
|
293
|
+
std::string __str__(const std::tuple<Ts...>& t) {
|
|
294
|
+
return tuple_to_str(t);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
template <typename... Ts>
|
|
298
|
+
std::string __repr__(const std::tuple<Ts...>& t) {
|
|
299
|
+
return tuple_to_str(t);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
} // namespace tpy
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Protocols
|
|
3
|
+
*
|
|
4
|
+
* C++ concepts for marker protocols that have no structural methods.
|
|
5
|
+
* These are referenced by name from @native protocol definitions in
|
|
6
|
+
* lib/tpy/tpy/__init__.py (e.g. @native("tpy::NativeIterable")).
|
|
7
|
+
*
|
|
8
|
+
* Structural protocols (Truthy, Comparable, Hashable, etc.) are now
|
|
9
|
+
* generated by the compiler from .py protocol definitions and live in
|
|
10
|
+
* the tpystd::tpy namespace.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
#pragma once
|
|
14
|
+
|
|
15
|
+
#include <cstdint>
|
|
16
|
+
#include <iterator>
|
|
17
|
+
#include <ranges>
|
|
18
|
+
#include <type_traits>
|
|
19
|
+
|
|
20
|
+
#include "dunder.hpp"
|
|
21
|
+
#include "ranges.hpp"
|
|
22
|
+
|
|
23
|
+
namespace tpy {
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* NativeIterable concept - types that support C++ range-based for loops
|
|
27
|
+
*
|
|
28
|
+
* A type is NativeIterable<ElemT> if it supports begin()/end() iteration
|
|
29
|
+
* and dereferencing yields ElemT. This is the "native" C++ iteration pattern.
|
|
30
|
+
*/
|
|
31
|
+
template<typename T, typename ElemT>
|
|
32
|
+
concept NativeIterable = requires(const T& t) {
|
|
33
|
+
{ std::ranges::begin(t) } -> std::input_or_output_iterator;
|
|
34
|
+
{ std::ranges::end(t) } -> std::sentinel_for<decltype(std::ranges::begin(t))>;
|
|
35
|
+
{ *std::ranges::begin(t) } -> std::convertible_to<ElemT>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* NativeRangeConstructible concept - types that can be constructed from a range
|
|
40
|
+
*
|
|
41
|
+
* A type is NativeRangeConstructible<ElemT> if from_range<T> can construct it.
|
|
42
|
+
* This requires an iterator-pair constructor (begin, end).
|
|
43
|
+
*/
|
|
44
|
+
template<typename T, typename ElemT>
|
|
45
|
+
concept NativeRangeConstructible = requires(repeat_range<ElemT> r) {
|
|
46
|
+
T(std::ranges::begin(r), std::ranges::end(r));
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Fixed-width integer concepts - constrain generic functions to fixed-int types
|
|
51
|
+
*/
|
|
52
|
+
template<typename T>
|
|
53
|
+
concept AnyFixedInt = std::is_integral_v<T> && !std::is_same_v<T, bool>;
|
|
54
|
+
|
|
55
|
+
template<typename T>
|
|
56
|
+
concept AnyFixedSigned = AnyFixedInt<T> && std::is_signed_v<T>;
|
|
57
|
+
|
|
58
|
+
template<typename T>
|
|
59
|
+
concept AnyFixedUnsigned = AnyFixedInt<T> && std::is_unsigned_v<T>;
|
|
60
|
+
|
|
61
|
+
} // namespace tpy
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Range
|
|
3
|
+
*
|
|
4
|
+
* Python-style range() as an immutable, reusable container with begin/end.
|
|
5
|
+
* Depends on: core.hpp (raise<E>), fixed_int.hpp
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <cstdint>
|
|
11
|
+
#include <iostream>
|
|
12
|
+
#include <limits>
|
|
13
|
+
#include <type_traits>
|
|
14
|
+
#include "fixed_int.hpp"
|
|
15
|
+
|
|
16
|
+
namespace tpy {
|
|
17
|
+
|
|
18
|
+
// Upfront overflow check for range loops with fixed-width integer types.
|
|
19
|
+
// Verifies that stepping through [start, stop) with the given step will never
|
|
20
|
+
// overflow T, so the loop body can use unchecked += for maximum speed.
|
|
21
|
+
// For step ±1 this is unnecessary (stop is already a valid T value).
|
|
22
|
+
// All arithmetic uses unsigned to avoid signed overflow UB in the check itself.
|
|
23
|
+
//
|
|
24
|
+
// The check computes the exact exit value (the value of i after the final
|
|
25
|
+
// increment) and verifies it fits in T. When step evenly divides
|
|
26
|
+
// (stop - start), the exit value is exactly `stop` (always representable).
|
|
27
|
+
// Otherwise the exit value overshoots by (step - remainder), and we check
|
|
28
|
+
// that overshoot against T's bounds.
|
|
29
|
+
template<typename T>
|
|
30
|
+
void range_check_overflow(T start, T stop, T step) {
|
|
31
|
+
static_assert(std::is_integral_v<T> && sizeof(T) <= 8);
|
|
32
|
+
using U = std::make_unsigned_t<T>;
|
|
33
|
+
if (step > T{0}) {
|
|
34
|
+
if (start >= stop) return; // empty range
|
|
35
|
+
U d = static_cast<U>(stop) - static_cast<U>(start);
|
|
36
|
+
U ustep = static_cast<U>(step);
|
|
37
|
+
U rem = d % ustep;
|
|
38
|
+
if (rem == 0) return; // exit value is exactly stop, always safe
|
|
39
|
+
// Exit value = stop + (step - rem). Need: stop + (step - rem) <= T::max.
|
|
40
|
+
U overshoot = ustep - rem;
|
|
41
|
+
U room = static_cast<U>(std::numeric_limits<T>::max()) - static_cast<U>(stop);
|
|
42
|
+
if (overshoot > room) {
|
|
43
|
+
raise_fixedint_overflow("range() would overflow on iteration");
|
|
44
|
+
}
|
|
45
|
+
} else if constexpr (std::is_signed_v<T>) {
|
|
46
|
+
if (step < T{0}) {
|
|
47
|
+
if (start <= stop) return; // empty range
|
|
48
|
+
U d = static_cast<U>(start) - static_cast<U>(stop);
|
|
49
|
+
U abs_step = static_cast<U>(0) - static_cast<U>(step);
|
|
50
|
+
U rem = d % abs_step;
|
|
51
|
+
if (rem == 0) return; // exit value is exactly stop, always safe
|
|
52
|
+
// Exit value = stop - (abs_step - rem). Need: stop - (abs_step - rem) >= T::min.
|
|
53
|
+
U overshoot = abs_step - rem;
|
|
54
|
+
U room = static_cast<U>(stop) - static_cast<U>(std::numeric_limits<T>::min());
|
|
55
|
+
if (overshoot > room) {
|
|
56
|
+
raise_fixedint_overflow("range() would overflow on iteration");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Raises ValueError when `step == 0`. Shared by Range<T>::Range(T,T,T)
|
|
63
|
+
// and the codegen-emitted inline range loops in statements.py / expressions.py
|
|
64
|
+
// so the message lives in one place.
|
|
65
|
+
template<typename T>
|
|
66
|
+
inline void range_check_step_nonzero(T step) {
|
|
67
|
+
if (step == T{}) raise_value_error("range() arg 3 must not be zero");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
template<typename T>
|
|
71
|
+
class Range {
|
|
72
|
+
T start_;
|
|
73
|
+
T end_;
|
|
74
|
+
T step_;
|
|
75
|
+
public:
|
|
76
|
+
Range() : start_{}, end_{}, step_(1) {}
|
|
77
|
+
Range(T end) : start_{}, end_(std::move(end)), step_(1) {}
|
|
78
|
+
Range(T start, T end) : start_(start), end_(std::move(end)), step_(1) {}
|
|
79
|
+
Range(T start, T end, T step) : start_(start), end_(std::move(end)), step_(std::move(step)) {
|
|
80
|
+
range_check_step_nonzero(step_);
|
|
81
|
+
if constexpr (std::is_integral_v<T> && sizeof(T) <= 8)
|
|
82
|
+
range_check_overflow<T>(start_, end_, step_);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
struct Iterator {
|
|
86
|
+
using value_type = T;
|
|
87
|
+
using difference_type = std::ptrdiff_t;
|
|
88
|
+
using iterator_category = std::input_iterator_tag;
|
|
89
|
+
T current_, end_, step_;
|
|
90
|
+
T operator*() const { return current_; }
|
|
91
|
+
Iterator& operator++() {
|
|
92
|
+
current_ += step_;
|
|
93
|
+
if (step_ > T{} ? !(current_ < end_) : !(current_ > end_))
|
|
94
|
+
current_ = end_;
|
|
95
|
+
return *this;
|
|
96
|
+
}
|
|
97
|
+
Iterator operator++(int) { auto t = *this; ++(*this); return t; }
|
|
98
|
+
bool operator==(const Iterator& o) const { return current_ == o.current_; }
|
|
99
|
+
bool operator!=(const Iterator& o) const { return !(current_ == o.current_); }
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
Iterator begin() const {
|
|
103
|
+
bool empty = step_ > T{} ? !(start_ < end_) : !(start_ > end_);
|
|
104
|
+
return {empty ? end_ : start_, end_, step_};
|
|
105
|
+
}
|
|
106
|
+
Iterator end() const { return {end_, end_, step_}; }
|
|
107
|
+
|
|
108
|
+
friend std::ostream& operator<<(std::ostream& os, const Range& r) {
|
|
109
|
+
os << "range(" << r.start_ << ", " << r.end_;
|
|
110
|
+
if (r.step_ != T{1}) os << ", " << r.step_;
|
|
111
|
+
return os << ")";
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
} // namespace tpy
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Range Utilities
|
|
3
|
+
*
|
|
4
|
+
* Utilities for list repetition and range-based construction.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include <array>
|
|
10
|
+
#include <cstddef>
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
#include <initializer_list>
|
|
13
|
+
#include <iterator>
|
|
14
|
+
#include <ranges>
|
|
15
|
+
#include <type_traits>
|
|
16
|
+
#include <vector>
|
|
17
|
+
|
|
18
|
+
#include "next_iter.hpp"
|
|
19
|
+
|
|
20
|
+
namespace tpy {
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* repeat_range<T> - A range that yields elements from a sequence N times.
|
|
24
|
+
*
|
|
25
|
+
* Used to implement Python's list repetition: [a, b] * 3 -> [a, b, a, b, a, b]
|
|
26
|
+
* Satisfies std::ranges::input_range for use with C++23 std::from_range constructors.
|
|
27
|
+
* Negative counts are treated as 0 (Python semantics).
|
|
28
|
+
*/
|
|
29
|
+
template<typename T>
|
|
30
|
+
class repeat_range {
|
|
31
|
+
std::vector<T> elements_;
|
|
32
|
+
std::size_t count_;
|
|
33
|
+
|
|
34
|
+
public:
|
|
35
|
+
repeat_range(int32_t count, std::initializer_list<T> elements)
|
|
36
|
+
: elements_(elements), count_(count > 0 ? static_cast<std::size_t>(count) : 0) {}
|
|
37
|
+
|
|
38
|
+
class iterator {
|
|
39
|
+
const repeat_range* parent_;
|
|
40
|
+
std::size_t rep_;
|
|
41
|
+
std::size_t idx_;
|
|
42
|
+
|
|
43
|
+
public:
|
|
44
|
+
using iterator_category = std::input_iterator_tag;
|
|
45
|
+
using value_type = T;
|
|
46
|
+
using difference_type = std::ptrdiff_t;
|
|
47
|
+
// For T=bool we must return by value: vector<bool>::operator[] returns
|
|
48
|
+
// a proxy, and a `const bool&` return would bind to a temporary bool
|
|
49
|
+
// created from the proxy and dangle past the function return. For all
|
|
50
|
+
// other T we keep zero-copy `const T&` so std::string/etc. don't pay
|
|
51
|
+
// an extra copy on every dereference.
|
|
52
|
+
using reference = std::conditional_t<std::is_same_v<T, bool>, T, const T&>;
|
|
53
|
+
using pointer = std::conditional_t<std::is_same_v<T, bool>, void, const T*>;
|
|
54
|
+
|
|
55
|
+
iterator() : parent_(nullptr), rep_(0), idx_(0) {}
|
|
56
|
+
iterator(const repeat_range* p, std::size_t r, std::size_t i)
|
|
57
|
+
: parent_(p), rep_(r), idx_(i) {}
|
|
58
|
+
|
|
59
|
+
reference operator*() const { return parent_->elements_[idx_]; }
|
|
60
|
+
|
|
61
|
+
iterator& operator++() {
|
|
62
|
+
if (++idx_ >= parent_->elements_.size()) {
|
|
63
|
+
idx_ = 0;
|
|
64
|
+
++rep_;
|
|
65
|
+
}
|
|
66
|
+
return *this;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
iterator operator++(int) { auto t = *this; ++(*this); return t; }
|
|
70
|
+
|
|
71
|
+
bool operator==(const iterator& o) const {
|
|
72
|
+
return rep_ == o.rep_ && idx_ == o.idx_;
|
|
73
|
+
}
|
|
74
|
+
bool operator!=(const iterator& o) const { return !(*this == o); }
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
iterator begin() const {
|
|
78
|
+
if (count_ == 0 || elements_.empty()) return end();
|
|
79
|
+
return iterator(this, 0, 0);
|
|
80
|
+
}
|
|
81
|
+
iterator end() const { return iterator(this, count_, 0); }
|
|
82
|
+
|
|
83
|
+
std::size_t size() const { return count_ * elements_.size(); }
|
|
84
|
+
|
|
85
|
+
// Support tpy::__len__() for len() calls on lazy repeat ranges
|
|
86
|
+
int32_t __len__() const { return static_cast<int32_t>(size()); }
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Convert a range to std::vector.
|
|
91
|
+
* Used for list repetition when std::from_range is unavailable (GCC < 14).
|
|
92
|
+
* Pre-allocates if the range has a size() method.
|
|
93
|
+
*/
|
|
94
|
+
template<typename T, std::ranges::input_range R>
|
|
95
|
+
std::vector<T> to_vector(R&& range) {
|
|
96
|
+
std::vector<T> result;
|
|
97
|
+
if constexpr (requires { range.size(); }) {
|
|
98
|
+
result.reserve(static_cast<std::size_t>(range.size()));
|
|
99
|
+
}
|
|
100
|
+
for (auto&& elem : range) {
|
|
101
|
+
result.push_back(elem);
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Construct a vector from move-only elements (avoids std::initializer_list copy).
|
|
108
|
+
* Uses a C++17 fold expression to emplace each element.
|
|
109
|
+
*/
|
|
110
|
+
template<typename T, typename... Args>
|
|
111
|
+
std::vector<T> make_vector(Args&&... args) {
|
|
112
|
+
std::vector<T> v;
|
|
113
|
+
v.reserve(sizeof...(args));
|
|
114
|
+
(v.emplace_back(std::forward<Args>(args)), ...);
|
|
115
|
+
return v;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Trait to detect std::array specializations
|
|
119
|
+
template<typename T> struct is_std_array : std::false_type {};
|
|
120
|
+
template<typename T, std::size_t N> struct is_std_array<std::array<T, N>> : std::true_type {};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* from_range<Container> - Construct a container from a range.
|
|
124
|
+
*
|
|
125
|
+
* Constructs container using iterator-pair constructor (begin, end).
|
|
126
|
+
* If container supports reserve() and range has known size, reserves first.
|
|
127
|
+
* For std::array (aggregate, no iterator-pair ctor), fills element-by-element.
|
|
128
|
+
* Works with std::vector, std::array, and any container with
|
|
129
|
+
* an iterator-pair constructor.
|
|
130
|
+
*
|
|
131
|
+
* Usage: tpy::from_range<std::vector<int>>(some_range)
|
|
132
|
+
* tpy::from_range<std::array<int, 5>>(some_range)
|
|
133
|
+
*/
|
|
134
|
+
template<typename Container, std::ranges::input_range R>
|
|
135
|
+
Container from_range(R&& range) {
|
|
136
|
+
if constexpr (is_std_array<Container>::value) {
|
|
137
|
+
constexpr auto N = std::tuple_size<Container>::value;
|
|
138
|
+
Container result{};
|
|
139
|
+
std::size_t i = 0;
|
|
140
|
+
for (auto&& elem : range) {
|
|
141
|
+
if (i >= N) { raise_value_error("from_range: range size exceeds array capacity"); }
|
|
142
|
+
result[i++] = std::move(elem);
|
|
143
|
+
}
|
|
144
|
+
if (i != N) { raise_value_error("from_range: range size does not match array size"); }
|
|
145
|
+
return result;
|
|
146
|
+
} else if constexpr (requires(Container& c) { c.reserve(std::size_t{}); } &&
|
|
147
|
+
std::ranges::sized_range<R>) {
|
|
148
|
+
Container result;
|
|
149
|
+
result.reserve(static_cast<std::size_t>(std::ranges::size(range)));
|
|
150
|
+
result.assign(std::ranges::begin(range), std::ranges::end(range));
|
|
151
|
+
return result;
|
|
152
|
+
} else {
|
|
153
|
+
return Container(std::ranges::begin(range), std::ranges::end(range));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* collect<Container> - Collect elements from an iterator into a container.
|
|
159
|
+
*
|
|
160
|
+
* Calls __next__() repeatedly until exhaustion, pushing elements
|
|
161
|
+
* into the container. Used for list(iterator) where iterator is a
|
|
162
|
+
* user-defined iterator (not NativeIterable).
|
|
163
|
+
*/
|
|
164
|
+
template<typename Container, typename Iter>
|
|
165
|
+
Container collect(Iter&& iter) {
|
|
166
|
+
Container result;
|
|
167
|
+
for (;;) {
|
|
168
|
+
auto __r = iter.__next__();
|
|
169
|
+
if (!__r.has_value()) break;
|
|
170
|
+
result.push_back(unwrap_ref_move(*__r));
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* construct<Container> - Unified container construction from any iterable.
|
|
177
|
+
*
|
|
178
|
+
* Dispatches at compile time: uses begin/end iteration for types that
|
|
179
|
+
* satisfy std::ranges::input_range, falls back to __next__() protocol
|
|
180
|
+
* for user-defined iterators.
|
|
181
|
+
*
|
|
182
|
+
* Usage: tpy::construct<std::vector<int>>(some_iterable)
|
|
183
|
+
*/
|
|
184
|
+
template<typename Container, typename Arg>
|
|
185
|
+
Container construct(Arg&& arg) {
|
|
186
|
+
if constexpr (std::ranges::input_range<std::remove_cvref_t<Arg>>) {
|
|
187
|
+
return from_range<Container>(std::forward<Arg>(arg));
|
|
188
|
+
} else {
|
|
189
|
+
return collect<Container>(std::forward<Arg>(arg));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* extend - Append elements from an iterable to an existing container.
|
|
195
|
+
* Dual-dispatch on input_range vs __next__() protocol, matching `construct`.
|
|
196
|
+
* Uses the container's iterator-pair insert for ranges (memcpy for
|
|
197
|
+
* trivially-copyable payloads).
|
|
198
|
+
*/
|
|
199
|
+
template<typename Container, typename Arg>
|
|
200
|
+
void extend(Container& c, Arg&& arg) {
|
|
201
|
+
if constexpr (std::ranges::input_range<std::remove_cvref_t<Arg>>) {
|
|
202
|
+
c.insert(c.end(), std::ranges::begin(arg), std::ranges::end(arg));
|
|
203
|
+
} else {
|
|
204
|
+
for (;;) {
|
|
205
|
+
auto __r = arg.__next__();
|
|
206
|
+
if (!__r.has_value()) break;
|
|
207
|
+
c.push_back(unwrap_ref_move(*__r));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
} // namespace tpy
|