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,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Dynamic Protocol Adapters
|
|
3
|
+
*
|
|
4
|
+
* Primary templates for Adapter<Base, T> and RefAdapter<Base, T>.
|
|
5
|
+
* Each @dynamic protocol generates partial specializations with
|
|
6
|
+
* virtual method overrides in the module's generated code.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
namespace tpy {
|
|
12
|
+
|
|
13
|
+
template<typename Base, typename T>
|
|
14
|
+
struct Adapter;
|
|
15
|
+
|
|
16
|
+
template<typename Base, typename T>
|
|
17
|
+
struct RefAdapter;
|
|
18
|
+
|
|
19
|
+
// Narrowing cast for `isinstance` against a STRUCTURAL conformer of a @dynamic
|
|
20
|
+
// protocol. A structural `Cat` behind a `Pet*` is physically an
|
|
21
|
+
// `Adapter<Pet, Cat>` (owning, from an rvalue source) or a
|
|
22
|
+
// `RefAdapter<Pet, Cat>` (from an lvalue source) -- never a `Cat` that IS-A
|
|
23
|
+
// `Pet` -- so `dynamic_cast<Cat*>` would always fail. Try both adapter shapes
|
|
24
|
+
// and project the contained `.inner`. Returns nullptr when neither matches
|
|
25
|
+
// (the object behind the pointer is a different conformer, or null).
|
|
26
|
+
template<typename Base, typename T>
|
|
27
|
+
T* dyn_adapter_cast(Base* p) {
|
|
28
|
+
if (auto* a = dynamic_cast<Adapter<Base, T>*>(p)) return &a->inner;
|
|
29
|
+
if (auto* r = dynamic_cast<RefAdapter<Base, T>*>(p)) return &r->inner;
|
|
30
|
+
return nullptr;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
template<typename Base, typename T>
|
|
34
|
+
const T* dyn_adapter_cast(const Base* p) {
|
|
35
|
+
if (auto* a = dynamic_cast<const Adapter<Base, T>*>(p)) return &a->inner;
|
|
36
|
+
// RefAdapter's `T& inner` is a reference member: it is not const-propagated
|
|
37
|
+
// through a const adapter, so const-qualify explicitly to honor the
|
|
38
|
+
// const-input overload's `const T*` contract.
|
|
39
|
+
if (auto* r = dynamic_cast<const RefAdapter<Base, T>*>(p))
|
|
40
|
+
return &static_cast<const T&>(r->inner);
|
|
41
|
+
return nullptr;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
} // namespace tpy
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Enum Utilities
|
|
3
|
+
*
|
|
4
|
+
* Primary template for EnumUtil<T>. Each TurboPython enum generates
|
|
5
|
+
* an explicit specialization with name(), members, from_value(), and
|
|
6
|
+
* try_parse() in the module's generated code.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include <ostream>
|
|
12
|
+
#include <string>
|
|
13
|
+
#include <type_traits>
|
|
14
|
+
|
|
15
|
+
namespace tpy {
|
|
16
|
+
|
|
17
|
+
template<typename T>
|
|
18
|
+
struct EnumUtil;
|
|
19
|
+
|
|
20
|
+
namespace detail {
|
|
21
|
+
|
|
22
|
+
// Single home for the "TypeName.MEMBER" enum formatting used by
|
|
23
|
+
// __repr__/__str__ (in dunder.hpp) and print_optional_val (in format.hpp).
|
|
24
|
+
// `requires` is matched by the same constraint shape used at each call
|
|
25
|
+
// site, so partial-template ambiguities don't arise.
|
|
26
|
+
template<typename T>
|
|
27
|
+
requires std::is_enum_v<T> && requires(T x) { ::tpy::EnumUtil<T>::name(x); }
|
|
28
|
+
inline std::ostream& write_enum_repr(std::ostream& os, T x) {
|
|
29
|
+
return os << ::tpy::EnumUtil<T>::type_name << "." << ::tpy::EnumUtil<T>::name(x);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
template<typename T>
|
|
33
|
+
requires std::is_enum_v<T> && requires(T x) { ::tpy::EnumUtil<T>::name(x); }
|
|
34
|
+
inline std::string enum_repr_string(T x) {
|
|
35
|
+
return std::string(::tpy::EnumUtil<T>::type_name) + "." +
|
|
36
|
+
std::string(::tpy::EnumUtil<T>::name(x));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
} // namespace detail
|
|
40
|
+
} // namespace tpy
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - File I/O
|
|
3
|
+
*
|
|
4
|
+
* TextFile: text-mode file wrapper for the open() builtin.
|
|
5
|
+
* Supports read/write/append modes, readline, readlines,
|
|
6
|
+
* and context manager protocol (__enter__/__exit__).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include "core.hpp"
|
|
12
|
+
|
|
13
|
+
#include <fstream>
|
|
14
|
+
#include <sstream>
|
|
15
|
+
#include <string>
|
|
16
|
+
#include <string_view>
|
|
17
|
+
#include <vector>
|
|
18
|
+
|
|
19
|
+
namespace tpy {
|
|
20
|
+
|
|
21
|
+
struct FileFlags {
|
|
22
|
+
std::ios_base::openmode mode;
|
|
23
|
+
bool readable;
|
|
24
|
+
bool writable;
|
|
25
|
+
|
|
26
|
+
static const FileFlags text_read;
|
|
27
|
+
static const FileFlags binary_read;
|
|
28
|
+
|
|
29
|
+
static FileFlags parse_text(std::string_view mode) {
|
|
30
|
+
if (mode == "r" || mode == "rt")
|
|
31
|
+
return {std::ios::in, true, false};
|
|
32
|
+
if (mode == "w" || mode == "wt")
|
|
33
|
+
return {std::ios::out | std::ios::trunc, false, true};
|
|
34
|
+
if (mode == "a" || mode == "at")
|
|
35
|
+
return {std::ios::out | std::ios::app, false, true};
|
|
36
|
+
if (mode == "r+" || mode == "r+t" || mode == "rt+")
|
|
37
|
+
return {std::ios::in | std::ios::out, true, true};
|
|
38
|
+
if (mode == "w+" || mode == "w+t" || mode == "wt+")
|
|
39
|
+
return {std::ios::in | std::ios::out | std::ios::trunc, true, true};
|
|
40
|
+
if (mode == "a+" || mode == "a+t" || mode == "at+")
|
|
41
|
+
return {std::ios::in | std::ios::out | std::ios::app, true, true};
|
|
42
|
+
if (mode == "x" || mode == "xt")
|
|
43
|
+
return {std::ios::out | std::ios::trunc | std::ios::noreplace, false, true};
|
|
44
|
+
if (mode == "x+" || mode == "x+t" || mode == "xt+")
|
|
45
|
+
return {std::ios::in | std::ios::out | std::ios::trunc | std::ios::noreplace, true, true};
|
|
46
|
+
raise_value_error("invalid mode: '{}'", mode);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static FileFlags parse_binary(std::string_view mode) {
|
|
50
|
+
std::ios_base::openmode base = std::ios::binary;
|
|
51
|
+
if (mode == "rb")
|
|
52
|
+
return {base | std::ios::in, true, false};
|
|
53
|
+
if (mode == "wb")
|
|
54
|
+
return {base | std::ios::out | std::ios::trunc, false, true};
|
|
55
|
+
if (mode == "ab")
|
|
56
|
+
return {base | std::ios::out | std::ios::app, false, true};
|
|
57
|
+
if (mode == "r+b" || mode == "rb+")
|
|
58
|
+
return {base | std::ios::in | std::ios::out, true, true};
|
|
59
|
+
if (mode == "w+b" || mode == "wb+")
|
|
60
|
+
return {base | std::ios::in | std::ios::out | std::ios::trunc, true, true};
|
|
61
|
+
if (mode == "a+b" || mode == "ab+")
|
|
62
|
+
return {base | std::ios::in | std::ios::out | std::ios::app, true, true};
|
|
63
|
+
if (mode == "xb")
|
|
64
|
+
return {base | std::ios::out | std::ios::trunc | std::ios::noreplace, false, true};
|
|
65
|
+
if (mode == "x+b" || mode == "xb+")
|
|
66
|
+
return {base | std::ios::in | std::ios::out | std::ios::trunc | std::ios::noreplace, true, true};
|
|
67
|
+
raise_value_error("invalid mode: '{}'", mode);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
inline const FileFlags FileFlags::text_read = {std::ios::in, true, false};
|
|
72
|
+
inline const FileFlags FileFlags::binary_read = {std::ios::binary | std::ios::in, true, false};
|
|
73
|
+
|
|
74
|
+
class TextFile {
|
|
75
|
+
std::fstream fs_;
|
|
76
|
+
std::string path_;
|
|
77
|
+
FileFlags flags_{};
|
|
78
|
+
bool closed_ = false;
|
|
79
|
+
|
|
80
|
+
public:
|
|
81
|
+
TextFile(std::string_view path, FileFlags flags) : path_(path), flags_(flags) {
|
|
82
|
+
fs_.open(path_, flags_.mode);
|
|
83
|
+
if (!fs_.is_open()) {
|
|
84
|
+
raise_file_not_found_error("open(): cannot open '{}'", path);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
TextFile(TextFile&&) = default;
|
|
89
|
+
TextFile& operator=(TextFile&&) = default;
|
|
90
|
+
TextFile(const TextFile&) = delete;
|
|
91
|
+
TextFile& operator=(const TextFile&) = delete;
|
|
92
|
+
|
|
93
|
+
std::string read() {
|
|
94
|
+
if (!flags_.readable) raise_os_error("read(): file not opened for reading");
|
|
95
|
+
std::ostringstream ss;
|
|
96
|
+
ss << fs_.rdbuf();
|
|
97
|
+
return ss.str();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
int32_t write(std::string_view text) {
|
|
101
|
+
if (!flags_.writable) raise_os_error("write(): file not opened for writing");
|
|
102
|
+
fs_ << text;
|
|
103
|
+
return static_cast<int32_t>(text.size());
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
void flush() {
|
|
107
|
+
if (!flags_.writable) raise_os_error("flush(): file not opened for writing");
|
|
108
|
+
fs_.flush();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
std::ostream& sink() { return fs_; }
|
|
112
|
+
|
|
113
|
+
std::string readline() {
|
|
114
|
+
if (!flags_.readable) raise_os_error("readline(): file not opened for reading");
|
|
115
|
+
std::string line;
|
|
116
|
+
if (!std::getline(fs_, line)) {
|
|
117
|
+
return "";
|
|
118
|
+
}
|
|
119
|
+
// getline strips the newline delimiter; restore it unless we hit EOF
|
|
120
|
+
// without a trailing newline (Python compat).
|
|
121
|
+
if (!fs_.eof()) {
|
|
122
|
+
line += '\n';
|
|
123
|
+
}
|
|
124
|
+
return line;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
std::vector<std::string> readlines() {
|
|
128
|
+
if (!flags_.readable) raise_os_error("readlines(): file not opened for reading");
|
|
129
|
+
std::vector<std::string> lines;
|
|
130
|
+
std::string line;
|
|
131
|
+
while (std::getline(fs_, line)) {
|
|
132
|
+
if (!fs_.eof()) line += '\n';
|
|
133
|
+
lines.push_back(std::move(line));
|
|
134
|
+
}
|
|
135
|
+
return lines;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
void close() {
|
|
139
|
+
if (!closed_) {
|
|
140
|
+
fs_.close();
|
|
141
|
+
closed_ = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
TextFile& __enter__() { return *this; }
|
|
146
|
+
void __exit__(std::monostate, const BaseException*, std::monostate) { close(); }
|
|
147
|
+
|
|
148
|
+
friend std::ostream& operator<<(std::ostream& os, const TextFile& f) {
|
|
149
|
+
return os << "<TextIO '" << f.path_ << "'>";
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
~TextFile() { close(); }
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
class BinaryFile {
|
|
156
|
+
std::fstream fs_;
|
|
157
|
+
std::string path_;
|
|
158
|
+
FileFlags flags_{};
|
|
159
|
+
bool closed_ = false;
|
|
160
|
+
|
|
161
|
+
public:
|
|
162
|
+
BinaryFile(std::string_view path, FileFlags flags) : path_(path), flags_(flags) {
|
|
163
|
+
fs_.open(path_, flags_.mode);
|
|
164
|
+
if (!fs_.is_open()) {
|
|
165
|
+
raise_file_not_found_error("open(): cannot open '{}'", path);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
BinaryFile(BinaryFile&&) = default;
|
|
170
|
+
BinaryFile& operator=(BinaryFile&&) = default;
|
|
171
|
+
BinaryFile(const BinaryFile&) = delete;
|
|
172
|
+
BinaryFile& operator=(const BinaryFile&) = delete;
|
|
173
|
+
|
|
174
|
+
std::vector<uint8_t> read() {
|
|
175
|
+
if (!flags_.readable) raise_os_error("read(): file not opened for reading");
|
|
176
|
+
return std::vector<uint8_t>(
|
|
177
|
+
std::istreambuf_iterator<char>(fs_),
|
|
178
|
+
std::istreambuf_iterator<char>()
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
std::vector<uint8_t> readline() {
|
|
183
|
+
if (!flags_.readable) raise_os_error("readline(): file not opened for reading");
|
|
184
|
+
std::string line;
|
|
185
|
+
if (!std::getline(fs_, line)) {
|
|
186
|
+
return {};
|
|
187
|
+
}
|
|
188
|
+
std::vector<uint8_t> result(line.begin(), line.end());
|
|
189
|
+
if (!fs_.eof()) {
|
|
190
|
+
result.push_back('\n');
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
std::vector<std::vector<uint8_t>> readlines() {
|
|
196
|
+
if (!flags_.readable) raise_os_error("readlines(): file not opened for reading");
|
|
197
|
+
std::vector<std::vector<uint8_t>> lines;
|
|
198
|
+
std::string line;
|
|
199
|
+
while (std::getline(fs_, line)) {
|
|
200
|
+
std::vector<uint8_t> row(line.begin(), line.end());
|
|
201
|
+
if (!fs_.eof()) row.push_back('\n');
|
|
202
|
+
lines.push_back(std::move(row));
|
|
203
|
+
}
|
|
204
|
+
return lines;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
int32_t write(std::span<const uint8_t> data) {
|
|
208
|
+
if (!flags_.writable) raise_os_error("write(): file not opened for writing");
|
|
209
|
+
fs_.write(reinterpret_cast<const char*>(data.data()),
|
|
210
|
+
static_cast<std::streamsize>(data.size()));
|
|
211
|
+
return static_cast<int32_t>(data.size());
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
void close() {
|
|
215
|
+
if (!closed_) {
|
|
216
|
+
fs_.close();
|
|
217
|
+
closed_ = true;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
BinaryFile& __enter__() { return *this; }
|
|
222
|
+
void __exit__(std::monostate, const BaseException*, std::monostate) { close(); }
|
|
223
|
+
|
|
224
|
+
friend std::ostream& operator<<(std::ostream& os, const BinaryFile& f) {
|
|
225
|
+
return os << "<BinaryIO '" << f.path_ << "'>";
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
~BinaryFile() { close(); }
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// --- Builtin open() helpers ---
|
|
232
|
+
|
|
233
|
+
inline TextFile builtin_open(std::string_view path) {
|
|
234
|
+
return TextFile(path, FileFlags::text_read);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
inline TextFile builtin_open_mode(std::string_view path, std::string_view mode) {
|
|
238
|
+
return TextFile(path, FileFlags::parse_text(mode));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
inline BinaryFile builtin_open_binary(std::string_view path, std::string_view mode = "rb") {
|
|
242
|
+
return BinaryFile(path, FileFlags::parse_binary(mode));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
} // namespace tpy
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Fixed-Width Integer Checked Arithmetic
|
|
3
|
+
*
|
|
4
|
+
* Template-based overflow-checked operations for all fixed-width integer types.
|
|
5
|
+
* Supports Int8/16/32/64 and UInt8/16/32/64 with Python semantics.
|
|
6
|
+
*
|
|
7
|
+
* The checked-arith helpers are marked constexpr so that `Final[IntN]`
|
|
8
|
+
* initializers that reference other Finals can be constant-evaluated. The
|
|
9
|
+
* overflow / divide-by-zero error branches route through non-constexpr
|
|
10
|
+
* helpers (`raise_fixedint_overflow`, `raise<ZeroDivisionError>`,
|
|
11
|
+
* `raise<ValueError>`); this is permitted under C++23 P2448 as long as those
|
|
12
|
+
* branches are not reached during constant evaluation. When they are reached
|
|
13
|
+
* (e.g. `Final[Int32] = -INT32_MIN`), the compiler rejects the call, turning
|
|
14
|
+
* a would-be runtime panic into a compile-time error.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#pragma once
|
|
18
|
+
|
|
19
|
+
#include <cctype>
|
|
20
|
+
#include <cerrno>
|
|
21
|
+
#include <cmath>
|
|
22
|
+
#include <cstdint>
|
|
23
|
+
#include <cstdlib>
|
|
24
|
+
#include <limits>
|
|
25
|
+
#include <string>
|
|
26
|
+
#include <string_view>
|
|
27
|
+
#include <type_traits>
|
|
28
|
+
#include "core.hpp"
|
|
29
|
+
|
|
30
|
+
namespace tpy {
|
|
31
|
+
|
|
32
|
+
// --- Checked power helper (reusable across all integer types) ---
|
|
33
|
+
|
|
34
|
+
template<typename T>
|
|
35
|
+
constexpr bool try_pow(T base, T exp, T& result) {
|
|
36
|
+
if (exp < 0) return false;
|
|
37
|
+
if (exp == 0) { result = 1; return true; }
|
|
38
|
+
|
|
39
|
+
result = 1;
|
|
40
|
+
T b = base;
|
|
41
|
+
|
|
42
|
+
while (exp > 0) {
|
|
43
|
+
if (exp & 1) {
|
|
44
|
+
if (__builtin_mul_overflow(result, b, &result)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exp >>= 1;
|
|
49
|
+
if (exp > 0) {
|
|
50
|
+
if (__builtin_mul_overflow(b, b, &b)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// --- Type name helper for error messages ---
|
|
59
|
+
|
|
60
|
+
template<typename T> constexpr const char* fixed_int_name() { return "FixedInt"; }
|
|
61
|
+
template<> constexpr const char* fixed_int_name<int8_t>() { return "Int8"; }
|
|
62
|
+
template<> constexpr const char* fixed_int_name<int16_t>() { return "Int16"; }
|
|
63
|
+
template<> constexpr const char* fixed_int_name<int32_t>() { return "Int32"; }
|
|
64
|
+
template<> constexpr const char* fixed_int_name<int64_t>() { return "Int64"; }
|
|
65
|
+
template<> constexpr const char* fixed_int_name<uint8_t>() { return "UInt8"; }
|
|
66
|
+
template<> constexpr const char* fixed_int_name<uint16_t>() { return "UInt16"; }
|
|
67
|
+
template<> constexpr const char* fixed_int_name<uint32_t>() { return "UInt32"; }
|
|
68
|
+
template<> constexpr const char* fixed_int_name<uint64_t>() { return "UInt64"; }
|
|
69
|
+
|
|
70
|
+
// --- Checked arithmetic ---
|
|
71
|
+
|
|
72
|
+
template<typename T>
|
|
73
|
+
constexpr T add_check(T a, T b) {
|
|
74
|
+
T result;
|
|
75
|
+
if (__builtin_add_overflow(a, b, &result)) {
|
|
76
|
+
raise_fixedint_overflow("{} overflow in addition", fixed_int_name<T>());
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
template<typename T>
|
|
82
|
+
constexpr T sub_check(T a, T b) {
|
|
83
|
+
T result;
|
|
84
|
+
if (__builtin_sub_overflow(a, b, &result)) {
|
|
85
|
+
raise_fixedint_overflow("{} overflow in subtraction", fixed_int_name<T>());
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
template<typename T>
|
|
91
|
+
constexpr T mul_check(T a, T b) {
|
|
92
|
+
T result;
|
|
93
|
+
if (__builtin_mul_overflow(a, b, &result)) {
|
|
94
|
+
raise_fixedint_overflow("{} overflow in multiplication", fixed_int_name<T>());
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Python floor division: round toward negative infinity.
|
|
100
|
+
// Divisor must be non-zero (caller's responsibility).
|
|
101
|
+
template<typename T>
|
|
102
|
+
constexpr T div_floor(T a, T b) {
|
|
103
|
+
if constexpr (std::is_signed_v<T>) {
|
|
104
|
+
if (a == std::numeric_limits<T>::min() && b == static_cast<T>(-1)) [[unlikely]] {
|
|
105
|
+
raise_fixedint_overflow("integer overflow in division");
|
|
106
|
+
}
|
|
107
|
+
T q = a / b;
|
|
108
|
+
T r = a % b;
|
|
109
|
+
if (r != 0 && ((r < 0) != (b < 0))) {
|
|
110
|
+
q -= 1;
|
|
111
|
+
}
|
|
112
|
+
return q;
|
|
113
|
+
} else {
|
|
114
|
+
return a / b;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Python modulo: result has same sign as divisor.
|
|
119
|
+
// Divisor must be non-zero (caller's responsibility).
|
|
120
|
+
template<typename T>
|
|
121
|
+
constexpr T mod_floor(T a, T b) {
|
|
122
|
+
if constexpr (std::is_signed_v<T>) {
|
|
123
|
+
if (a == std::numeric_limits<T>::min() && b == static_cast<T>(-1)) [[unlikely]] {
|
|
124
|
+
return 0; // Python: INT_MIN % -1 == 0
|
|
125
|
+
}
|
|
126
|
+
T r = a % b;
|
|
127
|
+
if (r != 0 && ((r < 0) != (b < 0))) {
|
|
128
|
+
r += b;
|
|
129
|
+
}
|
|
130
|
+
return r;
|
|
131
|
+
} else {
|
|
132
|
+
return a % b;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Checked variants: also check for division by zero.
|
|
137
|
+
template<typename T>
|
|
138
|
+
constexpr T div_check(T a, T b) {
|
|
139
|
+
if (b == 0) [[unlikely]] {
|
|
140
|
+
raise_zero_division_error("integer division or modulo by zero");
|
|
141
|
+
}
|
|
142
|
+
return div_floor(a, b);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
template<typename T>
|
|
146
|
+
constexpr T mod_check(T a, T b) {
|
|
147
|
+
if (b == 0) [[unlikely]] {
|
|
148
|
+
raise_zero_division_error("integer modulo by zero");
|
|
149
|
+
}
|
|
150
|
+
return mod_floor(a, b);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
template<typename T>
|
|
154
|
+
constexpr T neg_check(T a) {
|
|
155
|
+
static_assert(std::is_signed_v<T>, "Negation only supported on signed types");
|
|
156
|
+
if (a == std::numeric_limits<T>::min()) {
|
|
157
|
+
raise_fixedint_overflow("{} overflow in negation", fixed_int_name<T>());
|
|
158
|
+
}
|
|
159
|
+
return -a;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
template<typename T>
|
|
163
|
+
constexpr T lshift_check(T a, T b) {
|
|
164
|
+
if constexpr (std::is_signed_v<T>) {
|
|
165
|
+
if (b < 0) {
|
|
166
|
+
raise_value_error("negative shift count");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
constexpr int bits = sizeof(T) * 8;
|
|
170
|
+
if (b >= static_cast<T>(bits)) {
|
|
171
|
+
raise_fixedint_overflow("{} overflow in left shift", fixed_int_name<T>());
|
|
172
|
+
}
|
|
173
|
+
using U = std::make_unsigned_t<T>;
|
|
174
|
+
T result = static_cast<T>(static_cast<U>(a) << static_cast<U>(b));
|
|
175
|
+
if ((result >> b) != a) {
|
|
176
|
+
raise_fixedint_overflow("{} overflow in left shift", fixed_int_name<T>());
|
|
177
|
+
}
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
template<typename T>
|
|
182
|
+
constexpr T rshift_check(T a, T b) {
|
|
183
|
+
if constexpr (std::is_signed_v<T>) {
|
|
184
|
+
if (b < 0) {
|
|
185
|
+
raise_value_error("negative shift count");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
constexpr int bits = sizeof(T) * 8;
|
|
189
|
+
if (b >= static_cast<T>(bits)) {
|
|
190
|
+
raise_fixedint_overflow("{} shift count too large", fixed_int_name<T>());
|
|
191
|
+
}
|
|
192
|
+
return a >> b;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
template<typename T>
|
|
196
|
+
constexpr T pow_check(T base, T exp) {
|
|
197
|
+
if constexpr (std::is_signed_v<T>) {
|
|
198
|
+
if (exp < 0) {
|
|
199
|
+
// TPy-specific limitation: int**neg returns float in CPython, but
|
|
200
|
+
// our static return type is T. Stays panic (not raise_fixedint_overflow)
|
|
201
|
+
// because it's a language-shape issue, not a numeric overflow -- the
|
|
202
|
+
// future fixed-int policy switch can never make this branch "none".
|
|
203
|
+
tpy_panic("Negative exponent not supported (would require float)");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
T result;
|
|
207
|
+
if (!try_pow(base, exp, result)) {
|
|
208
|
+
raise_fixedint_overflow("{} overflow in power", fixed_int_name<T>());
|
|
209
|
+
}
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// --- Checked cast between fixed-int types ---
|
|
214
|
+
|
|
215
|
+
template<typename To, typename From>
|
|
216
|
+
constexpr To int_cast_check(From v) {
|
|
217
|
+
if constexpr (std::is_signed_v<From> && std::is_unsigned_v<To>) {
|
|
218
|
+
if (v < 0 || static_cast<std::make_unsigned_t<From>>(v) > std::numeric_limits<To>::max()) {
|
|
219
|
+
raise_fixedint_overflow("{} overflow: value out of range", fixed_int_name<To>());
|
|
220
|
+
}
|
|
221
|
+
} else if constexpr (std::is_unsigned_v<From> && std::is_signed_v<To>) {
|
|
222
|
+
if (v > static_cast<std::make_unsigned_t<To>>(std::numeric_limits<To>::max())) {
|
|
223
|
+
raise_fixedint_overflow("{} overflow: value out of range", fixed_int_name<To>());
|
|
224
|
+
}
|
|
225
|
+
} else if constexpr (sizeof(From) > sizeof(To)) {
|
|
226
|
+
if (v < static_cast<From>(std::numeric_limits<To>::min()) ||
|
|
227
|
+
v > static_cast<From>(std::numeric_limits<To>::max())) {
|
|
228
|
+
raise_fixedint_overflow("{} overflow: value out of range", fixed_int_name<To>());
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return static_cast<To>(v);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// --- Conversion from other types ---
|
|
235
|
+
|
|
236
|
+
template<typename T>
|
|
237
|
+
T from_float_check(double v) {
|
|
238
|
+
if (std::isnan(v)) {
|
|
239
|
+
raise_value_error("cannot convert float NaN to integer");
|
|
240
|
+
}
|
|
241
|
+
if (std::isinf(v)) {
|
|
242
|
+
raise_overflow_error("cannot convert float infinity to integer");
|
|
243
|
+
}
|
|
244
|
+
v = std::trunc(v);
|
|
245
|
+
if constexpr (sizeof(T) <= 4) {
|
|
246
|
+
// double represents all <=32-bit integer values exactly
|
|
247
|
+
constexpr auto lo = static_cast<double>(std::numeric_limits<T>::min());
|
|
248
|
+
constexpr auto hi = static_cast<double>(std::numeric_limits<T>::max());
|
|
249
|
+
if (v < lo || v > hi) {
|
|
250
|
+
raise_fixedint_overflow("{} overflow: float value out of range",
|
|
251
|
+
fixed_int_name<T>());
|
|
252
|
+
}
|
|
253
|
+
} else if constexpr (std::is_signed_v<T>) {
|
|
254
|
+
// int64_t range [-2^63, 2^63-1]: use exact power-of-2 bounds
|
|
255
|
+
// to avoid static_cast<double>(max) rounding up past the true max
|
|
256
|
+
constexpr double lo = -9223372036854775808.0; // -2^63, exact
|
|
257
|
+
constexpr double hi = 9223372036854775808.0; // 2^63, exact
|
|
258
|
+
if (v < lo || v >= hi) {
|
|
259
|
+
raise_fixedint_overflow("{} overflow: float value out of range",
|
|
260
|
+
fixed_int_name<T>());
|
|
261
|
+
}
|
|
262
|
+
} else {
|
|
263
|
+
// uint64_t range [0, 2^64-1]: 2^64 is exact in double
|
|
264
|
+
constexpr double hi = 18446744073709551616.0; // 2^64, exact
|
|
265
|
+
if (v < 0.0 || v >= hi) {
|
|
266
|
+
raise_fixedint_overflow("{} overflow: float value out of range",
|
|
267
|
+
fixed_int_name<T>());
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return static_cast<T>(v);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
template<typename T>
|
|
274
|
+
T from_str_check(std::string_view s) {
|
|
275
|
+
size_t start = 0;
|
|
276
|
+
while (start < s.size() && std::isspace(static_cast<unsigned char>(s[start]))) ++start;
|
|
277
|
+
size_t end = s.size();
|
|
278
|
+
while (end > start && std::isspace(static_cast<unsigned char>(s[end - 1]))) --end;
|
|
279
|
+
|
|
280
|
+
auto type_name = fixed_int_name<T>();
|
|
281
|
+
|
|
282
|
+
if (start >= end) {
|
|
283
|
+
raise_value_error("invalid literal for {}() with base 10: '{}'", type_name, s);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
std::string trimmed(s.substr(start, end - start));
|
|
287
|
+
char* endptr;
|
|
288
|
+
errno = 0;
|
|
289
|
+
|
|
290
|
+
if constexpr (std::is_signed_v<T>) {
|
|
291
|
+
long long result = std::strtoll(trimmed.c_str(), &endptr, 10);
|
|
292
|
+
if (endptr != trimmed.c_str() + trimmed.size()) {
|
|
293
|
+
raise_value_error("invalid literal for {}() with base 10: '{}'", type_name, s);
|
|
294
|
+
}
|
|
295
|
+
if (errno == ERANGE || result < static_cast<long long>(std::numeric_limits<T>::min())
|
|
296
|
+
|| result > static_cast<long long>(std::numeric_limits<T>::max())) {
|
|
297
|
+
raise_fixedint_overflow("{} overflow: value out of range for '{}'", type_name, s);
|
|
298
|
+
}
|
|
299
|
+
return static_cast<T>(result);
|
|
300
|
+
} else {
|
|
301
|
+
// Check for negative sign on unsigned types
|
|
302
|
+
if (trimmed[0] == '-') {
|
|
303
|
+
raise_fixedint_overflow("{} overflow: negative value for unsigned type '{}'",
|
|
304
|
+
type_name, s);
|
|
305
|
+
}
|
|
306
|
+
unsigned long long result = std::strtoull(trimmed.c_str(), &endptr, 10);
|
|
307
|
+
if (endptr != trimmed.c_str() + trimmed.size()) {
|
|
308
|
+
raise_value_error("invalid literal for {}() with base 10: '{}'", type_name, s);
|
|
309
|
+
}
|
|
310
|
+
if (errno == ERANGE || result > static_cast<unsigned long long>(std::numeric_limits<T>::max())) {
|
|
311
|
+
raise_fixedint_overflow("{} overflow: value out of range for '{}'", type_name, s);
|
|
312
|
+
}
|
|
313
|
+
return static_cast<T>(result);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
} // namespace tpy
|