From aa68d2d8f142724979470c5947617e1abb925512 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Fri, 31 Oct 2025 23:23:35 +0100 Subject: [PATCH 01/17] feat: fuzzing --- build.zig | 122 +- build/compiler_rt.zig | 276 +++ build/compiler_rt/aarch64_outline_atomics.zig | 2127 +++++++++++++++++ build/compiler_rt/absv.zig | 26 + build/compiler_rt/absvdi2.zig | 12 + build/compiler_rt/absvdi2_test.zig | 0 build/compiler_rt/absvsi2.zig | 12 + build/compiler_rt/absvsi2_test.zig | 0 build/compiler_rt/absvti2.zig | 12 + build/compiler_rt/absvti2_test.zig | 0 build/compiler_rt/adddf3.zig | 20 + build/compiler_rt/addf3.zig | 171 ++ build/compiler_rt/addf3_test.zig | 0 build/compiler_rt/addhf3.zig | 12 + build/compiler_rt/addo.zig | 46 + build/compiler_rt/addodi4_test.zig | 0 build/compiler_rt/addosi4_test.zig | 0 build/compiler_rt/addoti4_test.zig | 0 build/compiler_rt/addsf3.zig | 20 + build/compiler_rt/addtf3.zig | 21 + build/compiler_rt/addvsi3.zig | 26 + build/compiler_rt/addxf3.zig | 12 + build/compiler_rt/arm.zig | 267 +++ build/compiler_rt/atomics.zig | 616 +++++ build/compiler_rt/aulldiv.zig | 90 + build/compiler_rt/aullrem.zig | 91 + build/compiler_rt/bcmp.zig | 30 + build/compiler_rt/bitreverse.zig | 65 + build/compiler_rt/bitreversedi2_test.zig | 0 build/compiler_rt/bitreversesi2_test.zig | 0 build/compiler_rt/bitreverseti2_test.zig | 0 build/compiler_rt/bswap.zig | 85 + build/compiler_rt/bswapdi2_test.zig | 0 build/compiler_rt/bswapsi2_test.zig | 0 build/compiler_rt/bswapti2_test.zig | 0 build/compiler_rt/ceil.zig | 238 ++ build/compiler_rt/clear_cache.zig | 202 ++ build/compiler_rt/clzdi2_test.zig | 0 build/compiler_rt/clzsi2_test.zig | 0 build/compiler_rt/clzti2_test.zig | 0 build/compiler_rt/cmp.zig | 68 + build/compiler_rt/cmpdf2.zig | 68 + build/compiler_rt/cmpdi2_test.zig | 0 build/compiler_rt/cmphf2.zig | 50 + build/compiler_rt/cmpsf2.zig | 68 + build/compiler_rt/cmpsi2_test.zig | 0 build/compiler_rt/cmptf2.zig | 105 + build/compiler_rt/cmpti2_test.zig | 0 build/compiler_rt/cmpxf2.zig | 50 + build/compiler_rt/common.zig | 300 +++ build/compiler_rt/comparedf2_test.zig | 0 build/compiler_rt/comparef.zig | 129 + build/compiler_rt/comparesf2_test.zig | 0 build/compiler_rt/cos.zig | 171 ++ build/compiler_rt/count0bits.zig | 246 ++ build/compiler_rt/ctzdi2_test.zig | 0 build/compiler_rt/ctzsi2_test.zig | 0 build/compiler_rt/ctzti2_test.zig | 0 build/compiler_rt/divc3.zig | 60 + build/compiler_rt/divc3_test.zig | 0 build/compiler_rt/divdc3.zig | 13 + build/compiler_rt/divdf3.zig | 229 ++ build/compiler_rt/divdf3_test.zig | 0 build/compiler_rt/divhc3.zig | 13 + build/compiler_rt/divhf3.zig | 11 + build/compiler_rt/divmodei4.zig | 52 + build/compiler_rt/divsc3.zig | 13 + build/compiler_rt/divsf3.zig | 210 ++ build/compiler_rt/divsf3_test.zig | 0 build/compiler_rt/divtc3.zig | 15 + build/compiler_rt/divtf3.zig | 245 ++ build/compiler_rt/divtf3_test.zig | 0 build/compiler_rt/divti3.zig | 41 + build/compiler_rt/divti3_test.zig | 0 build/compiler_rt/divxc3.zig | 13 + build/compiler_rt/divxf3.zig | 210 ++ build/compiler_rt/divxf3_test.zig | 0 build/compiler_rt/emutls.zig | 380 +++ build/compiler_rt/exp.zig | 311 +++ build/compiler_rt/exp2.zig | 535 +++++ build/compiler_rt/extenddftf2.zig | 21 + build/compiler_rt/extenddfxf2.zig | 12 + build/compiler_rt/extendf.zig | 139 ++ build/compiler_rt/extendf_test.zig | 0 build/compiler_rt/extendhfdf2.zig | 12 + build/compiler_rt/extendhfsf2.zig | 25 + build/compiler_rt/extendhftf2.zig | 12 + build/compiler_rt/extendhfxf2.zig | 12 + build/compiler_rt/extendsfdf2.zig | 20 + build/compiler_rt/extendsftf2.zig | 21 + build/compiler_rt/extendsfxf2.zig | 12 + build/compiler_rt/extendxftf2.zig | 43 + build/compiler_rt/fabs.zig | 57 + build/compiler_rt/ffsdi2_test.zig | 0 build/compiler_rt/ffssi2_test.zig | 0 build/compiler_rt/ffsti2_test.zig | 0 build/compiler_rt/fixdfdi.zig | 21 + build/compiler_rt/fixdfei.zig | 15 + build/compiler_rt/fixdfsi.zig | 20 + build/compiler_rt/fixdfti.zig | 23 + build/compiler_rt/fixhfdi.zig | 12 + build/compiler_rt/fixhfei.zig | 15 + build/compiler_rt/fixhfsi.zig | 12 + build/compiler_rt/fixhfti.zig | 23 + build/compiler_rt/fixint_test.zig | 0 build/compiler_rt/fixsfdi.zig | 21 + build/compiler_rt/fixsfei.zig | 15 + build/compiler_rt/fixsfsi.zig | 20 + build/compiler_rt/fixsfti.zig | 23 + build/compiler_rt/fixtfdi.zig | 21 + build/compiler_rt/fixtfei.zig | 15 + build/compiler_rt/fixtfsi.zig | 21 + build/compiler_rt/fixtfti.zig | 25 + build/compiler_rt/fixunsdfdi.zig | 21 + build/compiler_rt/fixunsdfei.zig | 15 + build/compiler_rt/fixunsdfsi.zig | 20 + build/compiler_rt/fixunsdfti.zig | 23 + build/compiler_rt/fixunshfdi.zig | 12 + build/compiler_rt/fixunshfei.zig | 15 + build/compiler_rt/fixunshfsi.zig | 12 + build/compiler_rt/fixunshfti.zig | 23 + build/compiler_rt/fixunssfdi.zig | 21 + build/compiler_rt/fixunssfei.zig | 15 + build/compiler_rt/fixunssfsi.zig | 20 + build/compiler_rt/fixunssfti.zig | 23 + build/compiler_rt/fixunstfdi.zig | 21 + build/compiler_rt/fixunstfei.zig | 15 + build/compiler_rt/fixunstfsi.zig | 21 + build/compiler_rt/fixunstfti.zig | 25 + build/compiler_rt/fixunsxfdi.zig | 12 + build/compiler_rt/fixunsxfei.zig | 15 + build/compiler_rt/fixunsxfsi.zig | 12 + build/compiler_rt/fixunsxfti.zig | 23 + build/compiler_rt/fixxfdi.zig | 12 + build/compiler_rt/fixxfei.zig | 15 + build/compiler_rt/fixxfsi.zig | 12 + build/compiler_rt/fixxfti.zig | 23 + build/compiler_rt/float_from_int.zig | 107 + build/compiler_rt/float_from_int_test.zig | 0 build/compiler_rt/floatdidf.zig | 21 + build/compiler_rt/floatdihf.zig | 12 + build/compiler_rt/floatdisf.zig | 21 + build/compiler_rt/floatditf.zig | 21 + build/compiler_rt/floatdixf.zig | 12 + build/compiler_rt/floateidf.zig | 15 + build/compiler_rt/floateihf.zig | 15 + build/compiler_rt/floateisf.zig | 15 + build/compiler_rt/floateitf.zig | 15 + build/compiler_rt/floateixf.zig | 15 + build/compiler_rt/floatsidf.zig | 20 + build/compiler_rt/floatsihf.zig | 12 + build/compiler_rt/floatsisf.zig | 20 + build/compiler_rt/floatsitf.zig | 21 + build/compiler_rt/floatsixf.zig | 12 + build/compiler_rt/floattidf.zig | 21 + build/compiler_rt/floattihf.zig | 21 + build/compiler_rt/floattisf.zig | 21 + build/compiler_rt/floattitf.zig | 23 + build/compiler_rt/floattixf.zig | 21 + build/compiler_rt/floatundidf.zig | 21 + build/compiler_rt/floatundihf.zig | 12 + build/compiler_rt/floatundisf.zig | 21 + build/compiler_rt/floatunditf.zig | 21 + build/compiler_rt/floatundixf.zig | 12 + build/compiler_rt/floatuneidf.zig | 15 + build/compiler_rt/floatuneihf.zig | 15 + build/compiler_rt/floatuneisf.zig | 15 + build/compiler_rt/floatuneitf.zig | 15 + build/compiler_rt/floatuneixf.zig | 15 + build/compiler_rt/floatunsidf.zig | 20 + build/compiler_rt/floatunsihf.zig | 12 + build/compiler_rt/floatunsisf.zig | 20 + build/compiler_rt/floatunsitf.zig | 21 + build/compiler_rt/floatunsixf.zig | 12 + build/compiler_rt/floatuntidf.zig | 21 + build/compiler_rt/floatuntihf.zig | 21 + build/compiler_rt/floatuntisf.zig | 21 + build/compiler_rt/floatuntitf.zig | 23 + build/compiler_rt/floatuntixf.zig | 21 + build/compiler_rt/floor.zig | 238 ++ build/compiler_rt/fma.zig | 353 +++ build/compiler_rt/fmax.zig | 77 + build/compiler_rt/fmin.zig | 77 + build/compiler_rt/fmod.zig | 389 +++ build/compiler_rt/fmodq_test.zig | 0 build/compiler_rt/fmodx_test.zig | 0 build/compiler_rt/gedf2.zig | 36 + build/compiler_rt/gehf2.zig | 23 + build/compiler_rt/gesf2.zig | 36 + build/compiler_rt/getf2.zig | 30 + build/compiler_rt/gexf2.zig | 17 + build/compiler_rt/hexagon.zig | 1787 ++++++++++++++ build/compiler_rt/int.zig | 664 +++++ build/compiler_rt/int_from_float.zig | 107 + build/compiler_rt/int_from_float_test.zig | 0 build/compiler_rt/log.zig | 231 ++ build/compiler_rt/log10.zig | 261 ++ build/compiler_rt/log2.zig | 252 ++ build/compiler_rt/memcmp.zig | 30 + build/compiler_rt/memcpy.zig | 230 ++ build/compiler_rt/memmove.zig | 252 ++ build/compiler_rt/memset.zig | 33 + build/compiler_rt/modti3.zig | 44 + build/compiler_rt/modti3_test.zig | 0 build/compiler_rt/mulXi3.zig | 101 + build/compiler_rt/mulXi3_test.zig | 0 build/compiler_rt/mulc3.zig | 79 + build/compiler_rt/mulc3_test.zig | 0 build/compiler_rt/muldc3.zig | 14 + build/compiler_rt/muldf3.zig | 20 + build/compiler_rt/mulf3.zig | 203 ++ build/compiler_rt/mulf3_test.zig | 0 build/compiler_rt/mulhc3.zig | 14 + build/compiler_rt/mulhf3.zig | 12 + build/compiler_rt/mulo.zig | 79 + build/compiler_rt/mulodi4_test.zig | 0 build/compiler_rt/mulosi4_test.zig | 0 build/compiler_rt/muloti4_test.zig | 0 build/compiler_rt/mulsc3.zig | 14 + build/compiler_rt/mulsf3.zig | 20 + build/compiler_rt/multc3.zig | 16 + build/compiler_rt/multf3.zig | 21 + build/compiler_rt/mulvsi3.zig | 26 + build/compiler_rt/mulxc3.zig | 14 + build/compiler_rt/mulxf3.zig | 12 + build/compiler_rt/negXi2.zig | 41 + build/compiler_rt/negdf2.zig | 19 + build/compiler_rt/negdi2_test.zig | 0 build/compiler_rt/neghf2.zig | 11 + build/compiler_rt/negsf2.zig | 19 + build/compiler_rt/negsi2_test.zig | 0 build/compiler_rt/negtf2.zig | 13 + build/compiler_rt/negti2_test.zig | 0 build/compiler_rt/negv.zig | 46 + build/compiler_rt/negvdi2_test.zig | 0 build/compiler_rt/negvsi2_test.zig | 0 build/compiler_rt/negvti2_test.zig | 0 build/compiler_rt/negxf2.zig | 11 + build/compiler_rt/os_version_check.zig | 63 + build/compiler_rt/parity.zig | 44 + build/compiler_rt/paritydi2_test.zig | 0 build/compiler_rt/paritysi2_test.zig | 0 build/compiler_rt/parityti2_test.zig | 0 build/compiler_rt/popcount.zig | 56 + build/compiler_rt/popcountdi2_test.zig | 0 build/compiler_rt/popcountsi2_test.zig | 0 build/compiler_rt/popcountti2_test.zig | 0 build/compiler_rt/powiXf2.zig | 60 + build/compiler_rt/powiXf2_test.zig | 0 build/compiler_rt/rem_pio2.zig | 194 ++ build/compiler_rt/rem_pio2_large.zig | 503 ++++ build/compiler_rt/rem_pio2f.zig | 70 + build/compiler_rt/round.zig | 198 ++ build/compiler_rt/shift.zig | 143 ++ build/compiler_rt/shift_test.zig | 0 build/compiler_rt/sin.zig | 203 ++ build/compiler_rt/sincos.zig | 281 +++ build/compiler_rt/sqrt.zig | 750 ++++++ build/compiler_rt/ssp.zig | 143 ++ build/compiler_rt/stack_probe.zig | 271 +++ build/compiler_rt/strlen.zig | 10 + build/compiler_rt/subdf3.zig | 25 + build/compiler_rt/subhf3.zig | 13 + build/compiler_rt/subo.zig | 47 + build/compiler_rt/subodi4_test.zig | 0 build/compiler_rt/subosi4_test.zig | 0 build/compiler_rt/suboti4_test.zig | 0 build/compiler_rt/subsf3.zig | 25 + build/compiler_rt/subtf3.zig | 26 + build/compiler_rt/subvdi3.zig | 26 + build/compiler_rt/subvsi3.zig | 26 + build/compiler_rt/subxf3.zig | 15 + build/compiler_rt/tan.zig | 182 ++ build/compiler_rt/trig.zig | 273 +++ build/compiler_rt/trunc.zig | 153 ++ build/compiler_rt/truncdfhf2.zig | 19 + build/compiler_rt/truncdfsf2.zig | 20 + build/compiler_rt/truncf.zig | 186 ++ build/compiler_rt/truncf_test.zig | 0 build/compiler_rt/truncsfhf2.zig | 25 + build/compiler_rt/trunctfdf2.zig | 21 + build/compiler_rt/trunctfhf2.zig | 12 + build/compiler_rt/trunctfsf2.zig | 21 + build/compiler_rt/trunctfxf2.zig | 68 + build/compiler_rt/truncxfdf2.zig | 12 + build/compiler_rt/truncxfhf2.zig | 12 + build/compiler_rt/truncxfsf2.zig | 12 + build/compiler_rt/ucmpdi2_test.zig | 0 build/compiler_rt/ucmpsi2_test.zig | 0 build/compiler_rt/ucmpti2_test.zig | 0 build/compiler_rt/udivmod.zig | 149 ++ build/compiler_rt/udivmoddi4_test.zig | 0 build/compiler_rt/udivmodei4.zig | 149 ++ build/compiler_rt/udivmodsi4_test.zig | 0 build/compiler_rt/udivmodti4.zig | 28 + build/compiler_rt/udivmodti4_test.zig | 0 build/compiler_rt/udivti3.zig | 24 + build/compiler_rt/umodti3.zig | 28 + build/compiler_rt/unorddf2.zig | 20 + build/compiler_rt/unordhf2.zig | 12 + build/compiler_rt/unordsf2.zig | 20 + build/compiler_rt/unordtf2.zig | 18 + build/compiler_rt/unordxf2.zig | 12 + src/afl.c | 84 + src/behavior.zig | 426 +++- src/fuzz.zig | 22 + tests/{ => behavior}/001-basic-types.buzz | 0 tests/{ => behavior}/002-operators.buzz | 0 tests/{ => behavior}/003-control-flow.buzz | 0 tests/{ => behavior}/004-lists.buzz | 0 tests/{ => behavior}/005-maps.buzz | 0 tests/{ => behavior}/006-enums.buzz | 0 tests/{ => behavior}/007-objects.buzz | 0 tests/{ => behavior}/008-inline-catch.buzz | 0 tests/{ => behavior}/009-gc.buzz | 0 .../{ => behavior}/010-placeholder-cycle.buzz | 0 .../011-list-map-properties.buzz | 0 tests/{ => behavior}/012-lambda.buzz | 0 tests/{ => behavior}/013-import-export.buzz | 0 tests/{ => behavior}/014-import-lib.buzz | 0 tests/{ => behavior}/015-interpolation.buzz | 0 tests/{ => behavior}/016-optionals.buzz | 0 tests/{ => behavior}/017-for.buzz | 0 tests/{ => behavior}/018-foreach.buzz | 0 tests/{ => behavior}/019-is.buzz | 0 tests/{ => behavior}/021-upvalues.buzz | 0 tests/{ => behavior}/023-std.buzz | 0 tests/{ => behavior}/025-fs.buzz | 0 tests/{ => behavior}/026-break-continue.buzz | 0 tests/{ => behavior}/028-math.buzz | 0 .../{ => behavior}/029-default-arguments.buzz | 0 tests/{ => behavior}/030-str.buzz | 0 tests/{ => behavior}/032-debug.buzz | 0 tests/{ => behavior}/033-invoke.buzz | 0 tests/{ => behavior}/034-scope.buzz | 0 tests/{ => behavior}/035-const-expr.buzz | 0 tests/{ => behavior}/036-pattern.buzz | 0 tests/{ => behavior}/037-dead-branches.buzz | 0 tests/{ => behavior}/038-fibers.buzz | 0 tests/{ => behavior}/039-buffer.buzz | 0 tests/{ => behavior}/040-bitwise.buzz | 0 tests/{ => behavior}/041-iterator.buzz | 0 .../{ => behavior}/042-anonymous-objects.buzz | 0 tests/{ => behavior}/044-break-continue.buzz | 0 tests/{ => behavior}/045-mutual-import.buzz | 0 tests/{ => behavior}/046-try-catch.buzz | 0 tests/{ => behavior}/047-if-arrow.buzz | 0 tests/{ => behavior}/048-generics.buzz | 0 tests/{ => behavior}/050-protocols.buzz | 0 tests/{ => behavior}/051-functional.buzz | 0 tests/{ => behavior}/052-inline-if.buzz | 0 tests/{ => behavior}/053-range.buzz | 0 tests/{ => behavior}/056-crypto.buzz | 0 tests/{ => behavior}/057-any.buzz | 0 tests/{ => behavior}/059-types-as-value.buzz | 0 .../{ => behavior}/060-free-identifiers.buzz | 0 tests/{ => behavior}/061-utf8.buzz | 0 tests/{ => behavior}/062-discarded-value.buzz | 0 .../{ => behavior}/063-nullable-default.buzz | 0 .../{ => behavior}/064-throw-inside-try.buzz | 0 .../{ => behavior}/065-inferred-var-type.buzz | 0 tests/{ => behavior}/066-object-generics.buzz | 0 tests/{ => behavior}/069-named-expr.buzz | 0 .../{ => behavior}/070-block-expression.buzz | 0 tests/{ => behavior}/071-tail-call.buzz | 0 tests/{ => behavior}/072-labels.buzz | 0 tests/{ => behavior}/073-tuples.buzz | 0 .../{ => behavior}/074-checked-subscript.buzz | 0 .../{ => behavior}/075-composite-assign.buzz | 0 369 files changed, 21214 insertions(+), 92 deletions(-) create mode 100644 build/compiler_rt.zig create mode 100644 build/compiler_rt/aarch64_outline_atomics.zig create mode 100644 build/compiler_rt/absv.zig create mode 100644 build/compiler_rt/absvdi2.zig create mode 100644 build/compiler_rt/absvdi2_test.zig create mode 100644 build/compiler_rt/absvsi2.zig create mode 100644 build/compiler_rt/absvsi2_test.zig create mode 100644 build/compiler_rt/absvti2.zig create mode 100644 build/compiler_rt/absvti2_test.zig create mode 100644 build/compiler_rt/adddf3.zig create mode 100644 build/compiler_rt/addf3.zig create mode 100644 build/compiler_rt/addf3_test.zig create mode 100644 build/compiler_rt/addhf3.zig create mode 100644 build/compiler_rt/addo.zig create mode 100644 build/compiler_rt/addodi4_test.zig create mode 100644 build/compiler_rt/addosi4_test.zig create mode 100644 build/compiler_rt/addoti4_test.zig create mode 100644 build/compiler_rt/addsf3.zig create mode 100644 build/compiler_rt/addtf3.zig create mode 100644 build/compiler_rt/addvsi3.zig create mode 100644 build/compiler_rt/addxf3.zig create mode 100644 build/compiler_rt/arm.zig create mode 100644 build/compiler_rt/atomics.zig create mode 100644 build/compiler_rt/aulldiv.zig create mode 100644 build/compiler_rt/aullrem.zig create mode 100644 build/compiler_rt/bcmp.zig create mode 100644 build/compiler_rt/bitreverse.zig create mode 100644 build/compiler_rt/bitreversedi2_test.zig create mode 100644 build/compiler_rt/bitreversesi2_test.zig create mode 100644 build/compiler_rt/bitreverseti2_test.zig create mode 100644 build/compiler_rt/bswap.zig create mode 100644 build/compiler_rt/bswapdi2_test.zig create mode 100644 build/compiler_rt/bswapsi2_test.zig create mode 100644 build/compiler_rt/bswapti2_test.zig create mode 100644 build/compiler_rt/ceil.zig create mode 100644 build/compiler_rt/clear_cache.zig create mode 100644 build/compiler_rt/clzdi2_test.zig create mode 100644 build/compiler_rt/clzsi2_test.zig create mode 100644 build/compiler_rt/clzti2_test.zig create mode 100644 build/compiler_rt/cmp.zig create mode 100644 build/compiler_rt/cmpdf2.zig create mode 100644 build/compiler_rt/cmpdi2_test.zig create mode 100644 build/compiler_rt/cmphf2.zig create mode 100644 build/compiler_rt/cmpsf2.zig create mode 100644 build/compiler_rt/cmpsi2_test.zig create mode 100644 build/compiler_rt/cmptf2.zig create mode 100644 build/compiler_rt/cmpti2_test.zig create mode 100644 build/compiler_rt/cmpxf2.zig create mode 100644 build/compiler_rt/common.zig create mode 100644 build/compiler_rt/comparedf2_test.zig create mode 100644 build/compiler_rt/comparef.zig create mode 100644 build/compiler_rt/comparesf2_test.zig create mode 100644 build/compiler_rt/cos.zig create mode 100644 build/compiler_rt/count0bits.zig create mode 100644 build/compiler_rt/ctzdi2_test.zig create mode 100644 build/compiler_rt/ctzsi2_test.zig create mode 100644 build/compiler_rt/ctzti2_test.zig create mode 100644 build/compiler_rt/divc3.zig create mode 100644 build/compiler_rt/divc3_test.zig create mode 100644 build/compiler_rt/divdc3.zig create mode 100644 build/compiler_rt/divdf3.zig create mode 100644 build/compiler_rt/divdf3_test.zig create mode 100644 build/compiler_rt/divhc3.zig create mode 100644 build/compiler_rt/divhf3.zig create mode 100644 build/compiler_rt/divmodei4.zig create mode 100644 build/compiler_rt/divsc3.zig create mode 100644 build/compiler_rt/divsf3.zig create mode 100644 build/compiler_rt/divsf3_test.zig create mode 100644 build/compiler_rt/divtc3.zig create mode 100644 build/compiler_rt/divtf3.zig create mode 100644 build/compiler_rt/divtf3_test.zig create mode 100644 build/compiler_rt/divti3.zig create mode 100644 build/compiler_rt/divti3_test.zig create mode 100644 build/compiler_rt/divxc3.zig create mode 100644 build/compiler_rt/divxf3.zig create mode 100644 build/compiler_rt/divxf3_test.zig create mode 100644 build/compiler_rt/emutls.zig create mode 100644 build/compiler_rt/exp.zig create mode 100644 build/compiler_rt/exp2.zig create mode 100644 build/compiler_rt/extenddftf2.zig create mode 100644 build/compiler_rt/extenddfxf2.zig create mode 100644 build/compiler_rt/extendf.zig create mode 100644 build/compiler_rt/extendf_test.zig create mode 100644 build/compiler_rt/extendhfdf2.zig create mode 100644 build/compiler_rt/extendhfsf2.zig create mode 100644 build/compiler_rt/extendhftf2.zig create mode 100644 build/compiler_rt/extendhfxf2.zig create mode 100644 build/compiler_rt/extendsfdf2.zig create mode 100644 build/compiler_rt/extendsftf2.zig create mode 100644 build/compiler_rt/extendsfxf2.zig create mode 100644 build/compiler_rt/extendxftf2.zig create mode 100644 build/compiler_rt/fabs.zig create mode 100644 build/compiler_rt/ffsdi2_test.zig create mode 100644 build/compiler_rt/ffssi2_test.zig create mode 100644 build/compiler_rt/ffsti2_test.zig create mode 100644 build/compiler_rt/fixdfdi.zig create mode 100644 build/compiler_rt/fixdfei.zig create mode 100644 build/compiler_rt/fixdfsi.zig create mode 100644 build/compiler_rt/fixdfti.zig create mode 100644 build/compiler_rt/fixhfdi.zig create mode 100644 build/compiler_rt/fixhfei.zig create mode 100644 build/compiler_rt/fixhfsi.zig create mode 100644 build/compiler_rt/fixhfti.zig create mode 100644 build/compiler_rt/fixint_test.zig create mode 100644 build/compiler_rt/fixsfdi.zig create mode 100644 build/compiler_rt/fixsfei.zig create mode 100644 build/compiler_rt/fixsfsi.zig create mode 100644 build/compiler_rt/fixsfti.zig create mode 100644 build/compiler_rt/fixtfdi.zig create mode 100644 build/compiler_rt/fixtfei.zig create mode 100644 build/compiler_rt/fixtfsi.zig create mode 100644 build/compiler_rt/fixtfti.zig create mode 100644 build/compiler_rt/fixunsdfdi.zig create mode 100644 build/compiler_rt/fixunsdfei.zig create mode 100644 build/compiler_rt/fixunsdfsi.zig create mode 100644 build/compiler_rt/fixunsdfti.zig create mode 100644 build/compiler_rt/fixunshfdi.zig create mode 100644 build/compiler_rt/fixunshfei.zig create mode 100644 build/compiler_rt/fixunshfsi.zig create mode 100644 build/compiler_rt/fixunshfti.zig create mode 100644 build/compiler_rt/fixunssfdi.zig create mode 100644 build/compiler_rt/fixunssfei.zig create mode 100644 build/compiler_rt/fixunssfsi.zig create mode 100644 build/compiler_rt/fixunssfti.zig create mode 100644 build/compiler_rt/fixunstfdi.zig create mode 100644 build/compiler_rt/fixunstfei.zig create mode 100644 build/compiler_rt/fixunstfsi.zig create mode 100644 build/compiler_rt/fixunstfti.zig create mode 100644 build/compiler_rt/fixunsxfdi.zig create mode 100644 build/compiler_rt/fixunsxfei.zig create mode 100644 build/compiler_rt/fixunsxfsi.zig create mode 100644 build/compiler_rt/fixunsxfti.zig create mode 100644 build/compiler_rt/fixxfdi.zig create mode 100644 build/compiler_rt/fixxfei.zig create mode 100644 build/compiler_rt/fixxfsi.zig create mode 100644 build/compiler_rt/fixxfti.zig create mode 100644 build/compiler_rt/float_from_int.zig create mode 100644 build/compiler_rt/float_from_int_test.zig create mode 100644 build/compiler_rt/floatdidf.zig create mode 100644 build/compiler_rt/floatdihf.zig create mode 100644 build/compiler_rt/floatdisf.zig create mode 100644 build/compiler_rt/floatditf.zig create mode 100644 build/compiler_rt/floatdixf.zig create mode 100644 build/compiler_rt/floateidf.zig create mode 100644 build/compiler_rt/floateihf.zig create mode 100644 build/compiler_rt/floateisf.zig create mode 100644 build/compiler_rt/floateitf.zig create mode 100644 build/compiler_rt/floateixf.zig create mode 100644 build/compiler_rt/floatsidf.zig create mode 100644 build/compiler_rt/floatsihf.zig create mode 100644 build/compiler_rt/floatsisf.zig create mode 100644 build/compiler_rt/floatsitf.zig create mode 100644 build/compiler_rt/floatsixf.zig create mode 100644 build/compiler_rt/floattidf.zig create mode 100644 build/compiler_rt/floattihf.zig create mode 100644 build/compiler_rt/floattisf.zig create mode 100644 build/compiler_rt/floattitf.zig create mode 100644 build/compiler_rt/floattixf.zig create mode 100644 build/compiler_rt/floatundidf.zig create mode 100644 build/compiler_rt/floatundihf.zig create mode 100644 build/compiler_rt/floatundisf.zig create mode 100644 build/compiler_rt/floatunditf.zig create mode 100644 build/compiler_rt/floatundixf.zig create mode 100644 build/compiler_rt/floatuneidf.zig create mode 100644 build/compiler_rt/floatuneihf.zig create mode 100644 build/compiler_rt/floatuneisf.zig create mode 100644 build/compiler_rt/floatuneitf.zig create mode 100644 build/compiler_rt/floatuneixf.zig create mode 100644 build/compiler_rt/floatunsidf.zig create mode 100644 build/compiler_rt/floatunsihf.zig create mode 100644 build/compiler_rt/floatunsisf.zig create mode 100644 build/compiler_rt/floatunsitf.zig create mode 100644 build/compiler_rt/floatunsixf.zig create mode 100644 build/compiler_rt/floatuntidf.zig create mode 100644 build/compiler_rt/floatuntihf.zig create mode 100644 build/compiler_rt/floatuntisf.zig create mode 100644 build/compiler_rt/floatuntitf.zig create mode 100644 build/compiler_rt/floatuntixf.zig create mode 100644 build/compiler_rt/floor.zig create mode 100644 build/compiler_rt/fma.zig create mode 100644 build/compiler_rt/fmax.zig create mode 100644 build/compiler_rt/fmin.zig create mode 100644 build/compiler_rt/fmod.zig create mode 100644 build/compiler_rt/fmodq_test.zig create mode 100644 build/compiler_rt/fmodx_test.zig create mode 100644 build/compiler_rt/gedf2.zig create mode 100644 build/compiler_rt/gehf2.zig create mode 100644 build/compiler_rt/gesf2.zig create mode 100644 build/compiler_rt/getf2.zig create mode 100644 build/compiler_rt/gexf2.zig create mode 100644 build/compiler_rt/hexagon.zig create mode 100644 build/compiler_rt/int.zig create mode 100644 build/compiler_rt/int_from_float.zig create mode 100644 build/compiler_rt/int_from_float_test.zig create mode 100644 build/compiler_rt/log.zig create mode 100644 build/compiler_rt/log10.zig create mode 100644 build/compiler_rt/log2.zig create mode 100644 build/compiler_rt/memcmp.zig create mode 100644 build/compiler_rt/memcpy.zig create mode 100644 build/compiler_rt/memmove.zig create mode 100644 build/compiler_rt/memset.zig create mode 100644 build/compiler_rt/modti3.zig create mode 100644 build/compiler_rt/modti3_test.zig create mode 100644 build/compiler_rt/mulXi3.zig create mode 100644 build/compiler_rt/mulXi3_test.zig create mode 100644 build/compiler_rt/mulc3.zig create mode 100644 build/compiler_rt/mulc3_test.zig create mode 100644 build/compiler_rt/muldc3.zig create mode 100644 build/compiler_rt/muldf3.zig create mode 100644 build/compiler_rt/mulf3.zig create mode 100644 build/compiler_rt/mulf3_test.zig create mode 100644 build/compiler_rt/mulhc3.zig create mode 100644 build/compiler_rt/mulhf3.zig create mode 100644 build/compiler_rt/mulo.zig create mode 100644 build/compiler_rt/mulodi4_test.zig create mode 100644 build/compiler_rt/mulosi4_test.zig create mode 100644 build/compiler_rt/muloti4_test.zig create mode 100644 build/compiler_rt/mulsc3.zig create mode 100644 build/compiler_rt/mulsf3.zig create mode 100644 build/compiler_rt/multc3.zig create mode 100644 build/compiler_rt/multf3.zig create mode 100644 build/compiler_rt/mulvsi3.zig create mode 100644 build/compiler_rt/mulxc3.zig create mode 100644 build/compiler_rt/mulxf3.zig create mode 100644 build/compiler_rt/negXi2.zig create mode 100644 build/compiler_rt/negdf2.zig create mode 100644 build/compiler_rt/negdi2_test.zig create mode 100644 build/compiler_rt/neghf2.zig create mode 100644 build/compiler_rt/negsf2.zig create mode 100644 build/compiler_rt/negsi2_test.zig create mode 100644 build/compiler_rt/negtf2.zig create mode 100644 build/compiler_rt/negti2_test.zig create mode 100644 build/compiler_rt/negv.zig create mode 100644 build/compiler_rt/negvdi2_test.zig create mode 100644 build/compiler_rt/negvsi2_test.zig create mode 100644 build/compiler_rt/negvti2_test.zig create mode 100644 build/compiler_rt/negxf2.zig create mode 100644 build/compiler_rt/os_version_check.zig create mode 100644 build/compiler_rt/parity.zig create mode 100644 build/compiler_rt/paritydi2_test.zig create mode 100644 build/compiler_rt/paritysi2_test.zig create mode 100644 build/compiler_rt/parityti2_test.zig create mode 100644 build/compiler_rt/popcount.zig create mode 100644 build/compiler_rt/popcountdi2_test.zig create mode 100644 build/compiler_rt/popcountsi2_test.zig create mode 100644 build/compiler_rt/popcountti2_test.zig create mode 100644 build/compiler_rt/powiXf2.zig create mode 100644 build/compiler_rt/powiXf2_test.zig create mode 100644 build/compiler_rt/rem_pio2.zig create mode 100644 build/compiler_rt/rem_pio2_large.zig create mode 100644 build/compiler_rt/rem_pio2f.zig create mode 100644 build/compiler_rt/round.zig create mode 100644 build/compiler_rt/shift.zig create mode 100644 build/compiler_rt/shift_test.zig create mode 100644 build/compiler_rt/sin.zig create mode 100644 build/compiler_rt/sincos.zig create mode 100644 build/compiler_rt/sqrt.zig create mode 100644 build/compiler_rt/ssp.zig create mode 100644 build/compiler_rt/stack_probe.zig create mode 100644 build/compiler_rt/strlen.zig create mode 100644 build/compiler_rt/subdf3.zig create mode 100644 build/compiler_rt/subhf3.zig create mode 100644 build/compiler_rt/subo.zig create mode 100644 build/compiler_rt/subodi4_test.zig create mode 100644 build/compiler_rt/subosi4_test.zig create mode 100644 build/compiler_rt/suboti4_test.zig create mode 100644 build/compiler_rt/subsf3.zig create mode 100644 build/compiler_rt/subtf3.zig create mode 100644 build/compiler_rt/subvdi3.zig create mode 100644 build/compiler_rt/subvsi3.zig create mode 100644 build/compiler_rt/subxf3.zig create mode 100644 build/compiler_rt/tan.zig create mode 100644 build/compiler_rt/trig.zig create mode 100644 build/compiler_rt/trunc.zig create mode 100644 build/compiler_rt/truncdfhf2.zig create mode 100644 build/compiler_rt/truncdfsf2.zig create mode 100644 build/compiler_rt/truncf.zig create mode 100644 build/compiler_rt/truncf_test.zig create mode 100644 build/compiler_rt/truncsfhf2.zig create mode 100644 build/compiler_rt/trunctfdf2.zig create mode 100644 build/compiler_rt/trunctfhf2.zig create mode 100644 build/compiler_rt/trunctfsf2.zig create mode 100644 build/compiler_rt/trunctfxf2.zig create mode 100644 build/compiler_rt/truncxfdf2.zig create mode 100644 build/compiler_rt/truncxfhf2.zig create mode 100644 build/compiler_rt/truncxfsf2.zig create mode 100644 build/compiler_rt/ucmpdi2_test.zig create mode 100644 build/compiler_rt/ucmpsi2_test.zig create mode 100644 build/compiler_rt/ucmpti2_test.zig create mode 100644 build/compiler_rt/udivmod.zig create mode 100644 build/compiler_rt/udivmoddi4_test.zig create mode 100644 build/compiler_rt/udivmodei4.zig create mode 100644 build/compiler_rt/udivmodsi4_test.zig create mode 100644 build/compiler_rt/udivmodti4.zig create mode 100644 build/compiler_rt/udivmodti4_test.zig create mode 100644 build/compiler_rt/udivti3.zig create mode 100644 build/compiler_rt/umodti3.zig create mode 100644 build/compiler_rt/unorddf2.zig create mode 100644 build/compiler_rt/unordhf2.zig create mode 100644 build/compiler_rt/unordsf2.zig create mode 100644 build/compiler_rt/unordtf2.zig create mode 100644 build/compiler_rt/unordxf2.zig create mode 100644 src/afl.c create mode 100644 src/fuzz.zig rename tests/{ => behavior}/001-basic-types.buzz (100%) rename tests/{ => behavior}/002-operators.buzz (100%) rename tests/{ => behavior}/003-control-flow.buzz (100%) rename tests/{ => behavior}/004-lists.buzz (100%) rename tests/{ => behavior}/005-maps.buzz (100%) rename tests/{ => behavior}/006-enums.buzz (100%) rename tests/{ => behavior}/007-objects.buzz (100%) rename tests/{ => behavior}/008-inline-catch.buzz (100%) rename tests/{ => behavior}/009-gc.buzz (100%) rename tests/{ => behavior}/010-placeholder-cycle.buzz (100%) rename tests/{ => behavior}/011-list-map-properties.buzz (100%) rename tests/{ => behavior}/012-lambda.buzz (100%) rename tests/{ => behavior}/013-import-export.buzz (100%) rename tests/{ => behavior}/014-import-lib.buzz (100%) rename tests/{ => behavior}/015-interpolation.buzz (100%) rename tests/{ => behavior}/016-optionals.buzz (100%) rename tests/{ => behavior}/017-for.buzz (100%) rename tests/{ => behavior}/018-foreach.buzz (100%) rename tests/{ => behavior}/019-is.buzz (100%) rename tests/{ => behavior}/021-upvalues.buzz (100%) rename tests/{ => behavior}/023-std.buzz (100%) rename tests/{ => behavior}/025-fs.buzz (100%) rename tests/{ => behavior}/026-break-continue.buzz (100%) rename tests/{ => behavior}/028-math.buzz (100%) rename tests/{ => behavior}/029-default-arguments.buzz (100%) rename tests/{ => behavior}/030-str.buzz (100%) rename tests/{ => behavior}/032-debug.buzz (100%) rename tests/{ => behavior}/033-invoke.buzz (100%) rename tests/{ => behavior}/034-scope.buzz (100%) rename tests/{ => behavior}/035-const-expr.buzz (100%) rename tests/{ => behavior}/036-pattern.buzz (100%) rename tests/{ => behavior}/037-dead-branches.buzz (100%) rename tests/{ => behavior}/038-fibers.buzz (100%) rename tests/{ => behavior}/039-buffer.buzz (100%) rename tests/{ => behavior}/040-bitwise.buzz (100%) rename tests/{ => behavior}/041-iterator.buzz (100%) rename tests/{ => behavior}/042-anonymous-objects.buzz (100%) rename tests/{ => behavior}/044-break-continue.buzz (100%) rename tests/{ => behavior}/045-mutual-import.buzz (100%) rename tests/{ => behavior}/046-try-catch.buzz (100%) rename tests/{ => behavior}/047-if-arrow.buzz (100%) rename tests/{ => behavior}/048-generics.buzz (100%) rename tests/{ => behavior}/050-protocols.buzz (100%) rename tests/{ => behavior}/051-functional.buzz (100%) rename tests/{ => behavior}/052-inline-if.buzz (100%) rename tests/{ => behavior}/053-range.buzz (100%) rename tests/{ => behavior}/056-crypto.buzz (100%) rename tests/{ => behavior}/057-any.buzz (100%) rename tests/{ => behavior}/059-types-as-value.buzz (100%) rename tests/{ => behavior}/060-free-identifiers.buzz (100%) rename tests/{ => behavior}/061-utf8.buzz (100%) rename tests/{ => behavior}/062-discarded-value.buzz (100%) rename tests/{ => behavior}/063-nullable-default.buzz (100%) rename tests/{ => behavior}/064-throw-inside-try.buzz (100%) rename tests/{ => behavior}/065-inferred-var-type.buzz (100%) rename tests/{ => behavior}/066-object-generics.buzz (100%) rename tests/{ => behavior}/069-named-expr.buzz (100%) rename tests/{ => behavior}/070-block-expression.buzz (100%) rename tests/{ => behavior}/071-tail-call.buzz (100%) rename tests/{ => behavior}/072-labels.buzz (100%) rename tests/{ => behavior}/073-tuples.buzz (100%) rename tests/{ => behavior}/074-checked-subscript.buzz (100%) rename tests/{ => behavior}/075-composite-assign.buzz (100%) diff --git a/build.zig b/build.zig index 11c956ce..c5340a0c 100644 --- a/build.zig +++ b/build.zig @@ -178,6 +178,12 @@ pub fn build(b: *Build) !void { b.step("lsp", "run buzz lsp").dependOn(&run_lsp_exe.step); } + // fuzz + const fuzz = if (!is_wasm) + buildFuzz(b, target, build_mode, ext_deps) + else + null; + // check (exe not installed) const check_exe = b.addExecutable( .{ @@ -253,7 +259,7 @@ pub fn build(b: *Build) !void { run_tests.step.dependOn(install_step); // wait for libraries to be installed test_step.dependOn(&run_tests.step); - for ([_]?*std.Build.Step.Compile{ static_lib, lib, exe, behavior_exe, debugger_exe, lsp_exe, check_exe, tests }) |comp| { + for ([_]?*std.Build.Step.Compile{ static_lib, lib, exe, behavior_exe, debugger_exe, lsp_exe, check_exe, tests, fuzz }) |comp| { if (comp) |c| { // BuildOptions c.root_module.addImport("build_options", build_option_module); @@ -274,13 +280,13 @@ pub fn build(b: *Build) !void { } // So that JIT compiled function can reference buzz_api - for ([_]?*std.Build.Step.Compile{ exe, behavior_exe, debugger_exe, lsp_exe, check_exe }) |comp| { + for ([_]?*std.Build.Step.Compile{ exe, behavior_exe, debugger_exe, lsp_exe, check_exe, fuzz }) |comp| { if (comp) |c| { c.linkLibrary(static_lib); } } - for ([_]?*std.Build.Step.Compile{ tests, static_lib, lib, exe, debugger_exe, lsp_exe, behavior_exe, check_exe }) |comp| { + for ([_]?*std.Build.Step.Compile{ tests, static_lib, lib, exe, debugger_exe, lsp_exe, behavior_exe, check_exe, fuzz }) |comp| { if (comp) |c| { c.root_module.addImport( "dap", @@ -289,7 +295,7 @@ pub fn build(b: *Build) !void { } } - for ([_]?*std.Build.Step.Compile{ exe, debugger_exe, lsp_exe, check_exe }) |comp| { + for ([_]?*std.Build.Step.Compile{ behavior_exe, exe, debugger_exe, lsp_exe, check_exe, fuzz }) |comp| { if (comp) |c| { c.root_module.addImport( "clap", @@ -642,10 +648,118 @@ pub fn buildMir(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.O lib.linkSystemLibrary("kernel32"); lib.linkSystemLibrary("psapi"); } + b.installArtifact(lib); return lib; } +pub fn buildFuzz( + b: *Build, + target: Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + ext_deps: []const *std.Build.Step.Compile, +) *Build.Step.Compile { + // Define a step for generating fuzzing tooling: + const fuzz = b.step("fuzz", "Generate an instrumented executable for AFL++"); + + // Define an oblect file that contains your test function: + const afl_obj = b.addObject( + .{ + .name = "fuzz_obj", + .root_module = b.createModule( + .{ + .target = target, + .optimize = optimize, + .root_source_file = b.path("src/fuzz.zig"), + .stack_check = false, // not linking with compiler-rt + .sanitize_c = .off, + .link_libc = true, + }, + ), + }, + ); + + // Generate an instrumented executable: + var run_afl_cc: *std.Build.Step.Run = undefined; + if (false) { // Turn on to use .zon dependency + const afl = b.lazyDependency("AFLplusplus", .{ + .target = target, + .optimize = optimize, + .@"llvm-config-path" = &[_][]const u8{}, + }) orelse return null; + + const install_tools = b.addInstallDirectory(.{ + .source_dir = std.Build.LazyPath{ + .cwd_relative = afl.builder.install_path, + }, + .install_dir = .prefix, + .install_subdir = "AFLplusplus", + }); + + install_tools.step.dependOn(afl.builder.getInstallStep()); + run_afl_cc = b.addSystemCommand(&.{ + b.pathJoin(&.{ afl.builder.exe_dir, "afl-cc" }), + "-O3", + "-o", + }); + for (ext_deps) |dep| { + run_afl_cc.addArg("-L"); + run_afl_cc.addFileArg(dep.getEmittedBin()); + } + run_afl_cc.step.dependOn(&afl.builder.top_level_steps.get("llvm_exes").?.step); + run_afl_cc.step.dependOn(&install_tools.step); + } else { + run_afl_cc = b.addSystemCommand( + &.{ + b.findProgram(&.{"afl-cc"}, &.{}) catch @panic("Could not find 'afl-cc', which is required to build"), + }, + ); + + _ = afl_obj.getEmittedBin(); // hack around build system bug + + for (ext_deps) |dep| { + run_afl_cc.addFileArg(dep.getEmittedBin()); + } + + // On darwin we need compiler-rt + if (target.result.os.tag.isDarwin()) { + const compiler_rt = b.addLibrary( + .{ + .name = "zig-compiler-rt", + .linkage = .static, + .root_module = b.createModule( + .{ + .root_source_file = b.path("build/compiler_rt.zig"), + .target = target, + .optimize = optimize, + .link_libc = false, + .stack_check = false, + }, + ), + }, + ); + + run_afl_cc.addFileArg(compiler_rt.getEmittedBin()); + } + + run_afl_cc.addArgs( + &.{ + "-O3", + "-o", + }, + ); + } + + const fuzz_exe = run_afl_cc.addOutputFileArg(afl_obj.name); + run_afl_cc.addFileArg(b.path("src/afl.c")); + run_afl_cc.addFileArg(afl_obj.getEmittedLlvmBc()); + + // Install it + fuzz.dependOn(&b.addInstallBinFile(fuzz_exe, "fuzz_afl").step); + + return afl_obj; +} + const BuildOptions = struct { version: std.SemanticVersion, sha: []const u8, diff --git a/build/compiler_rt.zig b/build/compiler_rt.zig new file mode 100644 index 00000000..aac81bf4 --- /dev/null +++ b/build/compiler_rt.zig @@ -0,0 +1,276 @@ +const builtin = @import("builtin"); +const common = @import("compiler_rt/common.zig"); + +pub const panic = common.panic; + +comptime { + // Integer routines + _ = @import("compiler_rt/count0bits.zig"); + _ = @import("compiler_rt/parity.zig"); + _ = @import("compiler_rt/popcount.zig"); + _ = @import("compiler_rt/bitreverse.zig"); + _ = @import("compiler_rt/bswap.zig"); + _ = @import("compiler_rt/cmp.zig"); + + _ = @import("compiler_rt/shift.zig"); + _ = @import("compiler_rt/negXi2.zig"); + _ = @import("compiler_rt/int.zig"); + _ = @import("compiler_rt/mulXi3.zig"); + _ = @import("compiler_rt/divti3.zig"); + _ = @import("compiler_rt/udivti3.zig"); + _ = @import("compiler_rt/modti3.zig"); + _ = @import("compiler_rt/umodti3.zig"); + + _ = @import("compiler_rt/absv.zig"); + _ = @import("compiler_rt/absvsi2.zig"); + _ = @import("compiler_rt/absvdi2.zig"); + _ = @import("compiler_rt/absvti2.zig"); + _ = @import("compiler_rt/negv.zig"); + + _ = @import("compiler_rt/addvsi3.zig"); + _ = @import("compiler_rt/subvsi3.zig"); + _ = @import("compiler_rt/subvdi3.zig"); + _ = @import("compiler_rt/mulvsi3.zig"); + + _ = @import("compiler_rt/addo.zig"); + _ = @import("compiler_rt/subo.zig"); + _ = @import("compiler_rt/mulo.zig"); + + // Float routines + // conversion + _ = @import("compiler_rt/extendf.zig"); + _ = @import("compiler_rt/extendhfsf2.zig"); + _ = @import("compiler_rt/extendhfdf2.zig"); + _ = @import("compiler_rt/extendhftf2.zig"); + _ = @import("compiler_rt/extendhfxf2.zig"); + _ = @import("compiler_rt/extendsfdf2.zig"); + _ = @import("compiler_rt/extendsftf2.zig"); + _ = @import("compiler_rt/extendsfxf2.zig"); + _ = @import("compiler_rt/extenddftf2.zig"); + _ = @import("compiler_rt/extenddfxf2.zig"); + _ = @import("compiler_rt/extendxftf2.zig"); + + _ = @import("compiler_rt/truncf.zig"); + _ = @import("compiler_rt/truncsfhf2.zig"); + _ = @import("compiler_rt/truncdfhf2.zig"); + _ = @import("compiler_rt/truncdfsf2.zig"); + _ = @import("compiler_rt/truncxfhf2.zig"); + _ = @import("compiler_rt/truncxfsf2.zig"); + _ = @import("compiler_rt/truncxfdf2.zig"); + _ = @import("compiler_rt/trunctfhf2.zig"); + _ = @import("compiler_rt/trunctfsf2.zig"); + _ = @import("compiler_rt/trunctfdf2.zig"); + _ = @import("compiler_rt/trunctfxf2.zig"); + + _ = @import("compiler_rt/int_from_float.zig"); + _ = @import("compiler_rt/fixhfsi.zig"); + _ = @import("compiler_rt/fixhfdi.zig"); + _ = @import("compiler_rt/fixhfti.zig"); + _ = @import("compiler_rt/fixhfei.zig"); + _ = @import("compiler_rt/fixsfsi.zig"); + _ = @import("compiler_rt/fixsfdi.zig"); + _ = @import("compiler_rt/fixsfti.zig"); + _ = @import("compiler_rt/fixsfei.zig"); + _ = @import("compiler_rt/fixdfsi.zig"); + _ = @import("compiler_rt/fixdfdi.zig"); + _ = @import("compiler_rt/fixdfti.zig"); + _ = @import("compiler_rt/fixdfei.zig"); + _ = @import("compiler_rt/fixtfsi.zig"); + _ = @import("compiler_rt/fixtfdi.zig"); + _ = @import("compiler_rt/fixtfti.zig"); + _ = @import("compiler_rt/fixtfei.zig"); + _ = @import("compiler_rt/fixxfsi.zig"); + _ = @import("compiler_rt/fixxfdi.zig"); + _ = @import("compiler_rt/fixxfti.zig"); + _ = @import("compiler_rt/fixxfei.zig"); + _ = @import("compiler_rt/fixunshfsi.zig"); + _ = @import("compiler_rt/fixunshfdi.zig"); + _ = @import("compiler_rt/fixunshfti.zig"); + _ = @import("compiler_rt/fixunshfei.zig"); + _ = @import("compiler_rt/fixunssfsi.zig"); + _ = @import("compiler_rt/fixunssfdi.zig"); + _ = @import("compiler_rt/fixunssfti.zig"); + _ = @import("compiler_rt/fixunssfei.zig"); + _ = @import("compiler_rt/fixunsdfsi.zig"); + _ = @import("compiler_rt/fixunsdfdi.zig"); + _ = @import("compiler_rt/fixunsdfti.zig"); + _ = @import("compiler_rt/fixunsdfei.zig"); + _ = @import("compiler_rt/fixunstfsi.zig"); + _ = @import("compiler_rt/fixunstfdi.zig"); + _ = @import("compiler_rt/fixunstfti.zig"); + _ = @import("compiler_rt/fixunstfei.zig"); + _ = @import("compiler_rt/fixunsxfsi.zig"); + _ = @import("compiler_rt/fixunsxfdi.zig"); + _ = @import("compiler_rt/fixunsxfti.zig"); + _ = @import("compiler_rt/fixunsxfei.zig"); + + _ = @import("compiler_rt/float_from_int.zig"); + _ = @import("compiler_rt/floatsihf.zig"); + _ = @import("compiler_rt/floatsisf.zig"); + _ = @import("compiler_rt/floatsidf.zig"); + _ = @import("compiler_rt/floatsitf.zig"); + _ = @import("compiler_rt/floatsixf.zig"); + _ = @import("compiler_rt/floatdihf.zig"); + _ = @import("compiler_rt/floatdisf.zig"); + _ = @import("compiler_rt/floatdidf.zig"); + _ = @import("compiler_rt/floatditf.zig"); + _ = @import("compiler_rt/floatdixf.zig"); + _ = @import("compiler_rt/floattihf.zig"); + _ = @import("compiler_rt/floattisf.zig"); + _ = @import("compiler_rt/floattidf.zig"); + _ = @import("compiler_rt/floattitf.zig"); + _ = @import("compiler_rt/floattixf.zig"); + _ = @import("compiler_rt/floateihf.zig"); + _ = @import("compiler_rt/floateisf.zig"); + _ = @import("compiler_rt/floateidf.zig"); + _ = @import("compiler_rt/floateitf.zig"); + _ = @import("compiler_rt/floateixf.zig"); + _ = @import("compiler_rt/floatunsihf.zig"); + _ = @import("compiler_rt/floatunsisf.zig"); + _ = @import("compiler_rt/floatunsidf.zig"); + _ = @import("compiler_rt/floatunsitf.zig"); + _ = @import("compiler_rt/floatunsixf.zig"); + _ = @import("compiler_rt/floatundihf.zig"); + _ = @import("compiler_rt/floatundisf.zig"); + _ = @import("compiler_rt/floatundidf.zig"); + _ = @import("compiler_rt/floatunditf.zig"); + _ = @import("compiler_rt/floatundixf.zig"); + _ = @import("compiler_rt/floatuntihf.zig"); + _ = @import("compiler_rt/floatuntisf.zig"); + _ = @import("compiler_rt/floatuntidf.zig"); + _ = @import("compiler_rt/floatuntitf.zig"); + _ = @import("compiler_rt/floatuntixf.zig"); + _ = @import("compiler_rt/floatuneihf.zig"); + _ = @import("compiler_rt/floatuneisf.zig"); + _ = @import("compiler_rt/floatuneidf.zig"); + _ = @import("compiler_rt/floatuneitf.zig"); + _ = @import("compiler_rt/floatuneixf.zig"); + + // comparison + _ = @import("compiler_rt/comparef.zig"); + _ = @import("compiler_rt/cmphf2.zig"); + _ = @import("compiler_rt/cmpsf2.zig"); + _ = @import("compiler_rt/cmpdf2.zig"); + _ = @import("compiler_rt/cmptf2.zig"); + _ = @import("compiler_rt/cmpxf2.zig"); + _ = @import("compiler_rt/unordhf2.zig"); + _ = @import("compiler_rt/unordsf2.zig"); + _ = @import("compiler_rt/unorddf2.zig"); + _ = @import("compiler_rt/unordxf2.zig"); + _ = @import("compiler_rt/unordtf2.zig"); + _ = @import("compiler_rt/gehf2.zig"); + _ = @import("compiler_rt/gesf2.zig"); + _ = @import("compiler_rt/gedf2.zig"); + _ = @import("compiler_rt/gexf2.zig"); + _ = @import("compiler_rt/getf2.zig"); + + // arithmetic + _ = @import("compiler_rt/addf3.zig"); + _ = @import("compiler_rt/addhf3.zig"); + _ = @import("compiler_rt/addsf3.zig"); + _ = @import("compiler_rt/adddf3.zig"); + _ = @import("compiler_rt/addtf3.zig"); + _ = @import("compiler_rt/addxf3.zig"); + + _ = @import("compiler_rt/subhf3.zig"); + _ = @import("compiler_rt/subsf3.zig"); + _ = @import("compiler_rt/subdf3.zig"); + _ = @import("compiler_rt/subtf3.zig"); + _ = @import("compiler_rt/subxf3.zig"); + + _ = @import("compiler_rt/mulf3.zig"); + _ = @import("compiler_rt/mulhf3.zig"); + _ = @import("compiler_rt/mulsf3.zig"); + _ = @import("compiler_rt/muldf3.zig"); + _ = @import("compiler_rt/multf3.zig"); + _ = @import("compiler_rt/mulxf3.zig"); + + _ = @import("compiler_rt/divhf3.zig"); + _ = @import("compiler_rt/divsf3.zig"); + _ = @import("compiler_rt/divdf3.zig"); + _ = @import("compiler_rt/divxf3.zig"); + _ = @import("compiler_rt/divtf3.zig"); + + _ = @import("compiler_rt/neghf2.zig"); + _ = @import("compiler_rt/negsf2.zig"); + _ = @import("compiler_rt/negdf2.zig"); + _ = @import("compiler_rt/negtf2.zig"); + _ = @import("compiler_rt/negxf2.zig"); + + // other + _ = @import("compiler_rt/powiXf2.zig"); + _ = @import("compiler_rt/mulc3.zig"); + _ = @import("compiler_rt/mulhc3.zig"); + _ = @import("compiler_rt/mulsc3.zig"); + _ = @import("compiler_rt/muldc3.zig"); + _ = @import("compiler_rt/mulxc3.zig"); + _ = @import("compiler_rt/multc3.zig"); + + _ = @import("compiler_rt/divc3.zig"); + _ = @import("compiler_rt/divhc3.zig"); + _ = @import("compiler_rt/divsc3.zig"); + _ = @import("compiler_rt/divdc3.zig"); + _ = @import("compiler_rt/divxc3.zig"); + _ = @import("compiler_rt/divtc3.zig"); + + // Math routines. Alphabetically sorted. + _ = @import("compiler_rt/ceil.zig"); + _ = @import("compiler_rt/cos.zig"); + _ = @import("compiler_rt/exp.zig"); + _ = @import("compiler_rt/exp2.zig"); + _ = @import("compiler_rt/fabs.zig"); + _ = @import("compiler_rt/floor.zig"); + _ = @import("compiler_rt/fma.zig"); + _ = @import("compiler_rt/fmax.zig"); + _ = @import("compiler_rt/fmin.zig"); + _ = @import("compiler_rt/fmod.zig"); + _ = @import("compiler_rt/log.zig"); + _ = @import("compiler_rt/log10.zig"); + _ = @import("compiler_rt/log2.zig"); + _ = @import("compiler_rt/round.zig"); + _ = @import("compiler_rt/sin.zig"); + _ = @import("compiler_rt/sincos.zig"); + _ = @import("compiler_rt/sqrt.zig"); + _ = @import("compiler_rt/tan.zig"); + _ = @import("compiler_rt/trunc.zig"); + + // BigInt. Alphabetically sorted. + _ = @import("compiler_rt/divmodei4.zig"); + _ = @import("compiler_rt/udivmodei4.zig"); + _ = @import("compiler_rt/udivmodti4.zig"); + + // extra + _ = @import("compiler_rt/os_version_check.zig"); + _ = @import("compiler_rt/emutls.zig"); + _ = @import("compiler_rt/arm.zig"); + _ = @import("compiler_rt/aulldiv.zig"); + _ = @import("compiler_rt/aullrem.zig"); + _ = @import("compiler_rt/clear_cache.zig"); + _ = @import("compiler_rt/hexagon.zig"); + + if (@import("builtin").object_format != .c) { + if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig"); + _ = @import("compiler_rt/stack_probe.zig"); + + // macOS has these functions inside libSystem. + if (builtin.cpu.arch.isAARCH64() and !builtin.os.tag.isDarwin()) { + if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/aarch64_outline_atomics.zig"); + } + + _ = @import("compiler_rt/memcpy.zig"); + _ = @import("compiler_rt/memset.zig"); + _ = @import("compiler_rt/memmove.zig"); + _ = @import("compiler_rt/memcmp.zig"); + _ = @import("compiler_rt/bcmp.zig"); + _ = @import("compiler_rt/ssp.zig"); + + _ = @import("compiler_rt/strlen.zig"); + } + + // Temporarily used for uefi until https://github.com/ziglang/zig/issues/21630 is addressed. + if (!builtin.link_libc and (builtin.os.tag == .windows or builtin.os.tag == .uefi) and (builtin.abi == .none or builtin.abi == .msvc)) { + @export(&_fltused, .{ .name = "_fltused", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +var _fltused: c_int = 1; diff --git a/build/compiler_rt/aarch64_outline_atomics.zig b/build/compiler_rt/aarch64_outline_atomics.zig new file mode 100644 index 00000000..817800eb --- /dev/null +++ b/build/compiler_rt/aarch64_outline_atomics.zig @@ -0,0 +1,2127 @@ +//! This file is generated by tools/gen_outline_atomics.zig. +const builtin = @import("builtin"); +const std = @import("std"); +const common = @import("common.zig"); +const always_has_lse = builtin.cpu.has(.aarch64, .lse); + +/// This default is overridden at runtime after inspecting CPU properties. +/// It is intentionally not exported in order to make the machine code that +/// uses it a statically predicted direct branch rather than using the PLT, +/// which ARM is concerned would have too much overhead. +var __aarch64_have_lse_atomics: u8 = @intFromBool(always_has_lse); + +fn __aarch64_cas1_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x00000000 + 0x000000 + \\ ret + \\8: + \\ uxtb w16, w0 + \\0: + \\ ldxrb w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stxrb w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp1_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x00000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ stxrb w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd1_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x00000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ add w17, w0, w16 + \\ stxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr1_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x00000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ bic w17, w0, w16 + \\ stxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor1_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x00000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ eor w17, w0, w16 + \\ stxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset1_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x00000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ orr w17, w0, w16 + \\ stxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas1_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x00000000 + 0x400000 + \\ ret + \\8: + \\ uxtb w16, w0 + \\0: + \\ ldaxrb w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stxrb w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp1_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x00000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ stxrb w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd1_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x00000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ add w17, w0, w16 + \\ stxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr1_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x00000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ bic w17, w0, w16 + \\ stxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor1_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x00000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ eor w17, w0, w16 + \\ stxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset1_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x00000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ orr w17, w0, w16 + \\ stxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas1_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x00000000 + 0x008000 + \\ ret + \\8: + \\ uxtb w16, w0 + \\0: + \\ ldxrb w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stlxrb w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp1_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x00000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ stlxrb w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd1_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x00000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ add w17, w0, w16 + \\ stlxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr1_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x00000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ bic w17, w0, w16 + \\ stlxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor1_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x00000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ eor w17, w0, w16 + \\ stlxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset1_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x00000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrb w0, [x1] + \\ orr w17, w0, w16 + \\ stlxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas1_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x00000000 + 0x408000 + \\ ret + \\8: + \\ uxtb w16, w0 + \\0: + \\ ldaxrb w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stlxrb w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp1_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x00000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ stlxrb w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd1_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x00000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ add w17, w0, w16 + \\ stlxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr1_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x00000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ bic w17, w0, w16 + \\ stlxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor1_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x00000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ eor w17, w0, w16 + \\ stlxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset1_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x00000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrb w0, [x1] + \\ orr w17, w0, w16 + \\ stlxrb w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas2_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x40000000 + 0x000000 + \\ ret + \\8: + \\ uxth w16, w0 + \\0: + \\ ldxrh w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stxrh w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp2_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x40000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ stxrh w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd2_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x40000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ add w17, w0, w16 + \\ stxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr2_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x40000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ bic w17, w0, w16 + \\ stxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor2_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x40000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ eor w17, w0, w16 + \\ stxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset2_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x40000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ orr w17, w0, w16 + \\ stxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas2_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x40000000 + 0x400000 + \\ ret + \\8: + \\ uxth w16, w0 + \\0: + \\ ldaxrh w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stxrh w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp2_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x40000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ stxrh w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd2_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x40000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ add w17, w0, w16 + \\ stxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr2_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x40000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ bic w17, w0, w16 + \\ stxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor2_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x40000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ eor w17, w0, w16 + \\ stxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset2_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x40000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ orr w17, w0, w16 + \\ stxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas2_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x40000000 + 0x008000 + \\ ret + \\8: + \\ uxth w16, w0 + \\0: + \\ ldxrh w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stlxrh w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp2_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x40000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ stlxrh w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd2_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x40000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ add w17, w0, w16 + \\ stlxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr2_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x40000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ bic w17, w0, w16 + \\ stlxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor2_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x40000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ eor w17, w0, w16 + \\ stlxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset2_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x40000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxrh w0, [x1] + \\ orr w17, w0, w16 + \\ stlxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas2_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x40000000 + 0x408000 + \\ ret + \\8: + \\ uxth w16, w0 + \\0: + \\ ldaxrh w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stlxrh w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp2_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x40000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ stlxrh w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd2_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x40000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ add w17, w0, w16 + \\ stlxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr2_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x40000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ bic w17, w0, w16 + \\ stlxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor2_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x40000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ eor w17, w0, w16 + \\ stlxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset2_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x40000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxrh w0, [x1] + \\ orr w17, w0, w16 + \\ stlxrh w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas4_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x80000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stxr w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp4_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x80000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ stxr w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd4_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x80000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ add w17, w0, w16 + \\ stxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr4_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x80000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ bic w17, w0, w16 + \\ stxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor4_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x80000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ eor w17, w0, w16 + \\ stxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset4_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x80000000 + 0x000000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ orr w17, w0, w16 + \\ stxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas4_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x80000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stxr w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp4_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x80000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ stxr w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd4_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x80000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ add w17, w0, w16 + \\ stxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr4_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x80000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ bic w17, w0, w16 + \\ stxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor4_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x80000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ eor w17, w0, w16 + \\ stxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset4_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x80000000 + 0x800000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ orr w17, w0, w16 + \\ stxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas4_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x80000000 + 0x008000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stlxr w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp4_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x80000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ stlxr w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd4_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x80000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ add w17, w0, w16 + \\ stlxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr4_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x80000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ bic w17, w0, w16 + \\ stlxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor4_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x80000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ eor w17, w0, w16 + \\ stlxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset4_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x80000000 + 0x400000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldxr w0, [x1] + \\ orr w17, w0, w16 + \\ stlxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas4_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0x80000000 + 0x408000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x2] + \\ cmp w0, w16 + \\ bne 1f + \\ stlxr w17, w1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp4_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0x80000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ stlxr w17, w16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd4_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0x80000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ add w17, w0, w16 + \\ stlxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr4_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0x80000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ bic w17, w0, w16 + \\ stlxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor4_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0x80000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ eor w17, w0, w16 + \\ stlxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset4_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0x80000000 + 0xc00000 + \\ ret + \\8: + \\ mov w16, w0 + \\0: + \\ ldaxr w0, [x1] + \\ orr w17, w0, w16 + \\ stlxr w15, w17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas8_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0xc0000000 + 0x000000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x2] + \\ cmp x0, x16 + \\ bne 1f + \\ stxr w17, x1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp8_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0xc0000000 + 0x000000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ stxr w17, x16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd8_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0xc0000000 + 0x000000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ add x17, x0, x16 + \\ stxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr8_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0xc0000000 + 0x000000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ bic x17, x0, x16 + \\ stxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor8_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0xc0000000 + 0x000000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ eor x17, x0, x16 + \\ stxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset8_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0xc0000000 + 0x000000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ orr x17, x0, x16 + \\ stxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas8_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0xc0000000 + 0x400000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x2] + \\ cmp x0, x16 + \\ bne 1f + \\ stxr w17, x1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp8_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0xc0000000 + 0x800000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ stxr w17, x16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd8_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0xc0000000 + 0x800000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ add x17, x0, x16 + \\ stxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr8_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0xc0000000 + 0x800000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ bic x17, x0, x16 + \\ stxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor8_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0xc0000000 + 0x800000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ eor x17, x0, x16 + \\ stxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset8_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0xc0000000 + 0x800000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ orr x17, x0, x16 + \\ stxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas8_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0xc0000000 + 0x008000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x2] + \\ cmp x0, x16 + \\ bne 1f + \\ stlxr w17, x1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp8_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0xc0000000 + 0x400000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ stlxr w17, x16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd8_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0xc0000000 + 0x400000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ add x17, x0, x16 + \\ stlxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr8_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0xc0000000 + 0x400000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ bic x17, x0, x16 + \\ stlxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor8_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0xc0000000 + 0x400000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ eor x17, x0, x16 + \\ stlxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset8_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0xc0000000 + 0x400000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldxr x0, [x1] + \\ orr x17, x0, x16 + \\ stlxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas8_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x08a07c41 + 0xc0000000 + 0x408000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x2] + \\ cmp x0, x16 + \\ bne 1f + \\ stlxr w17, x1, [x2] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_swp8_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38208020 + 0xc0000000 + 0xc00000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ stlxr w17, x16, [x1] + \\ cbnz w17, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldadd8_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x0000 + 0xc0000000 + 0xc00000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ add x17, x0, x16 + \\ stlxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldclr8_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x1000 + 0xc0000000 + 0xc00000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ bic x17, x0, x16 + \\ stlxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldeor8_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x2000 + 0xc0000000 + 0xc00000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ eor x17, x0, x16 + \\ stlxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_ldset8_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x38200020 + 0x3000 + 0xc0000000 + 0xc00000 + \\ ret + \\8: + \\ mov x16, x0 + \\0: + \\ ldaxr x0, [x1] + \\ orr x17, x0, x16 + \\ stlxr w15, x17, [x1] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas16_relax() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x48207c82 + 0x000000 + \\ ret + \\8: + \\ mov x16, x0 + \\ mov x17, x1 + \\0: + \\ ldxp x0, x1, [x4] + \\ cmp x0, x16 + \\ ccmp x1, x17, #0, eq + \\ bne 1f + \\ stxp w15, x2, x3, [x4] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas16_acq() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x48207c82 + 0x400000 + \\ ret + \\8: + \\ mov x16, x0 + \\ mov x17, x1 + \\0: + \\ ldaxp x0, x1, [x4] + \\ cmp x0, x16 + \\ ccmp x1, x17, #0, eq + \\ bne 1f + \\ stxp w15, x2, x3, [x4] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas16_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x48207c82 + 0x008000 + \\ ret + \\8: + \\ mov x16, x0 + \\ mov x17, x1 + \\0: + \\ ldxp x0, x1, [x4] + \\ cmp x0, x16 + \\ ccmp x1, x17, #0, eq + \\ bne 1f + \\ stlxp w15, x2, x3, [x4] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} +fn __aarch64_cas16_acq_rel() align(16) callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ cbz w16, 8f + \\ .inst 0x48207c82 + 0x408000 + \\ ret + \\8: + \\ mov x16, x0 + \\ mov x17, x1 + \\0: + \\ ldaxp x0, x1, [x4] + \\ cmp x0, x16 + \\ ccmp x1, x17, #0, eq + \\ bne 1f + \\ stlxp w15, x2, x3, [x4] + \\ cbnz w15, 0b + \\1: + \\ ret + : + : [__aarch64_have_lse_atomics] "{w16}" (__aarch64_have_lse_atomics), + : .{ .w15 = true, .w16 = true, .w17 = true, .memory = true }); + unreachable; +} + +comptime { + @export(&__aarch64_cas1_relax, .{ .name = "__aarch64_cas1_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp1_relax, .{ .name = "__aarch64_swp1_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd1_relax, .{ .name = "__aarch64_ldadd1_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr1_relax, .{ .name = "__aarch64_ldclr1_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor1_relax, .{ .name = "__aarch64_ldeor1_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset1_relax, .{ .name = "__aarch64_ldset1_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas1_acq, .{ .name = "__aarch64_cas1_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp1_acq, .{ .name = "__aarch64_swp1_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd1_acq, .{ .name = "__aarch64_ldadd1_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr1_acq, .{ .name = "__aarch64_ldclr1_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor1_acq, .{ .name = "__aarch64_ldeor1_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset1_acq, .{ .name = "__aarch64_ldset1_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas1_rel, .{ .name = "__aarch64_cas1_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp1_rel, .{ .name = "__aarch64_swp1_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd1_rel, .{ .name = "__aarch64_ldadd1_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr1_rel, .{ .name = "__aarch64_ldclr1_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor1_rel, .{ .name = "__aarch64_ldeor1_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset1_rel, .{ .name = "__aarch64_ldset1_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas1_acq_rel, .{ .name = "__aarch64_cas1_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp1_acq_rel, .{ .name = "__aarch64_swp1_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd1_acq_rel, .{ .name = "__aarch64_ldadd1_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr1_acq_rel, .{ .name = "__aarch64_ldclr1_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor1_acq_rel, .{ .name = "__aarch64_ldeor1_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset1_acq_rel, .{ .name = "__aarch64_ldset1_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas2_relax, .{ .name = "__aarch64_cas2_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp2_relax, .{ .name = "__aarch64_swp2_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd2_relax, .{ .name = "__aarch64_ldadd2_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr2_relax, .{ .name = "__aarch64_ldclr2_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor2_relax, .{ .name = "__aarch64_ldeor2_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset2_relax, .{ .name = "__aarch64_ldset2_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas2_acq, .{ .name = "__aarch64_cas2_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp2_acq, .{ .name = "__aarch64_swp2_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd2_acq, .{ .name = "__aarch64_ldadd2_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr2_acq, .{ .name = "__aarch64_ldclr2_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor2_acq, .{ .name = "__aarch64_ldeor2_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset2_acq, .{ .name = "__aarch64_ldset2_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas2_rel, .{ .name = "__aarch64_cas2_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp2_rel, .{ .name = "__aarch64_swp2_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd2_rel, .{ .name = "__aarch64_ldadd2_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr2_rel, .{ .name = "__aarch64_ldclr2_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor2_rel, .{ .name = "__aarch64_ldeor2_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset2_rel, .{ .name = "__aarch64_ldset2_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas2_acq_rel, .{ .name = "__aarch64_cas2_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp2_acq_rel, .{ .name = "__aarch64_swp2_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd2_acq_rel, .{ .name = "__aarch64_ldadd2_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr2_acq_rel, .{ .name = "__aarch64_ldclr2_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor2_acq_rel, .{ .name = "__aarch64_ldeor2_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset2_acq_rel, .{ .name = "__aarch64_ldset2_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas4_relax, .{ .name = "__aarch64_cas4_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp4_relax, .{ .name = "__aarch64_swp4_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd4_relax, .{ .name = "__aarch64_ldadd4_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr4_relax, .{ .name = "__aarch64_ldclr4_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor4_relax, .{ .name = "__aarch64_ldeor4_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset4_relax, .{ .name = "__aarch64_ldset4_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas4_acq, .{ .name = "__aarch64_cas4_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp4_acq, .{ .name = "__aarch64_swp4_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd4_acq, .{ .name = "__aarch64_ldadd4_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr4_acq, .{ .name = "__aarch64_ldclr4_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor4_acq, .{ .name = "__aarch64_ldeor4_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset4_acq, .{ .name = "__aarch64_ldset4_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas4_rel, .{ .name = "__aarch64_cas4_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp4_rel, .{ .name = "__aarch64_swp4_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd4_rel, .{ .name = "__aarch64_ldadd4_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr4_rel, .{ .name = "__aarch64_ldclr4_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor4_rel, .{ .name = "__aarch64_ldeor4_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset4_rel, .{ .name = "__aarch64_ldset4_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas4_acq_rel, .{ .name = "__aarch64_cas4_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp4_acq_rel, .{ .name = "__aarch64_swp4_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd4_acq_rel, .{ .name = "__aarch64_ldadd4_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr4_acq_rel, .{ .name = "__aarch64_ldclr4_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor4_acq_rel, .{ .name = "__aarch64_ldeor4_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset4_acq_rel, .{ .name = "__aarch64_ldset4_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas8_relax, .{ .name = "__aarch64_cas8_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp8_relax, .{ .name = "__aarch64_swp8_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd8_relax, .{ .name = "__aarch64_ldadd8_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr8_relax, .{ .name = "__aarch64_ldclr8_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor8_relax, .{ .name = "__aarch64_ldeor8_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset8_relax, .{ .name = "__aarch64_ldset8_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas8_acq, .{ .name = "__aarch64_cas8_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp8_acq, .{ .name = "__aarch64_swp8_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd8_acq, .{ .name = "__aarch64_ldadd8_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr8_acq, .{ .name = "__aarch64_ldclr8_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor8_acq, .{ .name = "__aarch64_ldeor8_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset8_acq, .{ .name = "__aarch64_ldset8_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas8_rel, .{ .name = "__aarch64_cas8_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp8_rel, .{ .name = "__aarch64_swp8_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd8_rel, .{ .name = "__aarch64_ldadd8_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr8_rel, .{ .name = "__aarch64_ldclr8_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor8_rel, .{ .name = "__aarch64_ldeor8_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset8_rel, .{ .name = "__aarch64_ldset8_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas8_acq_rel, .{ .name = "__aarch64_cas8_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_swp8_acq_rel, .{ .name = "__aarch64_swp8_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldadd8_acq_rel, .{ .name = "__aarch64_ldadd8_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldclr8_acq_rel, .{ .name = "__aarch64_ldclr8_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldeor8_acq_rel, .{ .name = "__aarch64_ldeor8_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_ldset8_acq_rel, .{ .name = "__aarch64_ldset8_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas16_relax, .{ .name = "__aarch64_cas16_relax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas16_acq, .{ .name = "__aarch64_cas16_acq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas16_rel, .{ .name = "__aarch64_cas16_rel", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aarch64_cas16_acq_rel, .{ .name = "__aarch64_cas16_acq_rel", .linkage = common.linkage, .visibility = common.visibility }); +} diff --git a/build/compiler_rt/absv.zig b/build/compiler_rt/absv.zig new file mode 100644 index 00000000..8910a4a6 --- /dev/null +++ b/build/compiler_rt/absv.zig @@ -0,0 +1,26 @@ +/// absv - absolute oVerflow +/// * @panic if value can not be represented +pub inline fn absv(comptime ST: type, a: ST) ST { + const UT = switch (ST) { + i32 => u32, + i64 => u64, + i128 => u128, + else => unreachable, + }; + // taken from Bit Twiddling Hacks + // compute the integer absolute value (abs) without branching + var x: ST = a; + const N: UT = @bitSizeOf(ST); + const sign: ST = a >> N - 1; + x +%= sign; + x ^= sign; + if (x < 0) + @panic("compiler_rt absv: overflow"); + return x; +} + +test { + _ = @import("absvsi2_test.zig"); + _ = @import("absvdi2_test.zig"); + _ = @import("absvti2_test.zig"); +} diff --git a/build/compiler_rt/absvdi2.zig b/build/compiler_rt/absvdi2.zig new file mode 100644 index 00000000..8b5e5d8a --- /dev/null +++ b/build/compiler_rt/absvdi2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const absv = @import("./absv.zig").absv; + +pub const panic = common.panic; + +comptime { + @export(&__absvdi2, .{ .name = "__absvdi2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __absvdi2(a: i64) callconv(.c) i64 { + return absv(i64, a); +} diff --git a/build/compiler_rt/absvdi2_test.zig b/build/compiler_rt/absvdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/absvsi2.zig b/build/compiler_rt/absvsi2.zig new file mode 100644 index 00000000..0030813d --- /dev/null +++ b/build/compiler_rt/absvsi2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const absv = @import("./absv.zig").absv; + +pub const panic = common.panic; + +comptime { + @export(&__absvsi2, .{ .name = "__absvsi2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __absvsi2(a: i32) callconv(.c) i32 { + return absv(i32, a); +} diff --git a/build/compiler_rt/absvsi2_test.zig b/build/compiler_rt/absvsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/absvti2.zig b/build/compiler_rt/absvti2.zig new file mode 100644 index 00000000..be232ece --- /dev/null +++ b/build/compiler_rt/absvti2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const absv = @import("./absv.zig").absv; + +pub const panic = common.panic; + +comptime { + @export(&__absvti2, .{ .name = "__absvti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __absvti2(a: i128) callconv(.c) i128 { + return absv(i128, a); +} diff --git a/build/compiler_rt/absvti2_test.zig b/build/compiler_rt/absvti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/adddf3.zig b/build/compiler_rt/adddf3.zig new file mode 100644 index 00000000..3a10f555 --- /dev/null +++ b/build/compiler_rt/adddf3.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_dadd, .{ .name = "__aeabi_dadd", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__adddf3, .{ .name = "__adddf3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +fn __adddf3(a: f64, b: f64) callconv(.c) f64 { + return addf3(f64, a, b); +} + +fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return addf3(f64, a, b); +} diff --git a/build/compiler_rt/addf3.zig b/build/compiler_rt/addf3.zig new file mode 100644 index 00000000..60ae0165 --- /dev/null +++ b/build/compiler_rt/addf3.zig @@ -0,0 +1,171 @@ +const std = @import("std"); +const math = std.math; +const common = @import("./common.zig"); +const normalize = common.normalize; + +/// Ported from: +/// +/// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc +pub inline fn addf3(comptime T: type, a: T, b: T) T { + const bits = @typeInfo(T).float.bits; + const Z = std.meta.Int(.unsigned, bits); + + const typeWidth = bits; + const significandBits = math.floatMantissaBits(T); + const fractionalBits = math.floatFractionalBits(T); + const exponentBits = math.floatExponentBits(T); + + const signBit = (@as(Z, 1) << (significandBits + exponentBits)); + const maxExponent = ((1 << exponentBits) - 1); + + const integerBit = (@as(Z, 1) << fractionalBits); + const quietBit = integerBit >> 1; + const significandMask = (@as(Z, 1) << significandBits) - 1; + + const absMask = signBit - 1; + const qnanRep = @as(Z, @bitCast(math.nan(T))) | quietBit; + + var aRep: Z = @bitCast(a); + var bRep: Z = @bitCast(b); + const aAbs = aRep & absMask; + const bAbs = bRep & absMask; + + const infRep: Z = @bitCast(math.inf(T)); + + // Detect if a or b is zero, infinity, or NaN. + if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or + bAbs -% @as(Z, 1) >= infRep - @as(Z, 1)) + { + // NaN + anything = qNaN + if (aAbs > infRep) return @bitCast(@as(Z, @bitCast(a)) | quietBit); + // anything + NaN = qNaN + if (bAbs > infRep) return @bitCast(@as(Z, @bitCast(b)) | quietBit); + + if (aAbs == infRep) { + // +/-infinity + -/+infinity = qNaN + if ((@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) == signBit) { + return @bitCast(qnanRep); + } + // +/-infinity + anything remaining = +/- infinity + else { + return a; + } + } + + // anything remaining + +/-infinity = +/-infinity + if (bAbs == infRep) return b; + + // zero + anything = anything + if (aAbs == 0) { + // but we need to get the sign right for zero + zero + if (bAbs == 0) { + return @bitCast(@as(Z, @bitCast(a)) & @as(Z, @bitCast(b))); + } else { + return b; + } + } + + // anything + zero = anything + if (bAbs == 0) return a; + } + + // Swap a and b if necessary so that a has the larger absolute value. + if (bAbs > aAbs) { + const temp = aRep; + aRep = bRep; + bRep = temp; + } + + // Extract the exponent and significand from the (possibly swapped) a and b. + var aExponent: i32 = @intCast((aRep >> significandBits) & maxExponent); + var bExponent: i32 = @intCast((bRep >> significandBits) & maxExponent); + var aSignificand = aRep & significandMask; + var bSignificand = bRep & significandMask; + + // Normalize any denormals, and adjust the exponent accordingly. + if (aExponent == 0) aExponent = normalize(T, &aSignificand); + if (bExponent == 0) bExponent = normalize(T, &bSignificand); + + // The sign of the result is the sign of the larger operand, a. If they + // have opposite signs, we are performing a subtraction; otherwise addition. + const resultSign = aRep & signBit; + const subtraction = (aRep ^ bRep) & signBit != 0; + + // Shift the significands to give us round, guard and sticky, and or in the + // implicit significand bit. (If we fell through from the denormal path it + // was already set by normalize( ), but setting it twice won't hurt + // anything.) + aSignificand = (aSignificand | integerBit) << 3; + bSignificand = (bSignificand | integerBit) << 3; + + // Shift the significand of b by the difference in exponents, with a sticky + // bottom bit to get rounding correct. + const @"align": u32 = @intCast(aExponent - bExponent); + if (@"align" != 0) { + if (@"align" < typeWidth) { + const sticky = if (bSignificand << @intCast(typeWidth - @"align") != 0) @as(Z, 1) else 0; + bSignificand = (bSignificand >> @truncate(@"align")) | sticky; + } else { + bSignificand = 1; // sticky; b is known to be non-zero. + } + } + if (subtraction) { + aSignificand -= bSignificand; + // If a == -b, return +zero. + if (aSignificand == 0) return @bitCast(@as(Z, 0)); + + // If partial cancellation occurred, we need to left-shift the result + // and adjust the exponent: + if (aSignificand < integerBit << 3) { + const shift = @as(i32, @intCast(@clz(aSignificand))) - @as(i32, @intCast(@clz(integerBit << 3))); + aSignificand <<= @intCast(shift); + aExponent -= shift; + } + } else { // addition + aSignificand += bSignificand; + + // If the addition carried up, we need to right-shift the result and + // adjust the exponent: + if (aSignificand & (integerBit << 4) != 0) { + const sticky = aSignificand & 1; + aSignificand = aSignificand >> 1 | sticky; + aExponent += 1; + } + } + + // If we have overflowed the type, return +/- infinity: + if (aExponent >= maxExponent) return @bitCast(infRep | resultSign); + + if (aExponent <= 0) { + // Result is denormal; the exponent and round/sticky bits are zero. + // All we need to do is shift the significand and apply the correct sign. + aSignificand >>= @intCast(4 - aExponent); + return @bitCast(resultSign | aSignificand); + } + + // Low three bits are round, guard, and sticky. + const roundGuardSticky = aSignificand & 0x7; + + // Shift the significand into place, and mask off the integer bit, if it's implicit. + var result = (aSignificand >> 3) & significandMask; + + // Insert the exponent and sign. + result |= @as(Z, @intCast(aExponent)) << significandBits; + result |= resultSign; + + // Final rounding. The result may overflow to infinity, but that is the + // correct result in that case. + if (roundGuardSticky > 0x4) result += 1; + if (roundGuardSticky == 0x4) result += result & 1; + + // Restore any explicit integer bit, if it was rounded off + if (significandBits != fractionalBits) { + if ((result >> significandBits) != 0) result |= integerBit; + } + + return @bitCast(result); +} + +test { + _ = @import("addf3_test.zig"); +} diff --git a/build/compiler_rt/addf3_test.zig b/build/compiler_rt/addf3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/addhf3.zig b/build/compiler_rt/addhf3.zig new file mode 100644 index 00000000..48a63288 --- /dev/null +++ b/build/compiler_rt/addhf3.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + @export(&__addhf3, .{ .name = "__addhf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __addhf3(a: f16, b: f16) callconv(.c) f16 { + return addf3(f16, a, b); +} diff --git a/build/compiler_rt/addo.zig b/build/compiler_rt/addo.zig new file mode 100644 index 00000000..610d6206 --- /dev/null +++ b/build/compiler_rt/addo.zig @@ -0,0 +1,46 @@ +const std = @import("std"); +const common = @import("./common.zig"); +pub const panic = @import("common.zig").panic; + +comptime { + @export(&__addosi4, .{ .name = "__addosi4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__addodi4, .{ .name = "__addodi4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__addoti4, .{ .name = "__addoti4", .linkage = common.linkage, .visibility = common.visibility }); +} + +// addo - add overflow +// * return a+%b. +// * return if a+b overflows => 1 else => 0 +// - addoXi4_generic as default + +inline fn addoXi4_generic(comptime ST: type, a: ST, b: ST, overflow: *c_int) ST { + @setRuntimeSafety(common.test_safety); + overflow.* = 0; + const sum: ST = a +% b; + // Hackers Delight: section Overflow Detection, subsection Signed Add/Subtract + // Let sum = a +% b == a + b + carry == wraparound addition. + // Overflow in a+b+carry occurs, iff a and b have opposite signs + // and the sign of a+b+carry is the same as a (or equivalently b). + // Slower routine: res = ~(a ^ b) & ((sum ^ a) + // Faster routine: res = (sum ^ a) & (sum ^ b) + // Overflow occurred, iff (res < 0) + if (((sum ^ a) & (sum ^ b)) < 0) + overflow.* = 1; + return sum; +} + +pub fn __addosi4(a: i32, b: i32, overflow: *c_int) callconv(.c) i32 { + return addoXi4_generic(i32, a, b, overflow); +} +pub fn __addodi4(a: i64, b: i64, overflow: *c_int) callconv(.c) i64 { + return addoXi4_generic(i64, a, b, overflow); +} +pub fn __addoti4(a: i128, b: i128, overflow: *c_int) callconv(.c) i128 { + return addoXi4_generic(i128, a, b, overflow); +} + +test { + _ = @import("addosi4_test.zig"); + _ = @import("addodi4_test.zig"); + _ = @import("addoti4_test.zig"); +} diff --git a/build/compiler_rt/addodi4_test.zig b/build/compiler_rt/addodi4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/addosi4_test.zig b/build/compiler_rt/addosi4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/addoti4_test.zig b/build/compiler_rt/addoti4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/addsf3.zig b/build/compiler_rt/addsf3.zig new file mode 100644 index 00000000..c4b7773e --- /dev/null +++ b/build/compiler_rt/addsf3.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_fadd, .{ .name = "__aeabi_fadd", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__addsf3, .{ .name = "__addsf3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +fn __addsf3(a: f32, b: f32) callconv(.c) f32 { + return addf3(f32, a, b); +} + +fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + return addf3(f32, a, b); +} diff --git a/build/compiler_rt/addtf3.zig b/build/compiler_rt/addtf3.zig new file mode 100644 index 00000000..34e5bdf7 --- /dev/null +++ b/build/compiler_rt/addtf3.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__addtf3, .{ .name = "__addkf3", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_add, .{ .name = "_Qp_add", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__addtf3, .{ .name = "__addtf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __addtf3(a: f128, b: f128) callconv(.c) f128 { + return addf3(f128, a, b); +} + +fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void { + c.* = addf3(f128, a.*, b.*); +} diff --git a/build/compiler_rt/addvsi3.zig b/build/compiler_rt/addvsi3.zig new file mode 100644 index 00000000..04c19881 --- /dev/null +++ b/build/compiler_rt/addvsi3.zig @@ -0,0 +1,26 @@ +const addv = @import("addo.zig"); +const common = @import("./common.zig"); +const testing = @import("std").testing; + +pub const panic = common.panic; + +comptime { + @export(&__addvsi3, .{ .name = "__addvsi3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 { + var overflow: c_int = 0; + const sum = addv.__addosi4(a, b, &overflow); + if (overflow != 0) @panic("compiler-rt: integer overflow"); + return sum; +} + +test "addvsi3" { + // const min: i32 = -2147483648 + // const max: i32 = 2147483647 + // TODO write panic handler for testing panics + // try test__addvsi3(-2147483648, -1, -1); // panic + // try test__addvsi3(2147483647, 1, 1); // panic + try testing.expectEqual(-2147483648, __addvsi3(-2147483647, -1)); + try testing.expectEqual(2147483647, __addvsi3(2147483646, 1)); +} diff --git a/build/compiler_rt/addxf3.zig b/build/compiler_rt/addxf3.zig new file mode 100644 index 00000000..1aac7367 --- /dev/null +++ b/build/compiler_rt/addxf3.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + @export(&__addxf3, .{ .name = "__addxf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __addxf3(a: f80, b: f80) callconv(.c) f80 { + return addf3(f80, a, b); +} diff --git a/build/compiler_rt/arm.zig b/build/compiler_rt/arm.zig new file mode 100644 index 00000000..3c55df5f --- /dev/null +++ b/build/compiler_rt/arm.zig @@ -0,0 +1,267 @@ +//! Implementation of ARM specific builtins for Run-time ABI +//! This file includes all ARM-only functions. +const std = @import("std"); +const builtin = @import("builtin"); +const target = builtin.target; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + if (!builtin.is_test) { + if (arch.isArm()) { + @export(&__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&__aeabi_ldivmod, .{ .name = if (common.want_windows_arm_abi) "__rt_sdiv64" else "__aeabi_ldivmod", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_uldivmod, .{ .name = if (common.want_windows_arm_abi) "__rt_udiv64" else "__aeabi_uldivmod", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&__aeabi_idivmod, .{ .name = if (common.want_windows_arm_abi) "__rt_sdiv" else "__aeabi_idivmod", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_uidivmod, .{ .name = if (common.want_windows_arm_abi) "__rt_udiv" else "__aeabi_uidivmod", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_memcpy4, .{ .name = "__aeabi_memcpy4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_memcpy8, .{ .name = "__aeabi_memcpy8", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&__aeabi_memmove, .{ .name = "__aeabi_memmove", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_memmove4, .{ .name = "__aeabi_memmove4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_memmove8, .{ .name = "__aeabi_memmove8", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&__aeabi_memset, .{ .name = "__aeabi_memset", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_memset4, .{ .name = "__aeabi_memset4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_memset8, .{ .name = "__aeabi_memset8", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&__aeabi_memclr, .{ .name = "__aeabi_memclr", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_memclr4, .{ .name = "__aeabi_memclr4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_memclr8, .{ .name = "__aeabi_memclr8", .linkage = common.linkage, .visibility = common.visibility }); + + if (builtin.os.tag == .linux or builtin.os.tag == .freebsd) { + @export(&__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = common.linkage, .visibility = common.visibility }); + } + + // floating-point helper functions (single+double-precision reverse subtraction, y – x), see subdf3.zig + @export(&__aeabi_frsub, .{ .name = "__aeabi_frsub", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_drsub, .{ .name = "__aeabi_drsub", .linkage = common.linkage, .visibility = common.visibility }); + } + } +} + +const __divmodsi4 = @import("int.zig").__divmodsi4; +const __udivmodsi4 = @import("int.zig").__udivmodsi4; +const __divmoddi4 = @import("int.zig").__divmoddi4; +const __udivmoddi4 = @import("int.zig").__udivmoddi4; + +extern fn memset(dest: ?[*]u8, c: i32, n: usize) ?[*]u8; +extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) ?[*]u8; +extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) ?[*]u8; + +pub fn __aeabi_memcpy(dest: [*]u8, src: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memcpy(dest, src, n); +} +pub fn __aeabi_memcpy4(dest: [*]u8, src: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memcpy(dest, src, n); +} +pub fn __aeabi_memcpy8(dest: [*]u8, src: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memcpy(dest, src, n); +} + +pub fn __aeabi_memmove(dest: [*]u8, src: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memmove(dest, src, n); +} +pub fn __aeabi_memmove4(dest: [*]u8, src: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memmove(dest, src, n); +} +pub fn __aeabi_memmove8(dest: [*]u8, src: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memmove(dest, src, n); +} + +pub fn __aeabi_memset(dest: [*]u8, n: usize, c: i32) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + // This is dentical to the standard `memset` definition but with the last + // two arguments swapped + _ = memset(dest, c, n); +} +pub fn __aeabi_memset4(dest: [*]u8, n: usize, c: i32) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memset(dest, c, n); +} +pub fn __aeabi_memset8(dest: [*]u8, n: usize, c: i32) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memset(dest, c, n); +} + +pub fn __aeabi_memclr(dest: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memset(dest, 0, n); +} +pub fn __aeabi_memclr4(dest: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memset(dest, 0, n); +} +pub fn __aeabi_memclr8(dest: [*]u8, n: usize) callconv(.{ .arm_aapcs = .{} }) void { + @setRuntimeSafety(false); + _ = memset(dest, 0, n); +} + +// Dummy functions to avoid errors during the linking phase +pub fn __aeabi_unwind_cpp_pr0() callconv(.{ .arm_aapcs = .{} }) void {} +pub fn __aeabi_unwind_cpp_pr1() callconv(.{ .arm_aapcs = .{} }) void {} +pub fn __aeabi_unwind_cpp_pr2() callconv(.{ .arm_aapcs = .{} }) void {} + +// This function can only clobber r0 according to the ABI +pub fn __aeabi_read_tp() callconv(.naked) void { + @setRuntimeSafety(false); + asm volatile ( + \\ mrc p15, 0, r0, c13, c0, 3 + \\ bx lr + ); + unreachable; +} + +// The following functions are wrapped in an asm block to ensure the required +// calling convention is always respected + +pub fn __aeabi_uidivmod() callconv(.naked) void { + @setRuntimeSafety(false); + // Divide r0 by r1; the quotient goes in r0, the remainder in r1 + asm volatile ( + \\ push {lr} + \\ sub sp, #4 + \\ mov r2, sp + \\ bl %[__udivmodsi4] + \\ ldr r1, [sp] + \\ add sp, #4 + \\ pop {pc} + : + : [__udivmodsi4] "X" (&__udivmodsi4), + : .{ .memory = true }); + unreachable; +} + +pub fn __aeabi_uldivmod() callconv(.naked) void { + @setRuntimeSafety(false); + // Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2 + asm volatile ( + \\ push {r4, lr} + \\ sub sp, #16 + \\ add r4, sp, #8 + \\ str r4, [sp] + \\ bl %[__udivmoddi4] + \\ ldr r2, [sp, #8] + \\ ldr r3, [sp, #12] + \\ add sp, #16 + \\ pop {r4, pc} + : + : [__udivmoddi4] "X" (&__udivmoddi4), + : .{ .memory = true }); + unreachable; +} + +pub fn __aeabi_idivmod() callconv(.naked) void { + @setRuntimeSafety(false); + // Divide r0 by r1; the quotient goes in r0, the remainder in r1 + asm volatile ( + \\ push {lr} + \\ sub sp, #4 + \\ mov r2, sp + \\ bl %[__divmodsi4] + \\ ldr r1, [sp] + \\ add sp, #4 + \\ pop {pc} + : + : [__divmodsi4] "X" (&__divmodsi4), + : .{ .memory = true }); + unreachable; +} + +pub fn __aeabi_ldivmod() callconv(.naked) void { + @setRuntimeSafety(false); + // Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2 + asm volatile ( + \\ push {r4, lr} + \\ sub sp, #16 + \\ add r4, sp, #8 + \\ str r4, [sp] + \\ bl %[__divmoddi4] + \\ ldr r2, [sp, #8] + \\ ldr r3, [sp, #12] + \\ add sp, #16 + \\ pop {r4, pc} + : + : [__divmoddi4] "X" (&__divmoddi4), + : .{ .memory = true }); + unreachable; +} + +// Float Arithmetic + +fn __aeabi_frsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + const neg_a: f32 = @bitCast(@as(u32, @bitCast(a)) ^ (@as(u32, 1) << 31)); + return b + neg_a; +} + +fn __aeabi_drsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + const neg_a: f64 = @bitCast(@as(u64, @bitCast(a)) ^ (@as(u64, 1) << 63)); + return b + neg_a; +} + +test "__aeabi_frsub" { + if (!builtin.cpu.arch.isArm() or builtin.cpu.arch.isThumb()) return error.SkipZigTest; + const inf32 = std.math.inf(f32); + const maxf32 = std.math.floatMax(f32); + const frsub_data = [_][3]f32{ + [_]f32{ 0.0, 0.0, -0.0 }, + [_]f32{ 0.0, -0.0, -0.0 }, + [_]f32{ -0.0, 0.0, 0.0 }, + [_]f32{ -0.0, -0.0, -0.0 }, + [_]f32{ 0.0, 1.0, 1.0 }, + [_]f32{ 1.0, 0.0, -1.0 }, + [_]f32{ 1.0, 1.0, 0.0 }, + [_]f32{ 1234.56789, 9876.54321, 8641.97532 }, + [_]f32{ 9876.54321, 1234.56789, -8641.97532 }, + [_]f32{ -8641.97532, 1234.56789, 9876.54321 }, + [_]f32{ 8641.97532, 9876.54321, 1234.56789 }, + [_]f32{ -maxf32, -maxf32, 0.0 }, + [_]f32{ maxf32, maxf32, 0.0 }, + [_]f32{ maxf32, -maxf32, -inf32 }, + [_]f32{ -maxf32, maxf32, inf32 }, + }; + for (frsub_data) |data| { + try std.testing.expectApproxEqAbs(data[2], __aeabi_frsub(data[0], data[1]), 0.001); + } +} + +test "__aeabi_drsub" { + if (!builtin.cpu.arch.isArm() or builtin.cpu.arch.isThumb()) return error.SkipZigTest; + if (builtin.cpu.arch == .armeb and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/22061 + const inf64 = std.math.inf(f64); + const maxf64 = std.math.floatMax(f64); + const frsub_data = [_][3]f64{ + [_]f64{ 0.0, 0.0, -0.0 }, + [_]f64{ 0.0, -0.0, -0.0 }, + [_]f64{ -0.0, 0.0, 0.0 }, + [_]f64{ -0.0, -0.0, -0.0 }, + [_]f64{ 0.0, 1.0, 1.0 }, + [_]f64{ 1.0, 0.0, -1.0 }, + [_]f64{ 1.0, 1.0, 0.0 }, + [_]f64{ 1234.56789, 9876.54321, 8641.97532 }, + [_]f64{ 9876.54321, 1234.56789, -8641.97532 }, + [_]f64{ -8641.97532, 1234.56789, 9876.54321 }, + [_]f64{ 8641.97532, 9876.54321, 1234.56789 }, + [_]f64{ -maxf64, -maxf64, 0.0 }, + [_]f64{ maxf64, maxf64, 0.0 }, + [_]f64{ maxf64, -maxf64, -inf64 }, + [_]f64{ -maxf64, maxf64, inf64 }, + }; + for (frsub_data) |data| { + try std.testing.expectApproxEqAbs(data[2], __aeabi_drsub(data[0], data[1]), 0.000001); + } +} diff --git a/build/compiler_rt/atomics.zig b/build/compiler_rt/atomics.zig new file mode 100644 index 00000000..09fd1c2c --- /dev/null +++ b/build/compiler_rt/atomics.zig @@ -0,0 +1,616 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const cpu = builtin.cpu; +const arch = cpu.arch; +const linkage = common.linkage; +const visibility = common.visibility; +pub const panic = common.panic; + +// This parameter is true iff the target architecture supports the bare minimum +// to implement the atomic load/store intrinsics. +// Some architectures support atomic load/stores but no CAS, but we ignore this +// detail to keep the export logic clean and because we need some kind of CAS to +// implement the spinlocks. +const supports_atomic_ops = switch (arch) { + .msp430, .avr, .bpfel, .bpfeb => false, + .arm, .armeb, .thumb, .thumbeb => + // The ARM v6m ISA has no ldrex/strex and so it's impossible to do CAS + // operations (unless we're targeting Linux, the kernel provides a way to + // perform CAS operations). + // XXX: The Linux code path is not implemented yet. + !builtin.cpu.has(.arm, .has_v6m), + else => true, +}; + +// The size (in bytes) of the biggest object that the architecture can +// load/store atomically. +// Objects bigger than this threshold require the use of a lock. +const largest_atomic_size = switch (arch) { + // On SPARC systems that lacks CAS and/or swap instructions, the only + // available atomic operation is a test-and-set (`ldstub`), so we force + // every atomic memory access to go through the lock. + .sparc => if (builtin.cpu.has(.sparc, .hasleoncasa)) @sizeOf(usize) else 0, + + // XXX: On x86/x86_64 we could check the presence of cmpxchg8b/cmpxchg16b + // and set this parameter accordingly. + else => @sizeOf(usize), +}; + +// The size (in bytes) of the smallest atomic object that the architecture can +// perform fetch/exchange atomically. Note, this does not encompass load and store. +// Objects smaller than this threshold are implemented in terms of compare-exchange +// of a larger value. +const smallest_atomic_fetch_exch_size = switch (arch) { + // On AMDGCN, there are no instructions for atomic operations other than load and store + // (as of LLVM 15), and so these need to be implemented in terms of atomic CAS. + .amdgcn => @sizeOf(u32), + else => @sizeOf(u8), +}; + +const cache_line_size = 64; + +const SpinlockTable = struct { + // Allocate ~4096 bytes of memory for the spinlock table + const max_spinlocks = 64; + + const Spinlock = struct { + // SPARC ldstub instruction will write a 255 into the memory location. + // We'll use that as a sign that the lock is currently held. + // See also: Section B.7 in SPARCv8 spec & A.29 in SPARCv9 spec. + const sparc_lock: type = enum(u8) { Unlocked = 0, Locked = 255 }; + const other_lock: type = enum(usize) { Unlocked = 0, Locked }; + + // Prevent false sharing by providing enough padding between two + // consecutive spinlock elements + v: if (arch.isSPARC()) sparc_lock else other_lock align(cache_line_size) = .Unlocked, + + fn acquire(self: *@This()) void { + while (true) { + const flag = if (comptime arch.isSPARC()) flag: { + break :flag asm volatile ("ldstub [%[addr]], %[flag]" + : [flag] "=r" (-> @TypeOf(self.v)), + : [addr] "r" (&self.v), + : .{ .memory = true }); + } else flag: { + break :flag @atomicRmw(@TypeOf(self.v), &self.v, .Xchg, .Locked, .acquire); + }; + + switch (flag) { + .Unlocked => break, + .Locked => {}, + } + } + } + fn release(self: *@This()) void { + if (comptime arch.isSPARC()) { + _ = asm volatile ("clrb [%[addr]]" + : + : [addr] "r" (&self.v), + : .{ .memory = true }); + } else { + @atomicStore(@TypeOf(self.v), &self.v, .Unlocked, .release); + } + } + }; + + list: [max_spinlocks]Spinlock = [_]Spinlock{.{}} ** max_spinlocks, + + // The spinlock table behaves as a really simple hash table, mapping + // addresses to spinlocks. The mapping is not unique but that's only a + // performance problem as the lock will be contended by more than a pair of + // threads. + fn get(self: *@This(), address: usize) *Spinlock { + var sl = &self.list[(address >> 3) % max_spinlocks]; + sl.acquire(); + return sl; + } +}; + +var spinlocks: SpinlockTable = SpinlockTable{}; + +// The following builtins do not respect the specified memory model and instead +// uses seq_cst, the strongest one, for simplicity sake. + +// Generic version of GCC atomic builtin functions. +// Those work on any object no matter the pointer alignment nor its size. + +fn __atomic_load(size: u32, src: [*]u8, dest: [*]u8, model: i32) callconv(.c) void { + _ = model; + var sl = spinlocks.get(@intFromPtr(src)); + defer sl.release(); + @memcpy(dest[0..size], src); +} + +fn __atomic_store(size: u32, dest: [*]u8, src: [*]u8, model: i32) callconv(.c) void { + _ = model; + var sl = spinlocks.get(@intFromPtr(dest)); + defer sl.release(); + @memcpy(dest[0..size], src); +} + +fn __atomic_exchange(size: u32, ptr: [*]u8, val: [*]u8, old: [*]u8, model: i32) callconv(.c) void { + _ = model; + var sl = spinlocks.get(@intFromPtr(ptr)); + defer sl.release(); + @memcpy(old[0..size], ptr); + @memcpy(ptr[0..size], val); +} + +fn __atomic_compare_exchange( + size: u32, + ptr: [*]u8, + expected: [*]u8, + desired: [*]u8, + success: i32, + failure: i32, +) callconv(.c) i32 { + _ = success; + _ = failure; + var sl = spinlocks.get(@intFromPtr(ptr)); + defer sl.release(); + for (ptr[0..size], 0..) |b, i| { + if (expected[i] != b) break; + } else { + // The two objects, ptr and expected, are equal + @memcpy(ptr[0..size], desired); + return 1; + } + @memcpy(expected[0..size], ptr); + return 0; +} + +// Specialized versions of the GCC atomic builtin functions. +// LLVM emits those iff the object size is known and the pointers are correctly +// aligned. +inline fn atomic_load_N(comptime T: type, src: *T, model: i32) T { + _ = model; + if (@sizeOf(T) > largest_atomic_size) { + var sl = spinlocks.get(@intFromPtr(src)); + defer sl.release(); + return src.*; + } else { + return @atomicLoad(T, src, .seq_cst); + } +} + +fn __atomic_load_1(src: *u8, model: i32) callconv(.c) u8 { + return atomic_load_N(u8, src, model); +} + +fn __atomic_load_2(src: *u16, model: i32) callconv(.c) u16 { + return atomic_load_N(u16, src, model); +} + +fn __atomic_load_4(src: *u32, model: i32) callconv(.c) u32 { + return atomic_load_N(u32, src, model); +} + +fn __atomic_load_8(src: *u64, model: i32) callconv(.c) u64 { + return atomic_load_N(u64, src, model); +} + +fn __atomic_load_16(src: *u128, model: i32) callconv(.c) u128 { + return atomic_load_N(u128, src, model); +} + +inline fn atomic_store_N(comptime T: type, dst: *T, value: T, model: i32) void { + _ = model; + if (@sizeOf(T) > largest_atomic_size) { + var sl = spinlocks.get(@intFromPtr(dst)); + defer sl.release(); + dst.* = value; + } else { + @atomicStore(T, dst, value, .seq_cst); + } +} + +fn __atomic_store_1(dst: *u8, value: u8, model: i32) callconv(.c) void { + return atomic_store_N(u8, dst, value, model); +} + +fn __atomic_store_2(dst: *u16, value: u16, model: i32) callconv(.c) void { + return atomic_store_N(u16, dst, value, model); +} + +fn __atomic_store_4(dst: *u32, value: u32, model: i32) callconv(.c) void { + return atomic_store_N(u32, dst, value, model); +} + +fn __atomic_store_8(dst: *u64, value: u64, model: i32) callconv(.c) void { + return atomic_store_N(u64, dst, value, model); +} + +fn __atomic_store_16(dst: *u128, value: u128, model: i32) callconv(.c) void { + return atomic_store_N(u128, dst, value, model); +} + +fn wideUpdate(comptime T: type, ptr: *T, val: T, update: anytype) T { + const WideAtomic = std.meta.Int(.unsigned, smallest_atomic_fetch_exch_size * 8); + + const addr = @intFromPtr(ptr); + const wide_addr = addr & ~(@as(T, smallest_atomic_fetch_exch_size) - 1); + const wide_ptr: *align(smallest_atomic_fetch_exch_size) WideAtomic = @alignCast(@as(*WideAtomic, @ptrFromInt(wide_addr))); + + const inner_offset = addr & (@as(T, smallest_atomic_fetch_exch_size) - 1); + const inner_shift = @as(std.math.Log2Int(T), @intCast(inner_offset * 8)); + + const mask = @as(WideAtomic, std.math.maxInt(T)) << inner_shift; + + var wide_old = @atomicLoad(WideAtomic, wide_ptr, .seq_cst); + while (true) { + const old = @as(T, @truncate((wide_old & mask) >> inner_shift)); + const new = update(val, old); + const wide_new = wide_old & ~mask | (@as(WideAtomic, new) << inner_shift); + if (@cmpxchgWeak(WideAtomic, wide_ptr, wide_old, wide_new, .seq_cst, .seq_cst)) |new_wide_old| { + wide_old = new_wide_old; + } else { + return old; + } + } +} + +inline fn atomic_exchange_N(comptime T: type, ptr: *T, val: T, model: i32) T { + _ = model; + if (@sizeOf(T) > largest_atomic_size) { + var sl = spinlocks.get(@intFromPtr(ptr)); + defer sl.release(); + const value = ptr.*; + ptr.* = val; + return value; + } else if (@sizeOf(T) < smallest_atomic_fetch_exch_size) { + // Machine does not support this type, but it does support a larger type. + const Updater = struct { + fn update(new: T, old: T) T { + _ = old; + return new; + } + }; + return wideUpdate(T, ptr, val, Updater.update); + } else { + return @atomicRmw(T, ptr, .Xchg, val, .seq_cst); + } +} + +fn __atomic_exchange_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return atomic_exchange_N(u8, ptr, val, model); +} + +fn __atomic_exchange_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return atomic_exchange_N(u16, ptr, val, model); +} + +fn __atomic_exchange_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return atomic_exchange_N(u32, ptr, val, model); +} + +fn __atomic_exchange_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return atomic_exchange_N(u64, ptr, val, model); +} + +fn __atomic_exchange_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return atomic_exchange_N(u128, ptr, val, model); +} + +inline fn atomic_compare_exchange_N( + comptime T: type, + ptr: *T, + expected: *T, + desired: T, + success: i32, + failure: i32, +) i32 { + _ = success; + _ = failure; + if (@sizeOf(T) > largest_atomic_size) { + var sl = spinlocks.get(@intFromPtr(ptr)); + defer sl.release(); + const value = ptr.*; + if (value == expected.*) { + ptr.* = desired; + return 1; + } + expected.* = value; + return 0; + } else { + if (@cmpxchgStrong(T, ptr, expected.*, desired, .seq_cst, .seq_cst)) |old_value| { + expected.* = old_value; + return 0; + } + return 1; + } +} + +fn __atomic_compare_exchange_1(ptr: *u8, expected: *u8, desired: u8, success: i32, failure: i32) callconv(.c) i32 { + return atomic_compare_exchange_N(u8, ptr, expected, desired, success, failure); +} + +fn __atomic_compare_exchange_2(ptr: *u16, expected: *u16, desired: u16, success: i32, failure: i32) callconv(.c) i32 { + return atomic_compare_exchange_N(u16, ptr, expected, desired, success, failure); +} + +fn __atomic_compare_exchange_4(ptr: *u32, expected: *u32, desired: u32, success: i32, failure: i32) callconv(.c) i32 { + return atomic_compare_exchange_N(u32, ptr, expected, desired, success, failure); +} + +fn __atomic_compare_exchange_8(ptr: *u64, expected: *u64, desired: u64, success: i32, failure: i32) callconv(.c) i32 { + return atomic_compare_exchange_N(u64, ptr, expected, desired, success, failure); +} + +fn __atomic_compare_exchange_16(ptr: *u128, expected: *u128, desired: u128, success: i32, failure: i32) callconv(.c) i32 { + return atomic_compare_exchange_N(u128, ptr, expected, desired, success, failure); +} + +inline fn fetch_op_N(comptime T: type, comptime op: std.builtin.AtomicRmwOp, ptr: *T, val: T, model: i32) T { + _ = model; + const Updater = struct { + fn update(new: T, old: T) T { + return switch (op) { + .Add => old +% new, + .Sub => old -% new, + .And => old & new, + .Nand => ~(old & new), + .Or => old | new, + .Xor => old ^ new, + .Max => @max(old, new), + .Min => @min(old, new), + else => @compileError("unsupported atomic op"), + }; + } + }; + + if (@sizeOf(T) > largest_atomic_size) { + var sl = spinlocks.get(@intFromPtr(ptr)); + defer sl.release(); + + const value = ptr.*; + ptr.* = Updater.update(val, value); + return value; + } else if (@sizeOf(T) < smallest_atomic_fetch_exch_size) { + // Machine does not support this type, but it does support a larger type. + return wideUpdate(T, ptr, val, Updater.update); + } + + return @atomicRmw(T, ptr, op, val, .seq_cst); +} + +fn __atomic_fetch_add_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return fetch_op_N(u8, .Add, ptr, val, model); +} + +fn __atomic_fetch_add_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return fetch_op_N(u16, .Add, ptr, val, model); +} + +fn __atomic_fetch_add_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return fetch_op_N(u32, .Add, ptr, val, model); +} + +fn __atomic_fetch_add_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return fetch_op_N(u64, .Add, ptr, val, model); +} + +fn __atomic_fetch_add_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return fetch_op_N(u128, .Add, ptr, val, model); +} + +fn __atomic_fetch_sub_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return fetch_op_N(u8, .Sub, ptr, val, model); +} + +fn __atomic_fetch_sub_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return fetch_op_N(u16, .Sub, ptr, val, model); +} + +fn __atomic_fetch_sub_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return fetch_op_N(u32, .Sub, ptr, val, model); +} + +fn __atomic_fetch_sub_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return fetch_op_N(u64, .Sub, ptr, val, model); +} + +fn __atomic_fetch_sub_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return fetch_op_N(u128, .Sub, ptr, val, model); +} + +fn __atomic_fetch_and_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return fetch_op_N(u8, .And, ptr, val, model); +} + +fn __atomic_fetch_and_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return fetch_op_N(u16, .And, ptr, val, model); +} + +fn __atomic_fetch_and_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return fetch_op_N(u32, .And, ptr, val, model); +} + +fn __atomic_fetch_and_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return fetch_op_N(u64, .And, ptr, val, model); +} + +fn __atomic_fetch_and_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return fetch_op_N(u128, .And, ptr, val, model); +} + +fn __atomic_fetch_or_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return fetch_op_N(u8, .Or, ptr, val, model); +} + +fn __atomic_fetch_or_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return fetch_op_N(u16, .Or, ptr, val, model); +} + +fn __atomic_fetch_or_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return fetch_op_N(u32, .Or, ptr, val, model); +} + +fn __atomic_fetch_or_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return fetch_op_N(u64, .Or, ptr, val, model); +} + +fn __atomic_fetch_or_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return fetch_op_N(u128, .Or, ptr, val, model); +} + +fn __atomic_fetch_xor_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return fetch_op_N(u8, .Xor, ptr, val, model); +} + +fn __atomic_fetch_xor_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return fetch_op_N(u16, .Xor, ptr, val, model); +} + +fn __atomic_fetch_xor_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return fetch_op_N(u32, .Xor, ptr, val, model); +} + +fn __atomic_fetch_xor_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return fetch_op_N(u64, .Xor, ptr, val, model); +} + +fn __atomic_fetch_xor_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return fetch_op_N(u128, .Xor, ptr, val, model); +} + +fn __atomic_fetch_nand_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return fetch_op_N(u8, .Nand, ptr, val, model); +} + +fn __atomic_fetch_nand_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return fetch_op_N(u16, .Nand, ptr, val, model); +} + +fn __atomic_fetch_nand_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return fetch_op_N(u32, .Nand, ptr, val, model); +} + +fn __atomic_fetch_nand_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return fetch_op_N(u64, .Nand, ptr, val, model); +} + +fn __atomic_fetch_nand_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return fetch_op_N(u128, .Nand, ptr, val, model); +} + +fn __atomic_fetch_umax_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return fetch_op_N(u8, .Max, ptr, val, model); +} + +fn __atomic_fetch_umax_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return fetch_op_N(u16, .Max, ptr, val, model); +} + +fn __atomic_fetch_umax_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return fetch_op_N(u32, .Max, ptr, val, model); +} + +fn __atomic_fetch_umax_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return fetch_op_N(u64, .Max, ptr, val, model); +} + +fn __atomic_fetch_umax_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return fetch_op_N(u128, .Max, ptr, val, model); +} + +fn __atomic_fetch_umin_1(ptr: *u8, val: u8, model: i32) callconv(.c) u8 { + return fetch_op_N(u8, .Min, ptr, val, model); +} + +fn __atomic_fetch_umin_2(ptr: *u16, val: u16, model: i32) callconv(.c) u16 { + return fetch_op_N(u16, .Min, ptr, val, model); +} + +fn __atomic_fetch_umin_4(ptr: *u32, val: u32, model: i32) callconv(.c) u32 { + return fetch_op_N(u32, .Min, ptr, val, model); +} + +fn __atomic_fetch_umin_8(ptr: *u64, val: u64, model: i32) callconv(.c) u64 { + return fetch_op_N(u64, .Min, ptr, val, model); +} + +fn __atomic_fetch_umin_16(ptr: *u128, val: u128, model: i32) callconv(.c) u128 { + return fetch_op_N(u128, .Min, ptr, val, model); +} + +comptime { + if (supports_atomic_ops and builtin.object_format != .c) { + @export(&__atomic_load, .{ .name = "__atomic_load", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_store, .{ .name = "__atomic_store", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_exchange, .{ .name = "__atomic_exchange", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_compare_exchange, .{ .name = "__atomic_compare_exchange", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_fetch_add_1, .{ .name = "__atomic_fetch_add_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_add_2, .{ .name = "__atomic_fetch_add_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_add_4, .{ .name = "__atomic_fetch_add_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_add_8, .{ .name = "__atomic_fetch_add_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_add_16, .{ .name = "__atomic_fetch_add_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_fetch_sub_1, .{ .name = "__atomic_fetch_sub_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_sub_2, .{ .name = "__atomic_fetch_sub_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_sub_4, .{ .name = "__atomic_fetch_sub_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_sub_8, .{ .name = "__atomic_fetch_sub_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_sub_16, .{ .name = "__atomic_fetch_sub_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_fetch_and_1, .{ .name = "__atomic_fetch_and_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_and_2, .{ .name = "__atomic_fetch_and_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_and_4, .{ .name = "__atomic_fetch_and_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_and_8, .{ .name = "__atomic_fetch_and_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_and_16, .{ .name = "__atomic_fetch_and_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_fetch_or_1, .{ .name = "__atomic_fetch_or_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_or_2, .{ .name = "__atomic_fetch_or_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_or_4, .{ .name = "__atomic_fetch_or_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_or_8, .{ .name = "__atomic_fetch_or_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_or_16, .{ .name = "__atomic_fetch_or_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_fetch_xor_1, .{ .name = "__atomic_fetch_xor_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_xor_2, .{ .name = "__atomic_fetch_xor_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_xor_4, .{ .name = "__atomic_fetch_xor_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_xor_8, .{ .name = "__atomic_fetch_xor_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_xor_16, .{ .name = "__atomic_fetch_xor_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_fetch_nand_1, .{ .name = "__atomic_fetch_nand_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_nand_2, .{ .name = "__atomic_fetch_nand_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_nand_4, .{ .name = "__atomic_fetch_nand_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_nand_8, .{ .name = "__atomic_fetch_nand_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_nand_16, .{ .name = "__atomic_fetch_nand_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_fetch_umax_1, .{ .name = "__atomic_fetch_umax_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_umax_2, .{ .name = "__atomic_fetch_umax_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_umax_4, .{ .name = "__atomic_fetch_umax_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_umax_8, .{ .name = "__atomic_fetch_umax_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_umax_16, .{ .name = "__atomic_fetch_umax_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_fetch_umin_1, .{ .name = "__atomic_fetch_umin_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_umin_2, .{ .name = "__atomic_fetch_umin_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_umin_4, .{ .name = "__atomic_fetch_umin_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_umin_8, .{ .name = "__atomic_fetch_umin_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_fetch_umin_16, .{ .name = "__atomic_fetch_umin_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_load_1, .{ .name = "__atomic_load_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_load_2, .{ .name = "__atomic_load_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_load_4, .{ .name = "__atomic_load_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_load_8, .{ .name = "__atomic_load_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_load_16, .{ .name = "__atomic_load_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_store_1, .{ .name = "__atomic_store_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_store_2, .{ .name = "__atomic_store_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_store_4, .{ .name = "__atomic_store_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_store_8, .{ .name = "__atomic_store_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_store_16, .{ .name = "__atomic_store_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_exchange_1, .{ .name = "__atomic_exchange_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_exchange_2, .{ .name = "__atomic_exchange_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_exchange_4, .{ .name = "__atomic_exchange_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_exchange_8, .{ .name = "__atomic_exchange_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_exchange_16, .{ .name = "__atomic_exchange_16", .linkage = linkage, .visibility = visibility }); + + @export(&__atomic_compare_exchange_1, .{ .name = "__atomic_compare_exchange_1", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_compare_exchange_2, .{ .name = "__atomic_compare_exchange_2", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_compare_exchange_4, .{ .name = "__atomic_compare_exchange_4", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_compare_exchange_8, .{ .name = "__atomic_compare_exchange_8", .linkage = linkage, .visibility = visibility }); + @export(&__atomic_compare_exchange_16, .{ .name = "__atomic_compare_exchange_16", .linkage = linkage, .visibility = visibility }); + } +} diff --git a/build/compiler_rt/aulldiv.zig b/build/compiler_rt/aulldiv.zig new file mode 100644 index 00000000..2f57ab16 --- /dev/null +++ b/build/compiler_rt/aulldiv.zig @@ -0,0 +1,90 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const os = builtin.os.tag; +const abi = builtin.abi; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + if (arch == .x86 and common.want_windows_msvc_or_itanium_abi and !builtin.link_libc) { + // Don't let LLVM apply the stdcall name mangling on those MSVC builtins + @export(&_alldiv, .{ .name = "\x01__alldiv", .linkage = common.linkage, .visibility = common.visibility }); + @export(&_aulldiv, .{ .name = "\x01__aulldiv", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn _alldiv(a: i64, b: i64) callconv(.{ .x86_stdcall = .{} }) i64 { + const s_a = a >> (64 - 1); + const s_b = b >> (64 - 1); + + const an = (a ^ s_a) -% s_a; + const bn = (b ^ s_b) -% s_b; + + const r = @as(u64, @bitCast(an)) / @as(u64, @bitCast(bn)); + const s = s_a ^ s_b; + return (@as(i64, @bitCast(r)) ^ s) -% s; +} + +pub fn _aulldiv() callconv(.naked) void { + @setRuntimeSafety(false); + + // The stack layout is: + // ESP+16 divisor (hi) + // ESP+12 divisor (low) + // ESP+8 dividend (hi) + // ESP+4 dividend (low) + // ESP return address + + asm volatile ( + \\ push %%ebx + \\ push %%esi + \\ mov 0x18(%%esp),%%eax + \\ or %%eax,%%eax + \\ jne 1f + \\ mov 0x14(%%esp),%%ecx + \\ mov 0x10(%%esp),%%eax + \\ xor %%edx,%%edx + \\ div %%ecx + \\ mov %%eax,%%ebx + \\ mov 0xc(%%esp),%%eax + \\ div %%ecx + \\ mov %%ebx,%%edx + \\ jmp 5f + \\ 1: + \\ mov %%eax,%%ecx + \\ mov 0x14(%%esp),%%ebx + \\ mov 0x10(%%esp),%%edx + \\ mov 0xc(%%esp),%%eax + \\ 2: + \\ shr %%ecx + \\ rcr %%ebx + \\ shr %%edx + \\ rcr %%eax + \\ or %%ecx,%%ecx + \\ jne 2b + \\ div %%ebx + \\ mov %%eax,%%esi + \\ mull 0x18(%%esp) + \\ mov %%eax,%%ecx + \\ mov 0x14(%%esp),%%eax + \\ mul %%esi + \\ add %%ecx,%%edx + \\ jb 3f + \\ cmp 0x10(%%esp),%%edx + \\ ja 3f + \\ jb 4f + \\ cmp 0xc(%%esp),%%eax + \\ jbe 4f + \\ 3: + \\ dec %%esi + \\ 4: + \\ xor %%edx,%%edx + \\ mov %%esi,%%eax + \\ 5: + \\ pop %%esi + \\ pop %%ebx + \\ ret $0x10 + ); +} diff --git a/build/compiler_rt/aullrem.zig b/build/compiler_rt/aullrem.zig new file mode 100644 index 00000000..df50ef73 --- /dev/null +++ b/build/compiler_rt/aullrem.zig @@ -0,0 +1,91 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const os = builtin.os.tag; +const abi = builtin.abi; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + if (arch == .x86 and common.want_windows_msvc_or_itanium_abi and !builtin.link_libc) { + // Don't let LLVM apply the stdcall name mangling on those MSVC builtins + @export(&_allrem, .{ .name = "\x01__allrem", .linkage = common.linkage, .visibility = common.visibility }); + @export(&_aullrem, .{ .name = "\x01__aullrem", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn _allrem(a: i64, b: i64) callconv(.{ .x86_stdcall = .{} }) i64 { + const s_a = a >> (64 - 1); + const s_b = b >> (64 - 1); + + const an = (a ^ s_a) -% s_a; + const bn = (b ^ s_b) -% s_b; + + const r = @as(u64, @bitCast(an)) % @as(u64, @bitCast(bn)); + const s = s_a ^ s_b; + return (@as(i64, @bitCast(r)) ^ s) -% s; +} + +pub fn _aullrem() callconv(.naked) void { + @setRuntimeSafety(false); + + // The stack layout is: + // ESP+16 divisor (hi) + // ESP+12 divisor (low) + // ESP+8 dividend (hi) + // ESP+4 dividend (low) + // ESP return address + + asm volatile ( + \\ push %%ebx + \\ mov 0x14(%%esp),%%eax + \\ or %%eax,%%eax + \\ jne 1f + \\ mov 0x10(%%esp),%%ecx + \\ mov 0xc(%%esp),%%eax + \\ xor %%edx,%%edx + \\ div %%ecx + \\ mov 0x8(%%esp),%%eax + \\ div %%ecx + \\ mov %%edx,%%eax + \\ xor %%edx,%%edx + \\ jmp 6f + \\ 1: + \\ mov %%eax,%%ecx + \\ mov 0x10(%%esp),%%ebx + \\ mov 0xc(%%esp),%%edx + \\ mov 0x8(%%esp),%%eax + \\ 2: + \\ shr %%ecx + \\ rcr %%ebx + \\ shr %%edx + \\ rcr %%eax + \\ or %%ecx,%%ecx + \\ jne 2b + \\ div %%ebx + \\ mov %%eax,%%ecx + \\ mull 0x14(%%esp) + \\ xchg %%eax,%%ecx + \\ mull 0x10(%%esp) + \\ add %%ecx,%%edx + \\ jb 3f + \\ cmp 0xc(%%esp),%%edx + \\ ja 3f + \\ jb 4f + \\ cmp 0x8(%%esp),%%eax + \\ jbe 4f + \\ 3: + \\ sub 0x10(%%esp),%%eax + \\ sbb 0x14(%%esp),%%edx + \\ 4: + \\ sub 0x8(%%esp),%%eax + \\ sbb 0xc(%%esp),%%edx + \\ neg %%edx + \\ neg %%eax + \\ sbb $0x0,%%edx + \\ 6: + \\ pop %%ebx + \\ ret $0x10 + ); +} diff --git a/build/compiler_rt/bcmp.zig b/build/compiler_rt/bcmp.zig new file mode 100644 index 00000000..eb1fca21 --- /dev/null +++ b/build/compiler_rt/bcmp.zig @@ -0,0 +1,30 @@ +const std = @import("std"); +const common = @import("./common.zig"); + +comptime { + @export(&bcmp, .{ .name = "bcmp", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.c) c_int { + @setRuntimeSafety(false); + + var index: usize = 0; + while (index != n) : (index += 1) { + if (vl[index] != vr[index]) { + return 1; + } + } + + return 0; +} + +test "bcmp" { + const base_arr = &[_]u8{ 1, 1, 1 }; + const arr1 = &[_]u8{ 1, 1, 1 }; + const arr2 = &[_]u8{ 1, 0, 1 }; + const arr3 = &[_]u8{ 1, 2, 1 }; + + try std.testing.expect(bcmp(base_arr[0..], arr1[0..], base_arr.len) == 0); + try std.testing.expect(bcmp(base_arr[0..], arr2[0..], base_arr.len) != 0); + try std.testing.expect(bcmp(base_arr[0..], arr3[0..], base_arr.len) != 0); +} diff --git a/build/compiler_rt/bitreverse.zig b/build/compiler_rt/bitreverse.zig new file mode 100644 index 00000000..fe6cf898 --- /dev/null +++ b/build/compiler_rt/bitreverse.zig @@ -0,0 +1,65 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__bitreversesi2, .{ .name = "__bitreversesi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__bitreversedi2, .{ .name = "__bitreversedi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__bitreverseti2, .{ .name = "__bitreverseti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +inline fn bitreverseXi2(comptime T: type, a: T) T { + switch (@bitSizeOf(T)) { + 32 => { + var t: T = a; + t = ((t >> 1) & 0x55555555) | ((t & 0x55555555) << 1); + t = ((t >> 2) & 0x33333333) | ((t & 0x33333333) << 2); + t = ((t >> 4) & 0x0F0F0F0F) | ((t & 0x0F0F0F0F) << 4); + t = ((t >> 8) & 0x00FF00FF) | ((t & 0x00FF00FF) << 8); + t = (t >> 16) | (t << 16); + return t; + }, + 64 => { + var t: T = a; + t = ((t >> 1) & 0x5555555555555555) | ((t & 0x5555555555555555) << 1); + t = ((t >> 2) & 0x3333333333333333) | ((t & 0x3333333333333333) << 2); + t = ((t >> 4) & 0x0F0F0F0F0F0F0F0F) | ((t & 0x0F0F0F0F0F0F0F0F) << 4); + t = ((t >> 8) & 0x00FF00FF00FF00FF) | ((t & 0x00FF00FF00FF00FF) << 8); + t = ((t >> 16) & 0x0000FFFF0000FFFF) | ((t & 0x0000FFFF0000FFFF) << 16); + t = (t >> 32) | (t << 32); + return t; + }, + 128 => { + var t: T = a; + t = ((t >> 1) & 0x55555555555555555555555555555555) | ((t & 0x55555555555555555555555555555555) << 1); + t = ((t >> 2) & 0x33333333333333333333333333333333) | ((t & 0x33333333333333333333333333333333) << 2); + t = ((t >> 4) & 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F) | ((t & 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F) << 4); + t = ((t >> 8) & 0x00FF00FF00FF00FF00FF00FF00FF00FF) | ((t & 0x00FF00FF00FF00FF00FF00FF00FF00FF) << 8); + t = ((t >> 16) & 0x0000FFFF0000FFFF0000FFFF0000FFFF) | ((t & 0x0000FFFF0000FFFF0000FFFF0000FFFF) << 16); + t = ((t >> 32) & 0x00000000FFFFFFFF00000000FFFFFFFF) | ((t & 0x00000000FFFFFFFF00000000FFFFFFFF) << 32); + t = (t >> 64) | (t << 64); + return t; + }, + else => unreachable, + } +} + +pub fn __bitreversesi2(a: u32) callconv(.c) u32 { + return bitreverseXi2(u32, a); +} + +pub fn __bitreversedi2(a: u64) callconv(.c) u64 { + return bitreverseXi2(u64, a); +} + +pub fn __bitreverseti2(a: u128) callconv(.c) u128 { + return bitreverseXi2(u128, a); +} + +test { + _ = @import("bitreversesi2_test.zig"); + _ = @import("bitreversedi2_test.zig"); + _ = @import("bitreverseti2_test.zig"); +} diff --git a/build/compiler_rt/bitreversedi2_test.zig b/build/compiler_rt/bitreversedi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/bitreversesi2_test.zig b/build/compiler_rt/bitreversesi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/bitreverseti2_test.zig b/build/compiler_rt/bitreverseti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/bswap.zig b/build/compiler_rt/bswap.zig new file mode 100644 index 00000000..2d6df339 --- /dev/null +++ b/build/compiler_rt/bswap.zig @@ -0,0 +1,85 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__bswapsi2, .{ .name = "__bswapsi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__bswapdi2, .{ .name = "__bswapdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__bswapti2, .{ .name = "__bswapti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +// bswap - byteswap +// - bswapXi2 for unoptimized big and little endian +// ie for u32 +// DE AD BE EF <- little|big endian +// FE BE AD DE <- big|little endian +// ff 00 00 00 >> 3*8 (leftmost byte) +// 00 ff 00 00 >> 1*8 (2nd left byte) +// 00 00 ff 00 << 1*8 (2n right byte) +// 00 00 00 ff << 3*8 (rightmost byte) + +inline fn bswapXi2(comptime T: type, a: T) T { + switch (@bitSizeOf(T)) { + 32 => { + // zig fmt: off + return (((a & 0xff000000) >> 24) + | ((a & 0x00ff0000) >> 8 ) + | ((a & 0x0000ff00) << 8 ) + | ((a & 0x000000ff) << 24)); + // zig fmt: on + }, + 64 => { + // zig fmt: off + return (((a & 0xff00000000000000) >> 56) + | ((a & 0x00ff000000000000) >> 40 ) + | ((a & 0x0000ff0000000000) >> 24 ) + | ((a & 0x000000ff00000000) >> 8 ) + | ((a & 0x00000000ff000000) << 8 ) + | ((a & 0x0000000000ff0000) << 24 ) + | ((a & 0x000000000000ff00) << 40 ) + | ((a & 0x00000000000000ff) << 56)); + // zig fmt: on + }, + 128 => { + // zig fmt: off + return (((a & 0xff000000000000000000000000000000) >> 120) + | ((a & 0x00ff0000000000000000000000000000) >> 104) + | ((a & 0x0000ff00000000000000000000000000) >> 88 ) + | ((a & 0x000000ff000000000000000000000000) >> 72 ) + | ((a & 0x00000000ff0000000000000000000000) >> 56 ) + | ((a & 0x0000000000ff00000000000000000000) >> 40 ) + | ((a & 0x000000000000ff000000000000000000) >> 24 ) + | ((a & 0x00000000000000ff0000000000000000) >> 8 ) + | ((a & 0x0000000000000000ff00000000000000) << 8 ) + | ((a & 0x000000000000000000ff000000000000) << 24 ) + | ((a & 0x00000000000000000000ff0000000000) << 40 ) + | ((a & 0x0000000000000000000000ff00000000) << 56 ) + | ((a & 0x000000000000000000000000ff000000) << 72 ) + | ((a & 0x00000000000000000000000000ff0000) << 88 ) + | ((a & 0x0000000000000000000000000000ff00) << 104) + | ((a & 0x000000000000000000000000000000ff) << 120)); + // zig fmt: on + }, + else => unreachable, + } +} + +pub fn __bswapsi2(a: u32) callconv(.c) u32 { + return bswapXi2(u32, a); +} + +pub fn __bswapdi2(a: u64) callconv(.c) u64 { + return bswapXi2(u64, a); +} + +pub fn __bswapti2(a: u128) callconv(.c) u128 { + return bswapXi2(u128, a); +} + +test { + _ = @import("bswapsi2_test.zig"); + _ = @import("bswapdi2_test.zig"); + _ = @import("bswapti2_test.zig"); +} diff --git a/build/compiler_rt/bswapdi2_test.zig b/build/compiler_rt/bswapdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/bswapsi2_test.zig b/build/compiler_rt/bswapsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/bswapti2_test.zig b/build/compiler_rt/bswapti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/ceil.zig b/build/compiler_rt/ceil.zig new file mode 100644 index 00000000..1900496b --- /dev/null +++ b/build/compiler_rt/ceil.zig @@ -0,0 +1,238 @@ +//! Ported from musl, which is MIT licensed. +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/ceil.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/ceill.c + +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__ceilh, .{ .name = "__ceilh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&ceilf, .{ .name = "ceilf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&ceil, .{ .name = "ceil", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ceilx, .{ .name = "__ceilx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&ceilq, .{ .name = "ceilf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&ceilq, .{ .name = "ceilq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&ceill, .{ .name = "ceill", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __ceilh(x: f16) callconv(.c) f16 { + var u: u16 = @bitCast(x); + const e = @as(i16, @intCast((u >> 10) & 31)) - 15; + var m: u16 = undefined; + + if (e >= 10) return x; + + if (e >= 0) { + m = @as(u16, 0x03FF) >> @intCast(e); + if (u & m == 0) return x; + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120); + if (u >> 15 == 0) u += m; + u &= ~m; + return @bitCast(u); + } else { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120); + return if (u >> 15 != 0) -0.0 else if (u << 1 != 0) 1.0 else x; + } +} + +pub fn ceilf(x: f32) callconv(.c) f32 { + var u: u32 = @bitCast(x); + const e = @as(i32, @intCast((u >> 23) & 0xFF)) - 0x7F; + var m: u32 = undefined; + + if (e >= 23) return x; + + if (e >= 0) { + m = @as(u32, 0x007FFFFF) >> @intCast(e); + if (u & m == 0) return x; + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120); + if (u >> 31 == 0) u += m; + u &= ~m; + return @bitCast(u); + } else { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120); + return if (u >> 31 != 0) -0.0 else if (u << 1 != 0) 1.0 else x; + } +} + +pub fn ceil(x: f64) callconv(.c) f64 { + const f64_toint = 1.0 / math.floatEps(f64); + + const u: u64 = @bitCast(x); + const e = (u >> 52) & 0x7FF; + var y: f64 = undefined; + + if (e >= 0x3FF + 52 or x == 0) { + return x; + } + + if (u >> 63 != 0) { + y = x - f64_toint + f64_toint - x; + } else { + y = x + f64_toint - f64_toint - x; + } + + if (e <= 0x3FF - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(y); + if (u >> 63 != 0) { + return -0.0; + } else { + return 1.0; + } + } else if (y < 0) { + return x + y + 1; + } else { + return x + y; + } +} + +pub fn __ceilx(x: f80) callconv(.c) f80 { + const f80_toint = 1.0 / math.floatEps(f80); + + const u: u80 = @bitCast(x); + const e = (u >> 64) & 0x7FFF; + var y: f80 = undefined; + + if (e >= 0x3FFF + 64 or x == 0) return x; + + if (u >> 79 != 0) { + y = x - f80_toint + f80_toint - x; + } else { + y = x + f80_toint - f80_toint - x; + } + + if (e <= 0x3FFF - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(y); + if (u >> 79 != 0) { + return -0.0; + } else { + return 1.0; + } + } else if (y < 0) { + return x + y + 1; + } else { + return x + y; + } +} + +pub fn ceilq(x: f128) callconv(.c) f128 { + const f128_toint = 1.0 / math.floatEps(f128); + + const u: u128 = @bitCast(x); + const e = (u >> 112) & 0x7FFF; + var y: f128 = undefined; + + if (e >= 0x3FFF + 112 or x == 0) return x; + + if (u >> 127 != 0) { + y = x - f128_toint + f128_toint - x; + } else { + y = x + f128_toint - f128_toint - x; + } + + if (e <= 0x3FFF - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(y); + if (u >> 127 != 0) { + return -0.0; + } else { + return 1.0; + } + } else if (y < 0) { + return x + y + 1; + } else { + return x + y; + } +} + +pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __ceilh(x), + 32 => return ceilf(x), + 64 => return ceil(x), + 80 => return __ceilx(x), + 128 => return ceilq(x), + else => @compileError("unreachable"), + } +} + +test "ceil16" { + try expect(__ceilh(1.3) == 2.0); + try expect(__ceilh(-1.3) == -1.0); + try expect(__ceilh(0.2) == 1.0); +} + +test "ceil32" { + try expect(ceilf(1.3) == 2.0); + try expect(ceilf(-1.3) == -1.0); + try expect(ceilf(0.2) == 1.0); +} + +test "ceil64" { + try expect(ceil(1.3) == 2.0); + try expect(ceil(-1.3) == -1.0); + try expect(ceil(0.2) == 1.0); +} + +test "ceil80" { + try expect(__ceilx(1.3) == 2.0); + try expect(__ceilx(-1.3) == -1.0); + try expect(__ceilx(0.2) == 1.0); +} + +test "ceil128" { + try expect(ceilq(1.3) == 2.0); + try expect(ceilq(-1.3) == -1.0); + try expect(ceilq(0.2) == 1.0); +} + +test "ceil16.special" { + try expect(__ceilh(0.0) == 0.0); + try expect(__ceilh(-0.0) == -0.0); + try expect(math.isPositiveInf(__ceilh(math.inf(f16)))); + try expect(math.isNegativeInf(__ceilh(-math.inf(f16)))); + try expect(math.isNan(__ceilh(math.nan(f16)))); +} + +test "ceil32.special" { + try expect(ceilf(0.0) == 0.0); + try expect(ceilf(-0.0) == -0.0); + try expect(math.isPositiveInf(ceilf(math.inf(f32)))); + try expect(math.isNegativeInf(ceilf(-math.inf(f32)))); + try expect(math.isNan(ceilf(math.nan(f32)))); +} + +test "ceil64.special" { + try expect(ceil(0.0) == 0.0); + try expect(ceil(-0.0) == -0.0); + try expect(math.isPositiveInf(ceil(math.inf(f64)))); + try expect(math.isNegativeInf(ceil(-math.inf(f64)))); + try expect(math.isNan(ceil(math.nan(f64)))); +} + +test "ceil80.special" { + try expect(__ceilx(0.0) == 0.0); + try expect(__ceilx(-0.0) == -0.0); + try expect(math.isPositiveInf(__ceilx(math.inf(f80)))); + try expect(math.isNegativeInf(__ceilx(-math.inf(f80)))); + try expect(math.isNan(__ceilx(math.nan(f80)))); +} + +test "ceil128.special" { + try expect(ceilq(0.0) == 0.0); + try expect(ceilq(-0.0) == -0.0); + try expect(math.isPositiveInf(ceilq(math.inf(f128)))); + try expect(math.isNegativeInf(ceilq(-math.inf(f128)))); + try expect(math.isNan(ceilq(math.nan(f128)))); +} diff --git a/build/compiler_rt/clear_cache.zig b/build/compiler_rt/clear_cache.zig new file mode 100644 index 00000000..0c05e12d --- /dev/null +++ b/build/compiler_rt/clear_cache.zig @@ -0,0 +1,202 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const os = builtin.os.tag; +const common = @import("common.zig"); +pub const panic = common.panic; + +// Ported from llvm-project d32170dbd5b0d54436537b6b75beaf44324e0c28 + +// The compiler generates calls to __clear_cache() when creating +// trampoline functions on the stack for use with nested functions. +// It is expected to invalidate the instruction cache for the +// specified range. + +comptime { + _ = &clear_cache; +} + +fn clear_cache(start: usize, end: usize) callconv(.c) void { + const x86 = switch (arch) { + .x86, .x86_64 => true, + else => false, + }; + const arm32 = switch (arch) { + .arm, .armeb, .thumb, .thumbeb => true, + else => false, + }; + const arm64 = switch (arch) { + .aarch64, .aarch64_be => true, + else => false, + }; + const loongarch = switch (arch) { + .loongarch32, + .loongarch64, + => true, + else => false, + }; + const mips = switch (arch) { + .mips, .mipsel, .mips64, .mips64el => true, + else => false, + }; + const riscv = arch.isRISCV(); + const powerpc64 = switch (arch) { + .powerpc64, .powerpc64le => true, + else => false, + }; + const sparc = switch (arch) { + .sparc, .sparc64 => true, + else => false, + }; + const apple = switch (os) { + .ios, .macos, .watchos, .tvos, .visionos => true, + else => false, + }; + if (x86) { + // Intel processors have a unified instruction and data cache + // so there is nothing to do + exportIt(); + } else if (os == .windows and (arm32 or arm64)) { + // TODO + // FlushInstructionCache(GetCurrentProcess(), start, end - start); + // exportIt(); + } else if (arm32 and !apple) { + switch (os) { + .freebsd, .netbsd => { + var arg = arm_sync_icache_args{ + .addr = start, + .len = end - start, + }; + const result = sysarch(ARM_SYNC_ICACHE, @intFromPtr(&arg)); + std.debug.assert(result == 0); + exportIt(); + }, + .linux => { + const result = std.os.linux.syscall3(.cacheflush, start, end, 0); + std.debug.assert(result == 0); + exportIt(); + }, + else => {}, + } + } else if (os == .linux and mips) { + const flags = 3; // ICACHE | DCACHE + const result = std.os.linux.syscall3(.cacheflush, start, end - start, flags); + std.debug.assert(result == 0); + exportIt(); + } else if (os == .netbsd and mips) { + // Replace with https://github.com/ziglang/zig/issues/23904 in the future. + const cfa: extern struct { + va: usize, + nbytes: usize, + whichcache: u32, + } = .{ + .va = start, + .nbytes = end - start, + .whichcache = 3, // ICACHE | DCACHE + }; + asm volatile ("syscall" + : + : [_] "{$2}" (165), // nr = SYS_sysarch + [_] "{$4}" (0), // op = MIPS_CACHEFLUSH + [_] "{$5}" (&cfa), // args = &cfa + : .{ .r1 = true, .r2 = true, .r3 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true }); + exportIt(); + } else if (mips and os == .openbsd) { + // TODO + //cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE); + // exportIt(); + } else if (os == .linux and riscv) { + const result = std.os.linux.syscall3(.riscv_flush_icache, start, end - start, 0); + std.debug.assert(result == 0); + exportIt(); + } else if (arm64 and !apple) { + // Get Cache Type Info. + // TODO memoize this? + const ctr_el0 = asm volatile ("mrs %[ctr_el0], ctr_el0" + : [ctr_el0] "=r" (-> u64), + ); + // The DC and IC instructions must use 64-bit registers so we don't use + // uintptr_t in case this runs in an IPL32 environment. + var addr: u64 = undefined; + // If CTR_EL0.IDC is set, data cache cleaning to the point of unification + // is not required for instruction to data coherence. + if (((ctr_el0 >> 28) & 0x1) == 0x0) { + const dcache_line_size = @as(usize, 4) << @intCast((ctr_el0 >> 16) & 15); + addr = start & ~(dcache_line_size - 1); + while (addr < end) : (addr += dcache_line_size) { + asm volatile ("dc cvau, %[addr]" + : + : [addr] "r" (addr), + ); + } + } + asm volatile ("dsb ish"); + // If CTR_EL0.DIC is set, instruction cache invalidation to the point of + // unification is not required for instruction to data coherence. + if (((ctr_el0 >> 29) & 0x1) == 0x0) { + const icache_line_size = @as(usize, 4) << @intCast((ctr_el0 >> 0) & 15); + addr = start & ~(icache_line_size - 1); + while (addr < end) : (addr += icache_line_size) { + asm volatile ("ic ivau, %[addr]" + : + : [addr] "r" (addr), + ); + } + } + asm volatile ("isb sy"); + exportIt(); + } else if (powerpc64) { + // TODO + //const size_t line_size = 32; + //const size_t len = (uintptr_t)end - (uintptr_t)start; + // + //const uintptr_t mask = ~(line_size - 1); + //const uintptr_t start_line = ((uintptr_t)start) & mask; + //const uintptr_t end_line = ((uintptr_t)start + len + line_size - 1) & mask; + // + //for (uintptr_t line = start_line; line < end_line; line += line_size) + // __asm__ volatile("dcbf 0, %0" : : "r"(line)); + //__asm__ volatile("sync"); + // + //for (uintptr_t line = start_line; line < end_line; line += line_size) + // __asm__ volatile("icbi 0, %0" : : "r"(line)); + //__asm__ volatile("isync"); + // exportIt(); + } else if (sparc) { + // TODO + //const size_t dword_size = 8; + //const size_t len = (uintptr_t)end - (uintptr_t)start; + // + //const uintptr_t mask = ~(dword_size - 1); + //const uintptr_t start_dword = ((uintptr_t)start) & mask; + //const uintptr_t end_dword = ((uintptr_t)start + len + dword_size - 1) & mask; + // + //for (uintptr_t dword = start_dword; dword < end_dword; dword += dword_size) + // __asm__ volatile("flush %0" : : "r"(dword)); + // exportIt(); + } else if (apple) { + // On Darwin, sys_icache_invalidate() provides this functionality + sys_icache_invalidate(start, end - start); + exportIt(); + } else if (os == .linux and loongarch) { + // See: https://github.com/llvm/llvm-project/blob/cf54cae26b65fc3201eff7200ffb9b0c9e8f9a13/compiler-rt/lib/builtins/clear_cache.c#L94-L95 + asm volatile ("ibar 0"); + exportIt(); + } + + std.valgrind.discardTranslations(@as([*]u8, @ptrFromInt(start))[0 .. end - start]); +} + +fn exportIt() void { + @export(&clear_cache, .{ .name = "__clear_cache", .linkage = common.linkage, .visibility = common.visibility }); +} + +// Darwin-only +extern fn sys_icache_invalidate(start: usize, len: usize) void; +// BSD-only +const arm_sync_icache_args = extern struct { + addr: usize, // Virtual start address + len: usize, // Region size +}; +const ARM_SYNC_ICACHE = 0; +extern "c" fn sysarch(number: i32, args: usize) i32; diff --git a/build/compiler_rt/clzdi2_test.zig b/build/compiler_rt/clzdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/clzsi2_test.zig b/build/compiler_rt/clzsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/clzti2_test.zig b/build/compiler_rt/clzti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/cmp.zig b/build/compiler_rt/cmp.zig new file mode 100644 index 00000000..67cb5b09 --- /dev/null +++ b/build/compiler_rt/cmp.zig @@ -0,0 +1,68 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__cmpsi2, .{ .name = "__cmpsi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__cmpdi2, .{ .name = "__cmpdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__cmpti2, .{ .name = "__cmpti2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ucmpsi2, .{ .name = "__ucmpsi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ucmpdi2, .{ .name = "__ucmpdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ucmpti2, .{ .name = "__ucmpti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +// cmp - signed compare +// - cmpXi2_generic for unoptimized little and big endian + +// ucmp - unsigned compare +// - ucmpXi2_generic for unoptimized little and big endian + +// a < b => 0 +// a == b => 1 +// a > b => 2 + +inline fn XcmpXi2(comptime T: type, a: T, b: T) i32 { + var cmp1: i32 = 0; + var cmp2: i32 = 0; + if (a > b) + cmp1 = 1; + if (a < b) + cmp2 = 1; + return cmp1 - cmp2 + 1; +} + +pub fn __cmpsi2(a: i32, b: i32) callconv(.c) i32 { + return XcmpXi2(i32, a, b); +} + +pub fn __cmpdi2(a: i64, b: i64) callconv(.c) i32 { + return XcmpXi2(i64, a, b); +} + +pub fn __cmpti2(a: i128, b: i128) callconv(.c) i32 { + return XcmpXi2(i128, a, b); +} + +pub fn __ucmpsi2(a: u32, b: u32) callconv(.c) i32 { + return XcmpXi2(u32, a, b); +} + +pub fn __ucmpdi2(a: u64, b: u64) callconv(.c) i32 { + return XcmpXi2(u64, a, b); +} + +pub fn __ucmpti2(a: u128, b: u128) callconv(.c) i32 { + return XcmpXi2(u128, a, b); +} + +test { + _ = @import("cmpsi2_test.zig"); + _ = @import("cmpdi2_test.zig"); + _ = @import("cmpti2_test.zig"); + + _ = @import("ucmpsi2_test.zig"); + _ = @import("ucmpdi2_test.zig"); + _ = @import("ucmpti2_test.zig"); +} diff --git a/build/compiler_rt/cmpdf2.zig b/build/compiler_rt/cmpdf2.zig new file mode 100644 index 00000000..a0338c7a --- /dev/null +++ b/build/compiler_rt/cmpdf2.zig @@ -0,0 +1,68 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_dcmpeq, .{ .name = "__aeabi_dcmpeq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_dcmplt, .{ .name = "__aeabi_dcmplt", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_dcmple, .{ .name = "__aeabi_dcmple", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__eqdf2, .{ .name = "__eqdf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__nedf2, .{ .name = "__nedf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ledf2, .{ .name = "__ledf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__cmpdf2, .{ .name = "__cmpdf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ltdf2, .{ .name = "__ltdf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; +/// if a is greater than b, they return 1; and if a and b are equal they return 0. +/// If either argument is NaN they return 1..." +/// +/// Note that this matches the definition of `__ledf2`, `__eqdf2`, `__nedf2`, `__cmpdf2`, +/// and `__ltdf2`. +fn __cmpdf2(a: f64, b: f64) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f64, comparef.LE, a, b)); +} + +/// "These functions return a value less than or equal to zero if neither argument is NaN, +/// and a is less than or equal to b." +pub fn __ledf2(a: f64, b: f64) callconv(.c) i32 { + return __cmpdf2(a, b); +} + +/// "These functions return zero if neither argument is NaN, and a and b are equal." +/// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined +/// to have the same return value. +pub fn __eqdf2(a: f64, b: f64) callconv(.c) i32 { + return __cmpdf2(a, b); +} + +/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." +/// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined +/// to have the same return value. +pub fn __nedf2(a: f64, b: f64) callconv(.c) i32 { + return __cmpdf2(a, b); +} + +/// "These functions return a value less than zero if neither argument is NaN, and a +/// is strictly less than b." +pub fn __ltdf2(a: f64, b: f64) callconv(.c) i32 { + return __cmpdf2(a, b); +} + +fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Equal); +} + +fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Less); +} + +fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) != .Greater); +} diff --git a/build/compiler_rt/cmpdi2_test.zig b/build/compiler_rt/cmpdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/cmphf2.zig b/build/compiler_rt/cmphf2.zig new file mode 100644 index 00000000..9fcc1e24 --- /dev/null +++ b/build/compiler_rt/cmphf2.zig @@ -0,0 +1,50 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__eqhf2, .{ .name = "__eqhf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__nehf2, .{ .name = "__nehf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lehf2, .{ .name = "__lehf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__cmphf2, .{ .name = "__cmphf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lthf2, .{ .name = "__lthf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; +/// if a is greater than b, they return 1; and if a and b are equal they return 0. +/// If either argument is NaN they return 1..." +/// +/// Note that this matches the definition of `__lehf2`, `__eqhf2`, `__nehf2`, `__cmphf2`, +/// and `__lthf2`. +fn __cmphf2(a: f16, b: f16) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f16, comparef.LE, a, b)); +} + +/// "These functions return a value less than or equal to zero if neither argument is NaN, +/// and a is less than or equal to b." +pub fn __lehf2(a: f16, b: f16) callconv(.c) i32 { + return __cmphf2(a, b); +} + +/// "These functions return zero if neither argument is NaN, and a and b are equal." +/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined +/// to have the same return value. +pub fn __eqhf2(a: f16, b: f16) callconv(.c) i32 { + return __cmphf2(a, b); +} + +/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." +/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined +/// to have the same return value. +pub fn __nehf2(a: f16, b: f16) callconv(.c) i32 { + return __cmphf2(a, b); +} + +/// "These functions return a value less than zero if neither argument is NaN, and a +/// is strictly less than b." +pub fn __lthf2(a: f16, b: f16) callconv(.c) i32 { + return __cmphf2(a, b); +} diff --git a/build/compiler_rt/cmpsf2.zig b/build/compiler_rt/cmpsf2.zig new file mode 100644 index 00000000..371319b0 --- /dev/null +++ b/build/compiler_rt/cmpsf2.zig @@ -0,0 +1,68 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__eqsf2, .{ .name = "__eqsf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__nesf2, .{ .name = "__nesf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lesf2, .{ .name = "__lesf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__cmpsf2, .{ .name = "__cmpsf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ltsf2, .{ .name = "__ltsf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; +/// if a is greater than b, they return 1; and if a and b are equal they return 0. +/// If either argument is NaN they return 1..." +/// +/// Note that this matches the definition of `__lesf2`, `__eqsf2`, `__nesf2`, `__cmpsf2`, +/// and `__ltsf2`. +fn __cmpsf2(a: f32, b: f32) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f32, comparef.LE, a, b)); +} + +/// "These functions return a value less than or equal to zero if neither argument is NaN, +/// and a is less than or equal to b." +pub fn __lesf2(a: f32, b: f32) callconv(.c) i32 { + return __cmpsf2(a, b); +} + +/// "These functions return zero if neither argument is NaN, and a and b are equal." +/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined +/// to have the same return value. +pub fn __eqsf2(a: f32, b: f32) callconv(.c) i32 { + return __cmpsf2(a, b); +} + +/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." +/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined +/// to have the same return value. +pub fn __nesf2(a: f32, b: f32) callconv(.c) i32 { + return __cmpsf2(a, b); +} + +/// "These functions return a value less than zero if neither argument is NaN, and a +/// is strictly less than b." +pub fn __ltsf2(a: f32, b: f32) callconv(.c) i32 { + return __cmpsf2(a, b); +} + +fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f32, comparef.LE, a, b) == .Equal); +} + +fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f32, comparef.LE, a, b) == .Less); +} + +fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f32, comparef.LE, a, b) != .Greater); +} diff --git a/build/compiler_rt/cmpsi2_test.zig b/build/compiler_rt/cmpsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/cmptf2.zig b/build/compiler_rt/cmptf2.zig new file mode 100644 index 00000000..d5ee7970 --- /dev/null +++ b/build/compiler_rt/cmptf2.zig @@ -0,0 +1,105 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__eqtf2, .{ .name = "__eqkf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__netf2, .{ .name = "__nekf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lttf2, .{ .name = "__ltkf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__letf2, .{ .name = "__lekf2", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_cmp, .{ .name = "_Qp_cmp", .linkage = common.linkage, .visibility = common.visibility }); + @export(&_Qp_feq, .{ .name = "_Qp_feq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&_Qp_fne, .{ .name = "_Qp_fne", .linkage = common.linkage, .visibility = common.visibility }); + @export(&_Qp_flt, .{ .name = "_Qp_flt", .linkage = common.linkage, .visibility = common.visibility }); + @export(&_Qp_fle, .{ .name = "_Qp_fle", .linkage = common.linkage, .visibility = common.visibility }); + @export(&_Qp_fgt, .{ .name = "_Qp_fgt", .linkage = common.linkage, .visibility = common.visibility }); + @export(&_Qp_fge, .{ .name = "_Qp_fge", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__eqtf2, .{ .name = "__eqtf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__netf2, .{ .name = "__netf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__letf2, .{ .name = "__letf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__cmptf2, .{ .name = "__cmptf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lttf2, .{ .name = "__lttf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; +/// if a is greater than b, they return 1; and if a and b are equal they return 0. +/// If either argument is NaN they return 1..." +/// +/// Note that this matches the definition of `__letf2`, `__eqtf2`, `__netf2`, `__cmptf2`, +/// and `__lttf2`. +fn __cmptf2(a: f128, b: f128) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f128, comparef.LE, a, b)); +} + +/// "These functions return a value less than or equal to zero if neither argument is NaN, +/// and a is less than or equal to b." +fn __letf2(a: f128, b: f128) callconv(.c) i32 { + return __cmptf2(a, b); +} + +/// "These functions return zero if neither argument is NaN, and a and b are equal." +/// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined +/// to have the same return value. +fn __eqtf2(a: f128, b: f128) callconv(.c) i32 { + return __cmptf2(a, b); +} + +/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." +/// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined +/// to have the same return value. +fn __netf2(a: f128, b: f128) callconv(.c) i32 { + return __cmptf2(a, b); +} + +/// "These functions return a value less than zero if neither argument is NaN, and a +/// is strictly less than b." +fn __lttf2(a: f128, b: f128) callconv(.c) i32 { + return __cmptf2(a, b); +} + +const SparcFCMP = enum(i32) { + Equal = 0, + Less = 1, + Greater = 2, + Unordered = 3, +}; + +fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f128, SparcFCMP, a.*, b.*)); +} + +fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) bool { + return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Equal; +} + +fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) bool { + return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) != .Equal; +} + +fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) bool { + return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Less; +} + +fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) bool { + return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Greater; +} + +fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) bool { + return switch (@as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b)))) { + .Equal, .Greater => true, + .Less, .Unordered => false, + }; +} + +fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) bool { + return switch (@as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b)))) { + .Equal, .Less => true, + .Greater, .Unordered => false, + }; +} diff --git a/build/compiler_rt/cmpti2_test.zig b/build/compiler_rt/cmpti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/cmpxf2.zig b/build/compiler_rt/cmpxf2.zig new file mode 100644 index 00000000..dc90f87c --- /dev/null +++ b/build/compiler_rt/cmpxf2.zig @@ -0,0 +1,50 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__eqxf2, .{ .name = "__eqxf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__nexf2, .{ .name = "__nexf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lexf2, .{ .name = "__lexf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__cmpxf2, .{ .name = "__cmpxf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ltxf2, .{ .name = "__ltxf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; +/// if a is greater than b, they return 1; and if a and b are equal they return 0. +/// If either argument is NaN they return 1..." +/// +/// Note that this matches the definition of `__lexf2`, `__eqxf2`, `__nexf2`, `__cmpxf2`, +/// and `__ltxf2`. +fn __cmpxf2(a: f80, b: f80) callconv(.c) i32 { + return @intFromEnum(comparef.cmp_f80(comparef.LE, a, b)); +} + +/// "These functions return a value less than or equal to zero if neither argument is NaN, +/// and a is less than or equal to b." +fn __lexf2(a: f80, b: f80) callconv(.c) i32 { + return __cmpxf2(a, b); +} + +/// "These functions return zero if neither argument is NaN, and a and b are equal." +/// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined +/// to have the same return value. +fn __eqxf2(a: f80, b: f80) callconv(.c) i32 { + return __cmpxf2(a, b); +} + +/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." +/// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined +/// to have the same return value. +fn __nexf2(a: f80, b: f80) callconv(.c) i32 { + return __cmpxf2(a, b); +} + +/// "These functions return a value less than zero if neither argument is NaN, and a +/// is strictly less than b." +fn __ltxf2(a: f80, b: f80) callconv(.c) i32 { + return __cmpxf2(a, b); +} diff --git a/build/compiler_rt/common.zig b/build/compiler_rt/common.zig new file mode 100644 index 00000000..87747db2 --- /dev/null +++ b/build/compiler_rt/common.zig @@ -0,0 +1,300 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const native_endian = builtin.cpu.arch.endian(); +const ofmt_c = builtin.object_format == .c; + +/// For now, we prefer weak linkage because some of the routines we implement here may also be +/// provided by system/dynamic libc. Eventually we should be more disciplined about this on a +/// per-symbol, per-target basis: https://github.com/ziglang/zig/issues/11883 +pub const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) + .internal +else if (ofmt_c) + .strong +else + .weak; + +/// Determines the symbol's visibility to other objects. +/// For WebAssembly this allows the symbol to be resolved to other modules, but will not +/// export it to the host runtime. +pub const visibility: std.builtin.SymbolVisibility = if (linkage == .internal or builtin.link_mode == .dynamic) + .default +else + .hidden; + +pub const PreferredLoadStoreElement = element: { + if (std.simd.suggestVectorLength(u8)) |vec_size| { + const Vec = @Vector(vec_size, u8); + + if (@sizeOf(Vec) == vec_size and std.math.isPowerOfTwo(vec_size)) { + break :element Vec; + } + } + break :element usize; +}; + +pub const want_aeabi = switch (builtin.abi) { + .eabi, + .eabihf, + .musleabi, + .musleabihf, + .gnueabi, + .gnueabihf, + .android, + .androideabi, + => switch (builtin.cpu.arch) { + .arm, .armeb, .thumb, .thumbeb => true, + else => false, + }, + else => false, +}; + +/// These functions are provided by libc when targeting MSVC, but not MinGW. +// Temporarily used for thumb-uefi until https://github.com/ziglang/zig/issues/21630 is addressed. +pub const want_windows_arm_abi = builtin.cpu.arch.isArm() and (builtin.os.tag == .windows or builtin.os.tag == .uefi) and (builtin.abi.isGnu() or !builtin.link_libc); + +pub const want_windows_msvc_or_itanium_abi = switch (builtin.abi) { + .none, .msvc, .itanium => builtin.os.tag == .windows, + else => false, +}; + +pub const want_ppc_abi = builtin.cpu.arch.isPowerPC(); + +pub const want_float_exceptions = !builtin.cpu.arch.isWasm(); + +// Libcalls that involve u128 on Windows x86-64 are expected by LLVM to use the +// calling convention of @Vector(2, u64), rather than what's standard. +pub const want_windows_v2u64_abi = builtin.os.tag == .windows and builtin.cpu.arch == .x86_64 and !ofmt_c; + +/// This governs whether to use these symbol names for f16/f32 conversions +/// rather than the standard names: +/// * __gnu_f2h_ieee +/// * __gnu_h2f_ieee +/// Known correct configurations: +/// x86_64-freestanding-none => true +/// x86_64-linux-none => true +/// x86_64-linux-gnu => true +/// x86_64-linux-musl => true +/// x86_64-linux-eabi => true +/// arm-linux-musleabihf => true +/// arm-linux-gnueabihf => true +/// arm-linux-eabihf => false +/// wasm32-wasi-musl => false +/// wasm32-freestanding-none => false +/// x86_64-windows-gnu => true +/// x86_64-windows-msvc => true +/// any-macos-any => false +pub const gnu_f16_abi = switch (builtin.cpu.arch) { + .wasm32, + .wasm64, + .riscv64, + .riscv64be, + .riscv32, + .riscv32be, + => false, + + .x86, .x86_64 => true, + + .arm, .armeb, .thumb, .thumbeb => switch (builtin.abi) { + .eabi, .eabihf => false, + else => true, + }, + + else => !builtin.os.tag.isDarwin(), +}; + +pub const want_sparc_abi = builtin.cpu.arch.isSPARC(); + +pub const test_safety = switch (builtin.zig_backend) { + .stage2_aarch64 => false, + else => builtin.is_test, +}; + +// Avoid dragging in the runtime safety mechanisms into this .o file, unless +// we're trying to test compiler-rt. +pub const panic = if (test_safety) std.debug.FullPanic(std.debug.defaultPanic) else std.debug.no_panic; + +/// This seems to mostly correspond to `clang::TargetInfo::HasFloat16`. +pub fn F16T(comptime OtherType: type) type { + return switch (builtin.cpu.arch) { + .amdgcn, + .arm, + .armeb, + .thumb, + .thumbeb, + .aarch64, + .aarch64_be, + .hexagon, + .loongarch32, + .loongarch64, + .nvptx, + .nvptx64, + .riscv32, + .riscv32be, + .riscv64, + .riscv64be, + .s390x, + .spirv32, + .spirv64, + => f16, + .x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) { + // Starting with LLVM 16, Darwin uses different abi for f16 + // depending on the type of the other return/argument..??? + f32, f64 => u16, + f80, f128 => f16, + else => unreachable, + } else f16, + else => u16, + }; +} + +pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void { + switch (Z) { + u16 => { + // 16x16 --> 32 bit multiply + const product = @as(u32, a) * @as(u32, b); + hi.* = @intCast(product >> 16); + lo.* = @truncate(product); + }, + u32 => { + // 32x32 --> 64 bit multiply + const product = @as(u64, a) * @as(u64, b); + hi.* = @truncate(product >> 32); + lo.* = @truncate(product); + }, + u64 => { + const S = struct { + fn loWord(x: u64) u64 { + return @as(u32, @truncate(x)); + } + fn hiWord(x: u64) u64 { + return @as(u32, @truncate(x >> 32)); + } + }; + // 64x64 -> 128 wide multiply for platforms that don't have such an operation; + // many 64-bit platforms have this operation, but they tend to have hardware + // floating-point, so we don't bother with a special case for them here. + // Each of the component 32x32 -> 64 products + const plolo: u64 = S.loWord(a) * S.loWord(b); + const plohi: u64 = S.loWord(a) * S.hiWord(b); + const philo: u64 = S.hiWord(a) * S.loWord(b); + const phihi: u64 = S.hiWord(a) * S.hiWord(b); + // Sum terms that contribute to lo in a way that allows us to get the carry + const r0: u64 = S.loWord(plolo); + const r1: u64 = S.hiWord(plolo) +% S.loWord(plohi) +% S.loWord(philo); + lo.* = r0 +% (r1 << 32); + // Sum terms contributing to hi with the carry from lo + hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi; + }, + u128 => { + const Word_LoMask: u64 = 0x00000000ffffffff; + const Word_HiMask: u64 = 0xffffffff00000000; + const Word_FullMask: u64 = 0xffffffffffffffff; + const S = struct { + fn Word_1(x: u128) u64 { + return @as(u32, @truncate(x >> 96)); + } + fn Word_2(x: u128) u64 { + return @as(u32, @truncate(x >> 64)); + } + fn Word_3(x: u128) u64 { + return @as(u32, @truncate(x >> 32)); + } + fn Word_4(x: u128) u64 { + return @as(u32, @truncate(x)); + } + }; + // 128x128 -> 256 wide multiply for platforms that don't have such an operation; + // many 64-bit platforms have this operation, but they tend to have hardware + // floating-point, so we don't bother with a special case for them here. + + const product11: u64 = S.Word_1(a) * S.Word_1(b); + const product12: u64 = S.Word_1(a) * S.Word_2(b); + const product13: u64 = S.Word_1(a) * S.Word_3(b); + const product14: u64 = S.Word_1(a) * S.Word_4(b); + const product21: u64 = S.Word_2(a) * S.Word_1(b); + const product22: u64 = S.Word_2(a) * S.Word_2(b); + const product23: u64 = S.Word_2(a) * S.Word_3(b); + const product24: u64 = S.Word_2(a) * S.Word_4(b); + const product31: u64 = S.Word_3(a) * S.Word_1(b); + const product32: u64 = S.Word_3(a) * S.Word_2(b); + const product33: u64 = S.Word_3(a) * S.Word_3(b); + const product34: u64 = S.Word_3(a) * S.Word_4(b); + const product41: u64 = S.Word_4(a) * S.Word_1(b); + const product42: u64 = S.Word_4(a) * S.Word_2(b); + const product43: u64 = S.Word_4(a) * S.Word_3(b); + const product44: u64 = S.Word_4(a) * S.Word_4(b); + + const sum0: u128 = @as(u128, product44); + const sum1: u128 = @as(u128, product34) +% + @as(u128, product43); + const sum2: u128 = @as(u128, product24) +% + @as(u128, product33) +% + @as(u128, product42); + const sum3: u128 = @as(u128, product14) +% + @as(u128, product23) +% + @as(u128, product32) +% + @as(u128, product41); + const sum4: u128 = @as(u128, product13) +% + @as(u128, product22) +% + @as(u128, product31); + const sum5: u128 = @as(u128, product12) +% + @as(u128, product21); + const sum6: u128 = @as(u128, product11); + + const r0: u128 = (sum0 & Word_FullMask) +% + ((sum1 & Word_LoMask) << 32); + const r1: u128 = (sum0 >> 64) +% + ((sum1 >> 32) & Word_FullMask) +% + (sum2 & Word_FullMask) +% + ((sum3 << 32) & Word_HiMask); + + lo.* = r0 +% (r1 << 64); + hi.* = (r1 >> 64) +% + (sum1 >> 96) +% + (sum2 >> 64) +% + (sum3 >> 32) +% + sum4 +% + (sum5 << 32) +% + (sum6 << 64); + }, + else => @compileError("unsupported"), + } +} + +pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).float.bits)) i32 { + const Z = std.meta.Int(.unsigned, @typeInfo(T).float.bits); + const integerBit = @as(Z, 1) << std.math.floatFractionalBits(T); + + const shift = @clz(significand.*) - @clz(integerBit); + significand.* <<= @as(std.math.Log2Int(Z), @intCast(shift)); + return @as(i32, 1) - shift; +} + +pub inline fn fneg(a: anytype) @TypeOf(a) { + const F = @TypeOf(a); + const bits = @typeInfo(F).float.bits; + const U = @Type(.{ .int = .{ + .signedness = .unsigned, + .bits = bits, + } }); + const sign_bit_mask = @as(U, 1) << (bits - 1); + const negated = @as(U, @bitCast(a)) ^ sign_bit_mask; + return @bitCast(negated); +} + +/// Allows to access underlying bits as two equally sized lower and higher +/// signed or unsigned integers. +pub fn HalveInt(comptime T: type, comptime signed_half: bool) type { + return extern union { + pub const bits = @divExact(@typeInfo(T).int.bits, 2); + pub const HalfTU = std.meta.Int(.unsigned, bits); + pub const HalfTS = std.meta.Int(.signed, bits); + pub const HalfT = if (signed_half) HalfTS else HalfTU; + + all: T, + s: if (native_endian == .little) + extern struct { low: HalfT, high: HalfT } + else + extern struct { high: HalfT, low: HalfT }, + }; +} diff --git a/build/compiler_rt/comparedf2_test.zig b/build/compiler_rt/comparedf2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/comparef.zig b/build/compiler_rt/comparef.zig new file mode 100644 index 00000000..76f04f43 --- /dev/null +++ b/build/compiler_rt/comparef.zig @@ -0,0 +1,129 @@ +const std = @import("std"); + +pub const LE = enum(i32) { + Less = -1, + Equal = 0, + Greater = 1, + + const Unordered: LE = .Greater; +}; + +pub const GE = enum(i32) { + Less = -1, + Equal = 0, + Greater = 1, + + const Unordered: GE = .Less; +}; + +pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { + const bits = @typeInfo(T).float.bits; + const srep_t = std.meta.Int(.signed, bits); + const rep_t = std.meta.Int(.unsigned, bits); + + const significandBits = std.math.floatMantissaBits(T); + const exponentBits = std.math.floatExponentBits(T); + const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); + const absMask = signBit - 1; + const infT = comptime std.math.inf(T); + const infRep = @as(rep_t, @bitCast(infT)); + + const aInt = @as(srep_t, @bitCast(a)); + const bInt = @as(srep_t, @bitCast(b)); + const aAbs = @as(rep_t, @bitCast(aInt)) & absMask; + const bAbs = @as(rep_t, @bitCast(bInt)) & absMask; + + // If either a or b is NaN, they are unordered. + if (aAbs > infRep or bAbs > infRep) return RT.Unordered; + + // If a and b are both zeros, they are equal. + if ((aAbs | bAbs) == 0) return .Equal; + + // If at least one of a and b is positive, we get the same result comparing + // a and b as signed integers as we would with a floating-point compare. + if ((aInt & bInt) >= 0) { + if (aInt < bInt) { + return .Less; + } else if (aInt == bInt) { + return .Equal; + } else return .Greater; + } else { + // Otherwise, both are negative, so we need to flip the sense of the + // comparison to get the correct result. (This assumes a twos- or ones- + // complement integer representation; if integers are represented in a + // sign-magnitude representation, then this flip is incorrect). + if (aInt > bInt) { + return .Less; + } else if (aInt == bInt) { + return .Equal; + } else return .Greater; + } +} + +pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { + const a_rep = std.math.F80.fromFloat(a); + const b_rep = std.math.F80.fromFloat(b); + const sig_bits = std.math.floatMantissaBits(f80); + const int_bit = 0x8000000000000000; + const sign_bit = 0x8000; + const special_exp = 0x7FFF; + + // If either a or b is NaN, they are unordered. + if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or + (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0)) + return RT.Unordered; + + // If a and b are both zeros, they are equal. + if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0) + return .Equal; + + if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) { + return .Equal; + } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) { + // signs are different + if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) { + return .Less; + } else { + return .Greater; + } + } else { + const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); + const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); + if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) { + return .Less; + } else { + return .Greater; + } + } +} + +test "cmp_f80" { + inline for (.{ LE, GE }) |RT| { + try std.testing.expect(cmp_f80(RT, 1.0, 1.0) == RT.Equal); + try std.testing.expect(cmp_f80(RT, 0.0, -0.0) == RT.Equal); + try std.testing.expect(cmp_f80(RT, 2.0, 4.0) == RT.Less); + try std.testing.expect(cmp_f80(RT, 2.0, -4.0) == RT.Greater); + try std.testing.expect(cmp_f80(RT, -2.0, -4.0) == RT.Greater); + try std.testing.expect(cmp_f80(RT, -2.0, 4.0) == RT.Less); + } +} + +pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { + const rep_t = std.meta.Int(.unsigned, @typeInfo(T).float.bits); + + const significandBits = std.math.floatMantissaBits(T); + const exponentBits = std.math.floatExponentBits(T); + const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); + const absMask = signBit - 1; + const infRep = @as(rep_t, @bitCast(std.math.inf(T))); + + const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask; + const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask; + + return @intFromBool(aAbs > infRep or bAbs > infRep); +} + +test { + _ = @import("comparesf2_test.zig"); + _ = @import("comparedf2_test.zig"); +} diff --git a/build/compiler_rt/comparesf2_test.zig b/build/compiler_rt/comparesf2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/cos.zig b/build/compiler_rt/cos.zig new file mode 100644 index 00000000..01a51962 --- /dev/null +++ b/build/compiler_rt/cos.zig @@ -0,0 +1,171 @@ +const std = @import("std"); +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; +const common = @import("common.zig"); + +pub const panic = common.panic; + +const trig = @import("trig.zig"); +const rem_pio2 = @import("rem_pio2.zig").rem_pio2; +const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; + +comptime { + @export(&__cosh, .{ .name = "__cosh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&cosf, .{ .name = "cosf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&cos, .{ .name = "cos", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__cosx, .{ .name = "__cosx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&cosq, .{ .name = "cosf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&cosq, .{ .name = "cosq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&cosl, .{ .name = "cosl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __cosh(a: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(cosf(a)); +} + +pub fn cosf(x: f32) callconv(.c) f32 { + // Small multiples of pi/2 rounded to double precision. + const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 + const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 + const c3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 + const c4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18 + + var ix: u32 = @bitCast(x); + const sign = ix >> 31 != 0; + ix &= 0x7fffffff; + + if (ix <= 0x3f490fda) { // |x| ~<= pi/4 + if (ix < 0x39800000) { // |x| < 2**-12 + // raise inexact if x != 0 + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); + return 1.0; + } + return trig.__cosdf(x); + } + if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 + if (ix > 0x4016cbe3) { // |x| ~> 3*pi/4 + return -trig.__cosdf(if (sign) x + c2pio2 else x - c2pio2); + } else { + if (sign) { + return trig.__sindf(x + c1pio2); + } else { + return trig.__sindf(c1pio2 - x); + } + } + } + if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 + if (ix > 0x40afeddf) { // |x| ~> 7*pi/4 + return trig.__cosdf(if (sign) x + c4pio2 else x - c4pio2); + } else { + if (sign) { + return trig.__sindf(-x - c3pio2); + } else { + return trig.__sindf(x - c3pio2); + } + } + } + + // cos(Inf or NaN) is NaN + if (ix >= 0x7f800000) { + return x - x; + } + + var y: f64 = undefined; + const n = rem_pio2f(x, &y); + return switch (n & 3) { + 0 => trig.__cosdf(y), + 1 => trig.__sindf(-y), + 2 => -trig.__cosdf(y), + else => trig.__sindf(y), + }; +} + +pub fn cos(x: f64) callconv(.c) f64 { + var ix = @as(u64, @bitCast(x)) >> 32; + ix &= 0x7fffffff; + + // |x| ~< pi/4 + if (ix <= 0x3fe921fb) { + if (ix < 0x3e46a09e) { // |x| < 2**-27 * sqrt(2) + // raise inexact if x!=0 + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); + return 1.0; + } + return trig.__cos(x, 0); + } + + // cos(Inf or NaN) is NaN + if (ix >= 0x7ff00000) { + return x - x; + } + + var y: [2]f64 = undefined; + const n = rem_pio2(x, &y); + return switch (n & 3) { + 0 => trig.__cos(y[0], y[1]), + 1 => -trig.__sin(y[0], y[1], 1), + 2 => -trig.__cos(y[0], y[1]), + else => trig.__sin(y[0], y[1], 1), + }; +} + +pub fn __cosx(a: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(cosq(a)); +} + +pub fn cosq(a: f128) callconv(.c) f128 { + // TODO: more correct implementation + return cos(@floatCast(a)); +} + +pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __cosh(x), + 32 => return cosf(x), + 64 => return cos(x), + 80 => return __cosx(x), + 128 => return cosq(x), + else => @compileError("unreachable"), + } +} + +test "cos32" { + const epsilon = 0.00001; + + try expect(math.approxEqAbs(f32, cosf(0.0), 1.0, epsilon)); + try expect(math.approxEqAbs(f32, cosf(0.2), 0.980067, epsilon)); + try expect(math.approxEqAbs(f32, cosf(0.8923), 0.627623, epsilon)); + try expect(math.approxEqAbs(f32, cosf(1.5), 0.070737, epsilon)); + try expect(math.approxEqAbs(f32, cosf(-1.5), 0.070737, epsilon)); + try expect(math.approxEqAbs(f32, cosf(37.45), 0.969132, epsilon)); + try expect(math.approxEqAbs(f32, cosf(89.123), 0.400798, epsilon)); +} + +test "cos64" { + const epsilon = 0.000001; + + try expect(math.approxEqAbs(f64, cos(0.0), 1.0, epsilon)); + try expect(math.approxEqAbs(f64, cos(0.2), 0.980067, epsilon)); + try expect(math.approxEqAbs(f64, cos(0.8923), 0.627623, epsilon)); + try expect(math.approxEqAbs(f64, cos(1.5), 0.070737, epsilon)); + try expect(math.approxEqAbs(f64, cos(-1.5), 0.070737, epsilon)); + try expect(math.approxEqAbs(f64, cos(37.45), 0.969132, epsilon)); + try expect(math.approxEqAbs(f64, cos(89.123), 0.40080, epsilon)); +} + +test "cos32.special" { + try expect(math.isNan(cosf(math.inf(f32)))); + try expect(math.isNan(cosf(-math.inf(f32)))); + try expect(math.isNan(cosf(math.nan(f32)))); +} + +test "cos64.special" { + try expect(math.isNan(cos(math.inf(f64)))); + try expect(math.isNan(cos(-math.inf(f64)))); + try expect(math.isNan(cos(math.nan(f64)))); +} diff --git a/build/compiler_rt/count0bits.zig b/build/compiler_rt/count0bits.zig new file mode 100644 index 00000000..874604eb --- /dev/null +++ b/build/compiler_rt/count0bits.zig @@ -0,0 +1,246 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__clzsi2, .{ .name = "__clzsi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__clzdi2, .{ .name = "__clzdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__clzti2, .{ .name = "__clzti2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ctzsi2, .{ .name = "__ctzsi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ctzdi2, .{ .name = "__ctzdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ctzti2, .{ .name = "__ctzti2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ffssi2, .{ .name = "__ffssi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ffsdi2, .{ .name = "__ffsdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ffsti2, .{ .name = "__ffsti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +// clz - count leading zeroes +// - clzXi2 for unoptimized little and big endian +// - __clzsi2_thumb1: assume a != 0 +// - __clzsi2_arm32: assume a != 0 + +// ctz - count trailing zeroes +// - ctzXi2 for unoptimized little and big endian + +// ffs - find first set +// * ffs = (a == 0) => 0, (a != 0) => ctz + 1 +// * dont pay for `if (x == 0) return shift;` inside ctz +// - ffsXi2 for unoptimized little and big endian + +inline fn clzXi2(comptime T: type, a: T) i32 { + var x = switch (@bitSizeOf(T)) { + 32 => @as(u32, @bitCast(a)), + 64 => @as(u64, @bitCast(a)), + 128 => @as(u128, @bitCast(a)), + else => unreachable, + }; + var n: T = @bitSizeOf(T); + // Count first bit set using binary search, from Hacker's Delight + var y: @TypeOf(x) = 0; + comptime var shift: u8 = @bitSizeOf(T); + inline while (shift > 0) { + shift = shift >> 1; + y = x >> shift; + if (y != 0) { + n = n - shift; + x = y; + } + } + return @intCast(n - @as(T, @bitCast(x))); +} + +fn __clzsi2_thumb1() callconv(.naked) void { + @setRuntimeSafety(false); + + // Similar to the generic version with the last two rounds replaced by a LUT + asm volatile ( + \\ movs r1, #32 + \\ lsrs r2, r0, #16 + \\ beq 1f + \\ subs r1, #16 + \\ movs r0, r2 + \\ 1: + \\ lsrs r2, r0, #8 + \\ beq 1f + \\ subs r1, #8 + \\ movs r0, r2 + \\ 1: + \\ lsrs r2, r0, #4 + \\ beq 1f + \\ subs r1, #4 + \\ movs r0, r2 + \\ 1: + \\ adr r3, .lut + \\ ldrb r0, [r3, r0] + \\ subs r0, r1, r0 + \\ bx lr + \\ .p2align 2 + \\ // Number of bits set in the 0-15 range + \\ .lut: + \\ .byte 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 + ); + + unreachable; +} + +fn __clzsi2_arm32() callconv(.naked) void { + @setRuntimeSafety(false); + + asm volatile ( + \\ // Assumption: n != 0 + \\ // r0: n + \\ // r1: count of leading zeros in n + 1 + \\ // r2: scratch register for shifted r0 + \\ mov r1, #1 + \\ + \\ // Basic block: + \\ // if ((r0 >> SHIFT) == 0) + \\ // r1 += SHIFT; + \\ // else + \\ // r0 >>= SHIFT; + \\ // for descending powers of two as SHIFT. + \\ lsrs r2, r0, #16 + \\ movne r0, r2 + \\ addeq r1, #16 + \\ + \\ lsrs r2, r0, #8 + \\ movne r0, r2 + \\ addeq r1, #8 + \\ + \\ lsrs r2, r0, #4 + \\ movne r0, r2 + \\ addeq r1, #4 + \\ + \\ lsrs r2, r0, #2 + \\ movne r0, r2 + \\ addeq r1, #2 + \\ + \\ // The basic block invariants at this point are (r0 >> 2) == 0 and + \\ // r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1. + \\ // + \\ // r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)f + \\ // ---+----------------+----------------+------------+-------------- + \\ // 1 | 1 | 0 | 0 | 1 + \\ // 2 | 0 | 1 | -1 | 0 + \\ // 3 | 0 | 1 | -1 | 0 + \\ // + \\ // The r1's initial value of 1 compensates for the 1 here. + \\ sub r0, r1, r0, lsr #1 + \\ bx lr + ); + + unreachable; +} + +fn clzsi2_generic(a: i32) callconv(.c) i32 { + return clzXi2(i32, a); +} + +pub const __clzsi2 = switch (builtin.cpu.arch) { + .arm, .armeb, .thumb, .thumbeb => impl: { + const use_thumb1 = + (builtin.cpu.arch.isThumb() or builtin.cpu.has(.arm, .noarm)) and !builtin.cpu.has(.arm, .thumb2); + + if (use_thumb1) { + break :impl __clzsi2_thumb1; + } + // From here on we're either targeting Thumb2 or ARM. + else if (!builtin.cpu.arch.isThumb()) { + break :impl __clzsi2_arm32; + } + // Use the generic implementation otherwise. + else break :impl clzsi2_generic; + }, + else => clzsi2_generic, +}; + +pub fn __clzdi2(a: i64) callconv(.c) i32 { + return clzXi2(i64, a); +} + +pub fn __clzti2(a: i128) callconv(.c) i32 { + return clzXi2(i128, a); +} + +inline fn ctzXi2(comptime T: type, a: T) i32 { + var x = switch (@bitSizeOf(T)) { + 32 => @as(u32, @bitCast(a)), + 64 => @as(u64, @bitCast(a)), + 128 => @as(u128, @bitCast(a)), + else => unreachable, + }; + var n: T = 1; + // Number of trailing zeroes as binary search, from Hacker's Delight + var mask: @TypeOf(x) = std.math.maxInt(@TypeOf(x)); + comptime var shift = @bitSizeOf(T); + if (x == 0) return shift; + inline while (shift > 1) { + shift = shift >> 1; + mask = mask >> shift; + if ((x & mask) == 0) { + n = n + shift; + x = x >> shift; + } + } + return @intCast(n - @as(T, @bitCast((x & 1)))); +} + +pub fn __ctzsi2(a: i32) callconv(.c) i32 { + return ctzXi2(i32, a); +} + +pub fn __ctzdi2(a: i64) callconv(.c) i32 { + return ctzXi2(i64, a); +} + +pub fn __ctzti2(a: i128) callconv(.c) i32 { + return ctzXi2(i128, a); +} + +inline fn ffsXi2(comptime T: type, a: T) i32 { + var x: std.meta.Int(.unsigned, @typeInfo(T).int.bits) = @bitCast(a); + var n: T = 1; + // adapted from Number of trailing zeroes (see ctzXi2) + var mask: @TypeOf(x) = std.math.maxInt(@TypeOf(x)); + comptime var shift = @bitSizeOf(T); + // In contrast to ctz return 0 + if (x == 0) return 0; + inline while (shift > 1) { + shift = shift >> 1; + mask = mask >> shift; + if ((x & mask) == 0) { + n = n + shift; + x = x >> shift; + } + } + // return ctz + 1 + return @as(i32, @intCast(n - @as(T, @bitCast((x & 1))))) + 1; +} + +pub fn __ffssi2(a: i32) callconv(.c) i32 { + return ffsXi2(i32, a); +} + +pub fn __ffsdi2(a: i64) callconv(.c) i32 { + return ffsXi2(i64, a); +} + +pub fn __ffsti2(a: i128) callconv(.c) i32 { + return ffsXi2(i128, a); +} + +test { + _ = @import("clzsi2_test.zig"); + _ = @import("clzdi2_test.zig"); + _ = @import("clzti2_test.zig"); + + _ = @import("ctzsi2_test.zig"); + _ = @import("ctzdi2_test.zig"); + _ = @import("ctzti2_test.zig"); + + _ = @import("ffssi2_test.zig"); + _ = @import("ffsdi2_test.zig"); + _ = @import("ffsti2_test.zig"); +} diff --git a/build/compiler_rt/ctzdi2_test.zig b/build/compiler_rt/ctzdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/ctzsi2_test.zig b/build/compiler_rt/ctzsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/ctzti2_test.zig b/build/compiler_rt/ctzti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/divc3.zig b/build/compiler_rt/divc3.zig new file mode 100644 index 00000000..92d2b39f --- /dev/null +++ b/build/compiler_rt/divc3.zig @@ -0,0 +1,60 @@ +const std = @import("std"); +const isNan = std.math.isNan; +const isInf = std.math.isInf; +const scalbn = std.math.scalbn; +const ilogb = std.math.ilogb; +const maxInt = std.math.maxInt; +const minInt = std.math.minInt; +const isFinite = std.math.isFinite; +const copysign = std.math.copysign; +const Complex = @import("mulc3.zig").Complex; + +/// Implementation based on Annex G of C17 Standard (N2176) +pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { + var c = c_in; + var d = d_in; + + // logbw used to prevent under/over-flow + const logbw = ilogb(@max(@abs(c), @abs(d))); + const logbw_finite = logbw != maxInt(i32) and logbw != minInt(i32); + const ilogbw = if (logbw_finite) b: { + c = scalbn(c, -logbw); + d = scalbn(d, -logbw); + break :b logbw; + } else 0; + const denom = c * c + d * d; + const result = Complex(T){ + .real = scalbn((a * c + b * d) / denom, -ilogbw), + .imag = scalbn((b * c - a * d) / denom, -ilogbw), + }; + + // Recover infinities and zeros that computed as NaN+iNaN; + // the only cases are non-zero/zero, infinite/finite, and finite/infinite, ... + if (isNan(result.real) and isNan(result.imag)) { + const zero: T = 0.0; + const one: T = 1.0; + + if ((denom == 0.0) and (!isNan(a) or !isNan(b))) { + return .{ + .real = copysign(std.math.inf(T), c) * a, + .imag = copysign(std.math.inf(T), c) * b, + }; + } else if ((isInf(a) or isInf(b)) and isFinite(c) and isFinite(d)) { + const boxed_a = copysign(if (isInf(a)) one else zero, a); + const boxed_b = copysign(if (isInf(b)) one else zero, b); + return .{ + .real = std.math.inf(T) * (boxed_a * c - boxed_b * d), + .imag = std.math.inf(T) * (boxed_b * c - boxed_a * d), + }; + } else if (logbw == maxInt(i32) and isFinite(a) and isFinite(b)) { + const boxed_c = copysign(if (isInf(c)) one else zero, c); + const boxed_d = copysign(if (isInf(d)) one else zero, d); + return .{ + .real = 0.0 * (a * boxed_c + b * boxed_d), + .imag = 0.0 * (b * boxed_c - a * boxed_d), + }; + } + } + + return result; +} diff --git a/build/compiler_rt/divc3_test.zig b/build/compiler_rt/divc3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/divdc3.zig b/build/compiler_rt/divdc3.zig new file mode 100644 index 00000000..ce2797ee --- /dev/null +++ b/build/compiler_rt/divdc3.zig @@ -0,0 +1,13 @@ +const common = @import("./common.zig"); +const divc3 = @import("./divc3.zig"); +const Complex = @import("./mulc3.zig").Complex; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + @export(&__divdc3, .{ .name = "__divdc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __divdc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) Complex(f64) { + return divc3.divc3(f64, a, b, c, d); +} diff --git a/build/compiler_rt/divdf3.zig b/build/compiler_rt/divdf3.zig new file mode 100644 index 00000000..7b47cd3a --- /dev/null +++ b/build/compiler_rt/divdf3.zig @@ -0,0 +1,229 @@ +//! Ported from: +//! +//! https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divdf3.c + +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +const normalize = common.normalize; +const wideMultiply = common.wideMultiply; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__divdf3, .{ .name = "__divdf3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __divdf3(a: f64, b: f64) callconv(.c) f64 { + return div(a, b); +} + +fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return div(a, b); +} + +inline fn div(a: f64, b: f64) f64 { + const Z = std.meta.Int(.unsigned, 64); + const SignedZ = std.meta.Int(.signed, 64); + + const significandBits = std.math.floatMantissaBits(f64); + const exponentBits = std.math.floatExponentBits(f64); + + const signBit = (@as(Z, 1) << (significandBits + exponentBits)); + const maxExponent = ((1 << exponentBits) - 1); + const exponentBias = (maxExponent >> 1); + + const implicitBit = (@as(Z, 1) << significandBits); + const quietBit = implicitBit >> 1; + const significandMask = implicitBit - 1; + + const absMask = signBit - 1; + const exponentMask = absMask ^ significandMask; + const qnanRep = exponentMask | quietBit; + const infRep = @as(Z, @bitCast(std.math.inf(f64))); + + const aExponent: u32 = @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent); + const bExponent: u32 = @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent); + const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit; + + var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask; + var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask; + var scale: i32 = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { + const aAbs: Z = @as(Z, @bitCast(a)) & absMask; + const bAbs: Z = @as(Z, @bitCast(b)) & absMask; + + // NaN / anything = qNaN + if (aAbs > infRep) return @bitCast(@as(Z, @bitCast(a)) | quietBit); + // anything / NaN = qNaN + if (bAbs > infRep) return @bitCast(@as(Z, @bitCast(b)) | quietBit); + + if (aAbs == infRep) { + // infinity / infinity = NaN + if (bAbs == infRep) { + return @bitCast(qnanRep); + } + // infinity / anything else = +/- infinity + else { + return @bitCast(aAbs | quotientSign); + } + } + + // anything else / infinity = +/- 0 + if (bAbs == infRep) return @bitCast(quotientSign); + + if (aAbs == 0) { + // zero / zero = NaN + if (bAbs == 0) { + return @bitCast(qnanRep); + } + // zero / anything else = +/- zero + else { + return @bitCast(quotientSign); + } + } + // anything else / zero = +/- infinity + if (bAbs == 0) return @bitCast(infRep | quotientSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < implicitBit) scale +%= normalize(f64, &aSignificand); + if (bAbs < implicitBit) scale -%= normalize(f64, &bSignificand); + } + + // Or in the implicit significand bit. (If we fell through from the + // denormal path it was already set by normalize( ), but setting it twice + // won't hurt anything.) + aSignificand |= implicitBit; + bSignificand |= implicitBit; + var quotientExponent: i32 = @as(i32, @bitCast(aExponent -% bExponent)) +% scale; + + // Align the significand of b as a Q31 fixed-point number in the range + // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax + // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This + // is accurate to about 3.5 binary digits. + const q31b: u32 = @truncate(bSignificand >> 21); + var recip32 = @as(u32, 0x7504f333) -% q31b; + + // Now refine the reciprocal estimate using a Newton-Raphson iteration: + // + // x1 = x0 * (2 - x0 * b) + // + // This doubles the number of correct binary digits in the approximation + // with each iteration, so after three iterations, we have about 28 binary + // digits of accuracy. + var correction32: u32 = undefined; + correction32 = @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1); + recip32 = @truncate(@as(u64, recip32) *% correction32 >> 31); + correction32 = @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1); + recip32 = @truncate(@as(u64, recip32) *% correction32 >> 31); + correction32 = @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1); + recip32 = @truncate(@as(u64, recip32) *% correction32 >> 31); + + // recip32 might have overflowed to exactly zero in the preceding + // computation if the high word of b is exactly 1.0. This would sabotage + // the full-width final stage of the computation that follows, so we adjust + // recip32 downward by one bit. + recip32 -%= 1; + + // We need to perform one more iteration to get us to 56 binary digits; + // The last iteration needs to happen with extra precision. + const q63blo: u32 = @truncate(bSignificand << 11); + var correction: u64 = undefined; + var reciprocal: u64 = undefined; + correction = ~(@as(u64, recip32) *% q31b +% (@as(u64, recip32) *% q63blo >> 32)) +% 1; + const cHi: u32 = @truncate(correction >> 32); + const cLo: u32 = @truncate(correction); + reciprocal = @as(u64, recip32) *% cHi +% (@as(u64, recip32) *% cLo >> 32); + + // We already adjusted the 32-bit estimate, now we need to adjust the final + // 64-bit reciprocal estimate downward to ensure that it is strictly smaller + // than the infinitely precise exact reciprocal. Because the computation + // of the Newton-Raphson step is truncating at every step, this adjustment + // is small; most of the work is already done. + reciprocal -%= 2; + + // The numerical reciprocal is accurate to within 2^-56, lies in the + // interval [0.5, 1.0), and is strictly smaller than the true reciprocal + // of b. Multiplying a by this reciprocal thus gives a numerical q = a/b + // in Q53 with the following properties: + // + // 1. q < a/b + // 2. q is in the interval [0.5, 2.0) + // 3. the error in q is bounded away from 2^-53 (actually, we have a + // couple of bits to spare, but this is all we need). + + // We need a 64 x 64 multiply high to compute q, which isn't a basic + // operation in C, so we need to be a little bit fussy. + var quotient: Z = undefined; + var quotientLo: Z = undefined; + wideMultiply(Z, aSignificand << 2, reciprocal, "ient, "ientLo); + + // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). + // In either case, we are going to compute a residual of the form + // + // r = a - q*b + // + // We know from the construction of q that r satisfies: + // + // 0 <= r < ulp(q)*b + // + // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we + // already have the correct result. The exact halfway case cannot occur. + // We also take this time to right shift quotient if it falls in the [1,2) + // range and adjust the exponent accordingly. + var residual: Z = undefined; + if (quotient < (implicitBit << 1)) { + residual = (aSignificand << 53) -% quotient *% bSignificand; + quotientExponent -%= 1; + } else { + quotient >>= 1; + residual = (aSignificand << 52) -% quotient *% bSignificand; + } + + const writtenExponent = quotientExponent +% exponentBias; + + if (writtenExponent >= maxExponent) { + // If we have overflowed the exponent, return infinity. + return @bitCast(infRep | quotientSign); + } else if (writtenExponent < 1) { + if (writtenExponent == 0) { + // Check whether the rounded result is normal. + const round = @intFromBool((residual << 1) > bSignificand); + // Clear the implicit bit. + var absResult = quotient & significandMask; + // Round. + absResult += round; + if ((absResult & ~significandMask) != 0) { + // The rounded result is normal; return it. + return @bitCast(absResult | quotientSign); + } + } + // Flush denormals to zero. In the future, it would be nice to add + // code to round them correctly. + return @bitCast(quotientSign); + } else { + const round = @intFromBool((residual << 1) > bSignificand); + // Clear the implicit bit + var absResult = quotient & significandMask; + // Insert the exponent + absResult |= @as(Z, @bitCast(@as(SignedZ, writtenExponent))) << significandBits; + // Round + absResult +%= round; + // Insert the sign and return + return @bitCast(absResult | quotientSign); + } +} + +test { + _ = @import("divdf3_test.zig"); +} diff --git a/build/compiler_rt/divdf3_test.zig b/build/compiler_rt/divdf3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/divhc3.zig b/build/compiler_rt/divhc3.zig new file mode 100644 index 00000000..8243c545 --- /dev/null +++ b/build/compiler_rt/divhc3.zig @@ -0,0 +1,13 @@ +const common = @import("./common.zig"); +const divc3 = @import("./divc3.zig"); +const Complex = @import("./mulc3.zig").Complex; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + @export(&__divhc3, .{ .name = "__divhc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __divhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) Complex(f16) { + return divc3.divc3(f16, a, b, c, d); +} diff --git a/build/compiler_rt/divhf3.zig b/build/compiler_rt/divhf3.zig new file mode 100644 index 00000000..84bfe378 --- /dev/null +++ b/build/compiler_rt/divhf3.zig @@ -0,0 +1,11 @@ +const common = @import("common.zig"); +const divsf3 = @import("./divsf3.zig"); + +comptime { + @export(&__divhf3, .{ .name = "__divhf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __divhf3(a: f16, b: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(divsf3.__divsf3(a, b)); +} diff --git a/build/compiler_rt/divmodei4.zig b/build/compiler_rt/divmodei4.zig new file mode 100644 index 00000000..ab114522 --- /dev/null +++ b/build/compiler_rt/divmodei4.zig @@ -0,0 +1,52 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const udivmod = @import("udivmodei4.zig").divmod; + +comptime { + @export(&__divei4, .{ .name = "__divei4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__modei4, .{ .name = "__modei4", .linkage = common.linkage, .visibility = common.visibility }); +} + +const endian = builtin.cpu.arch.endian(); + +inline fn limb(x: []u32, i: usize) *u32 { + return if (endian == .little) &x[i] else &x[x.len - 1 - i]; +} + +inline fn neg(x: []u32) void { + var ov: u1 = 1; + for (0..x.len) |limb_index| { + const l = limb(x, limb_index); + l.*, ov = @addWithOverflow(~l.*, ov); + } +} + +/// Mutates the arguments! +fn divmod(q: ?[]u32, r: ?[]u32, u: []u32, v: []u32) !void { + const u_sign: i32 = @bitCast(u[u.len - 1]); + const v_sign: i32 = @bitCast(v[v.len - 1]); + if (u_sign < 0) neg(u); + if (v_sign < 0) neg(v); + try @call(.always_inline, udivmod, .{ q, r, u, v }); + if (q) |x| if (u_sign ^ v_sign < 0) neg(x); + if (r) |x| if (u_sign < 0) neg(x); +} + +pub fn __divei4(q_p: [*]u8, u_p: [*]u8, v_p: [*]u8, bits: usize) callconv(.c) void { + @setRuntimeSafety(common.test_safety); + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + const q: []u32 = @ptrCast(@alignCast(q_p[0..byte_size])); + const u: []u32 = @ptrCast(@alignCast(u_p[0..byte_size])); + const v: []u32 = @ptrCast(@alignCast(v_p[0..byte_size])); + @call(.always_inline, divmod, .{ q, null, u, v }) catch unreachable; +} + +pub fn __modei4(r_p: [*]u8, u_p: [*]u8, v_p: [*]u8, bits: usize) callconv(.c) void { + @setRuntimeSafety(common.test_safety); + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + const r: []u32 = @ptrCast(@alignCast(r_p[0..byte_size])); + const u: []u32 = @ptrCast(@alignCast(u_p[0..byte_size])); + const v: []u32 = @ptrCast(@alignCast(v_p[0..byte_size])); + @call(.always_inline, divmod, .{ null, r, u, v }) catch unreachable; +} diff --git a/build/compiler_rt/divsc3.zig b/build/compiler_rt/divsc3.zig new file mode 100644 index 00000000..504d8f7d --- /dev/null +++ b/build/compiler_rt/divsc3.zig @@ -0,0 +1,13 @@ +const common = @import("./common.zig"); +const divc3 = @import("./divc3.zig"); +const Complex = @import("./mulc3.zig").Complex; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + @export(&__divsc3, .{ .name = "__divsc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __divsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) Complex(f32) { + return divc3.divc3(f32, a, b, c, d); +} diff --git a/build/compiler_rt/divsf3.zig b/build/compiler_rt/divsf3.zig new file mode 100644 index 00000000..a74d3f7a --- /dev/null +++ b/build/compiler_rt/divsf3.zig @@ -0,0 +1,210 @@ +//! Ported from: +//! +//! https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divsf3.c + +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; + +const common = @import("common.zig"); +const normalize = common.normalize; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__divsf3, .{ .name = "__divsf3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __divsf3(a: f32, b: f32) callconv(.c) f32 { + return div(a, b); +} + +fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + return div(a, b); +} + +inline fn div(a: f32, b: f32) f32 { + const Z = std.meta.Int(.unsigned, 32); + + const significandBits = std.math.floatMantissaBits(f32); + const exponentBits = std.math.floatExponentBits(f32); + + const signBit = (@as(Z, 1) << (significandBits + exponentBits)); + const maxExponent = ((1 << exponentBits) - 1); + const exponentBias = (maxExponent >> 1); + + const implicitBit = (@as(Z, 1) << significandBits); + const quietBit = implicitBit >> 1; + const significandMask = implicitBit - 1; + + const absMask = signBit - 1; + const exponentMask = absMask ^ significandMask; + const qnanRep = exponentMask | quietBit; + const infRep: Z = @bitCast(std.math.inf(f32)); + + const aExponent: u32 = @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent); + const bExponent: u32 = @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent); + const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit; + + var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask; + var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask; + var scale: i32 = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { + const aAbs: Z = @as(Z, @bitCast(a)) & absMask; + const bAbs: Z = @as(Z, @bitCast(b)) & absMask; + + // NaN / anything = qNaN + if (aAbs > infRep) return @bitCast(@as(Z, @bitCast(a)) | quietBit); + // anything / NaN = qNaN + if (bAbs > infRep) return @bitCast(@as(Z, @bitCast(b)) | quietBit); + + if (aAbs == infRep) { + // infinity / infinity = NaN + if (bAbs == infRep) { + return @bitCast(qnanRep); + } + // infinity / anything else = +/- infinity + else { + return @bitCast(aAbs | quotientSign); + } + } + + // anything else / infinity = +/- 0 + if (bAbs == infRep) return @bitCast(quotientSign); + + if (aAbs == 0) { + // zero / zero = NaN + if (bAbs == 0) { + return @bitCast(qnanRep); + } + // zero / anything else = +/- zero + else { + return @bitCast(quotientSign); + } + } + // anything else / zero = +/- infinity + if (bAbs == 0) return @bitCast(infRep | quotientSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < implicitBit) scale +%= normalize(f32, &aSignificand); + if (bAbs < implicitBit) scale -%= normalize(f32, &bSignificand); + } + + // Or in the implicit significand bit. (If we fell through from the + // denormal path it was already set by normalize( ), but setting it twice + // won't hurt anything.) + aSignificand |= implicitBit; + bSignificand |= implicitBit; + var quotientExponent: i32 = @as(i32, @bitCast(aExponent -% bExponent)) +% scale; + + // Align the significand of b as a Q31 fixed-point number in the range + // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax + // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This + // is accurate to about 3.5 binary digits. + const q31b = bSignificand << 8; + var reciprocal = @as(u32, 0x7504f333) -% q31b; + + // Now refine the reciprocal estimate using a Newton-Raphson iteration: + // + // x1 = x0 * (2 - x0 * b) + // + // This doubles the number of correct binary digits in the approximation + // with each iteration, so after three iterations, we have about 28 binary + // digits of accuracy. + var correction: u32 = undefined; + correction = @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1); + reciprocal = @truncate(@as(u64, reciprocal) *% correction >> 31); + correction = @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1); + reciprocal = @truncate(@as(u64, reciprocal) *% correction >> 31); + correction = @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1); + reciprocal = @truncate(@as(u64, reciprocal) *% correction >> 31); + + // Exhaustive testing shows that the error in reciprocal after three steps + // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our + // expectations. We bump the reciprocal by a tiny value to force the error + // to be strictly positive (in the range [0x1.4fdfp-37,0x1.287246p-29], to + // be specific). This also causes 1/1 to give a sensible approximation + // instead of zero (due to overflow). + reciprocal -%= 2; + + // The numerical reciprocal is accurate to within 2^-28, lies in the + // interval [0x1.000000eep-1, 0x1.fffffffcp-1], and is strictly smaller + // than the true reciprocal of b. Multiplying a by this reciprocal thus + // gives a numerical q = a/b in Q24 with the following properties: + // + // 1. q < a/b + // 2. q is in the interval [0x1.000000eep-1, 0x1.fffffffcp0) + // 3. the error in q is at most 2^-24 + 2^-27 -- the 2^24 term comes + // from the fact that we truncate the product, and the 2^27 term + // is the error in the reciprocal of b scaled by the maximum + // possible value of a. As a consequence of this error bound, + // either q or nextafter(q) is the correctly rounded + var quotient: Z = @truncate(@as(u64, reciprocal) *% (aSignificand << 1) >> 32); + + // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). + // In either case, we are going to compute a residual of the form + // + // r = a - q*b + // + // We know from the construction of q that r satisfies: + // + // 0 <= r < ulp(q)*b + // + // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we + // already have the correct result. The exact halfway case cannot occur. + // We also take this time to right shift quotient if it falls in the [1,2) + // range and adjust the exponent accordingly. + var residual: Z = undefined; + if (quotient < (implicitBit << 1)) { + residual = (aSignificand << 24) -% quotient *% bSignificand; + quotientExponent -%= 1; + } else { + quotient >>= 1; + residual = (aSignificand << 23) -% quotient *% bSignificand; + } + + const writtenExponent = quotientExponent +% exponentBias; + + if (writtenExponent >= maxExponent) { + // If we have overflowed the exponent, return infinity. + return @bitCast(infRep | quotientSign); + } else if (writtenExponent < 1) { + if (writtenExponent == 0) { + // Check whether the rounded result is normal. + const round = @intFromBool((residual << 1) > bSignificand); + // Clear the implicit bit. + var absResult = quotient & significandMask; + // Round. + absResult += round; + if ((absResult & ~significandMask) > 0) { + // The rounded result is normal; return it. + return @bitCast(absResult | quotientSign); + } + } + // Flush denormals to zero. In the future, it would be nice to add + // code to round them correctly. + return @bitCast(quotientSign); + } else { + const round = @intFromBool((residual << 1) > bSignificand); + // Clear the implicit bit + var absResult = quotient & significandMask; + // Insert the exponent + absResult |= @as(Z, @bitCast(writtenExponent)) << significandBits; + // Round + absResult +%= round; + // Insert the sign and return + return @bitCast(absResult | quotientSign); + } +} + +test { + _ = @import("divsf3_test.zig"); +} diff --git a/build/compiler_rt/divsf3_test.zig b/build/compiler_rt/divsf3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/divtc3.zig b/build/compiler_rt/divtc3.zig new file mode 100644 index 00000000..3bdf2a90 --- /dev/null +++ b/build/compiler_rt/divtc3.zig @@ -0,0 +1,15 @@ +const common = @import("./common.zig"); +const divc3 = @import("./divc3.zig"); +const Complex = @import("./mulc3.zig").Complex; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + if (common.want_ppc_abi) + @export(&__divtc3, .{ .name = "__divkc3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__divtc3, .{ .name = "__divtc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __divtc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) Complex(f128) { + return divc3.divc3(f128, a, b, c, d); +} diff --git a/build/compiler_rt/divtf3.zig b/build/compiler_rt/divtf3.zig new file mode 100644 index 00000000..0bab96de --- /dev/null +++ b/build/compiler_rt/divtf3.zig @@ -0,0 +1,245 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +const common = @import("common.zig"); +const normalize = common.normalize; +const wideMultiply = common.wideMultiply; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__divtf3, .{ .name = "__divkf3", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_div, .{ .name = "_Qp_div", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__divtf3, .{ .name = "__divtf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __divtf3(a: f128, b: f128) callconv(.c) f128 { + return div(a, b); +} + +fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { + c.* = div(a.*, b.*); +} + +inline fn div(a: f128, b: f128) f128 { + const Z = std.meta.Int(.unsigned, 128); + + const significandBits = std.math.floatMantissaBits(f128); + const exponentBits = std.math.floatExponentBits(f128); + + const signBit = (@as(Z, 1) << (significandBits + exponentBits)); + const maxExponent = ((1 << exponentBits) - 1); + const exponentBias = (maxExponent >> 1); + + const implicitBit = (@as(Z, 1) << significandBits); + const quietBit = implicitBit >> 1; + const significandMask = implicitBit - 1; + + const absMask = signBit - 1; + const exponentMask = absMask ^ significandMask; + const qnanRep = exponentMask | quietBit; + const infRep: Z = @bitCast(std.math.inf(f128)); + + const aExponent: u32 = @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent); + const bExponent: u32 = @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent); + const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit; + + var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask; + var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask; + var scale: i32 = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { + const aAbs: Z = @as(Z, @bitCast(a)) & absMask; + const bAbs: Z = @as(Z, @bitCast(b)) & absMask; + + // NaN / anything = qNaN + if (aAbs > infRep) return @bitCast(@as(Z, @bitCast(a)) | quietBit); + // anything / NaN = qNaN + if (bAbs > infRep) return @bitCast(@as(Z, @bitCast(b)) | quietBit); + + if (aAbs == infRep) { + // infinity / infinity = NaN + if (bAbs == infRep) { + return @bitCast(qnanRep); + } + // infinity / anything else = +/- infinity + else { + return @bitCast(aAbs | quotientSign); + } + } + + // anything else / infinity = +/- 0 + if (bAbs == infRep) return @bitCast(quotientSign); + + if (aAbs == 0) { + // zero / zero = NaN + if (bAbs == 0) { + return @bitCast(qnanRep); + } + // zero / anything else = +/- zero + else { + return @bitCast(quotientSign); + } + } + // anything else / zero = +/- infinity + if (bAbs == 0) return @bitCast(infRep | quotientSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < implicitBit) scale +%= normalize(f128, &aSignificand); + if (bAbs < implicitBit) scale -%= normalize(f128, &bSignificand); + } + + // Set the implicit significand bit. If we fell through from the + // denormal path it was already set by normalize( ), but setting it twice + // won't hurt anything. + aSignificand |= implicitBit; + bSignificand |= implicitBit; + var quotientExponent: i32 = @as(i32, @bitCast(aExponent -% bExponent)) +% scale; + + // Align the significand of b as a Q63 fixed-point number in the range + // [1, 2.0) and get a Q64 approximate reciprocal using a small minimax + // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This + // is accurate to about 3.5 binary digits. + const q63b: u64 = @truncate(bSignificand >> 49); + var recip64 = @as(u64, 0x7504f333F9DE6484) -% q63b; + // 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2) + + // Now refine the reciprocal estimate using a Newton-Raphson iteration: + // + // x1 = x0 * (2 - x0 * b) + // + // This doubles the number of correct binary digits in the approximation + // with each iteration. + var correction64: u64 = undefined; + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + + // The reciprocal may have overflowed to zero if the upper half of b is + // exactly 1.0. This would sabatoge the full-width final stage of the + // computation that follows, so we adjust the reciprocal down by one bit. + recip64 -%= 1; + + // We need to perform one more iteration to get us to 112 binary digits; + // The last iteration needs to happen with extra precision. + const q127blo: u64 = @truncate(bSignificand << 15); + var correction: u128 = undefined; + var reciprocal: u128 = undefined; + + // NOTE: This operation is equivalent to __multi3, which is not implemented + // in some architecture + var r64q63: u128 = undefined; + var r64q127: u128 = undefined; + var r64cH: u128 = undefined; + var r64cL: u128 = undefined; + var dummy: u128 = undefined; + wideMultiply(u128, recip64, q63b, &dummy, &r64q63); + wideMultiply(u128, recip64, q127blo, &dummy, &r64q127); + + correction = -%(r64q63 + (r64q127 >> 64)); + + const cHi: u64 = @truncate(correction >> 64); + const cLo: u64 = @truncate(correction); + + wideMultiply(u128, recip64, cHi, &dummy, &r64cH); + wideMultiply(u128, recip64, cLo, &dummy, &r64cL); + + reciprocal = r64cH + (r64cL >> 64); + + // Adjust the final 128-bit reciprocal estimate downward to ensure that it + // is strictly smaller than the infinitely precise exact reciprocal. Because + // the computation of the Newton-Raphson step is truncating at every step, + // this adjustment is small; most of the work is already done. + reciprocal -%= 2; + + // The numerical reciprocal is accurate to within 2^-112, lies in the + // interval [0.5, 1.0), and is strictly smaller than the true reciprocal + // of b. Multiplying a by this reciprocal thus gives a numerical q = a/b + // in Q127 with the following properties: + // + // 1. q < a/b + // 2. q is in the interval [0.5, 2.0) + // 3. The error in q is bounded away from 2^-113 (actually, we have a + // couple of bits to spare, but this is all we need). + + // We need a 128 x 128 multiply high to compute q. + var quotient: u128 = undefined; + var quotientLo: u128 = undefined; + wideMultiply(u128, aSignificand << 2, reciprocal, "ient, "ientLo); + + // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). + // In either case, we are going to compute a residual of the form + // + // r = a - q*b + // + // We know from the construction of q that r satisfies: + // + // 0 <= r < ulp(q)*b + // + // If r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we + // already have the correct result. The exact halfway case cannot occur. + // We also take this time to right shift quotient if it falls in the [1,2) + // range and adjust the exponent accordingly. + var residual: u128 = undefined; + var qb: u128 = undefined; + + if (quotient < (implicitBit << 1)) { + wideMultiply(u128, quotient, bSignificand, &dummy, &qb); + residual = (aSignificand << 113) -% qb; + quotientExponent -%= 1; + } else { + quotient >>= 1; + wideMultiply(u128, quotient, bSignificand, &dummy, &qb); + residual = (aSignificand << 112) -% qb; + } + + const writtenExponent = quotientExponent +% exponentBias; + + if (writtenExponent >= maxExponent) { + // If we have overflowed the exponent, return infinity. + return @bitCast(infRep | quotientSign); + } else if (writtenExponent < 1) { + if (writtenExponent == 0) { + // Check whether the rounded result is normal. + const round = @intFromBool((residual << 1) > bSignificand); + // Clear the implicit bit. + var absResult = quotient & significandMask; + // Round. + absResult += round; + if ((absResult & ~significandMask) > 0) { + // The rounded result is normal; return it. + return @bitCast(absResult | quotientSign); + } + } + // Flush denormals to zero. In the future, it would be nice to add + // code to round them correctly. + return @bitCast(quotientSign); + } else { + const round = @intFromBool((residual << 1) >= bSignificand); + // Clear the implicit bit + var absResult = quotient & significandMask; + // Insert the exponent + absResult |= @as(Z, @intCast(writtenExponent)) << significandBits; + // Round + absResult +%= round; + // Insert the sign and return + return @bitCast(absResult | quotientSign); + } +} + +test { + _ = @import("divtf3_test.zig"); +} diff --git a/build/compiler_rt/divtf3_test.zig b/build/compiler_rt/divtf3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/divti3.zig b/build/compiler_rt/divti3.zig new file mode 100644 index 00000000..5f24d196 --- /dev/null +++ b/build/compiler_rt/divti3.zig @@ -0,0 +1,41 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const udivmod = @import("udivmod.zig").udivmod; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__divti3_windows_x86_64, .{ .name = "__divti3", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__divti3, .{ .name = "__divti3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __divti3(a: i128, b: i128) callconv(.c) i128 { + return div(a, b); +} + +const v128 = @Vector(2, u64); + +fn __divti3_windows_x86_64(a: v128, b: v128) callconv(.c) v128 { + return @bitCast(div(@bitCast(a), @bitCast(b))); +} + +inline fn div(a: i128, b: i128) i128 { + const s_a = a >> (128 - 1); + const s_b = b >> (128 - 1); + + const an = (a ^ s_a) -% s_a; + const bn = (b ^ s_b) -% s_b; + + const r = udivmod(u128, @bitCast(an), @bitCast(bn), null); + const s = s_a ^ s_b; + return (@as(i128, @bitCast(r)) ^ s) -% s; +} + +test { + _ = @import("divti3_test.zig"); +} diff --git a/build/compiler_rt/divti3_test.zig b/build/compiler_rt/divti3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/divxc3.zig b/build/compiler_rt/divxc3.zig new file mode 100644 index 00000000..6e5f7905 --- /dev/null +++ b/build/compiler_rt/divxc3.zig @@ -0,0 +1,13 @@ +const common = @import("./common.zig"); +const divc3 = @import("./divc3.zig"); +const Complex = @import("./mulc3.zig").Complex; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + @export(&__divxc3, .{ .name = "__divxc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __divxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) Complex(f80) { + return divc3.divc3(f80, a, b, c, d); +} diff --git a/build/compiler_rt/divxf3.zig b/build/compiler_rt/divxf3.zig new file mode 100644 index 00000000..1579db22 --- /dev/null +++ b/build/compiler_rt/divxf3.zig @@ -0,0 +1,210 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; + +const common = @import("common.zig"); +const normalize = common.normalize; +const wideMultiply = common.wideMultiply; + +pub const panic = common.panic; + +comptime { + @export(&__divxf3, .{ .name = "__divxf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __divxf3(a: f80, b: f80) callconv(.c) f80 { + const T = f80; + const Z = std.meta.Int(.unsigned, @bitSizeOf(T)); + + const significandBits = std.math.floatMantissaBits(T); + const fractionalBits = std.math.floatFractionalBits(T); + const exponentBits = std.math.floatExponentBits(T); + + const signBit = (@as(Z, 1) << (significandBits + exponentBits)); + const maxExponent = ((1 << exponentBits) - 1); + const exponentBias = (maxExponent >> 1); + + const integerBit = (@as(Z, 1) << fractionalBits); + const quietBit = integerBit >> 1; + const significandMask = (@as(Z, 1) << significandBits) - 1; + + const absMask = signBit - 1; + const qnanRep = @as(Z, @bitCast(std.math.nan(T))) | quietBit; + const infRep: Z = @bitCast(std.math.inf(T)); + + const aExponent: u32 = @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent); + const bExponent: u32 = @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent); + const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit; + + var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask; + var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask; + var scale: i32 = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { + const aAbs: Z = @as(Z, @bitCast(a)) & absMask; + const bAbs: Z = @as(Z, @bitCast(b)) & absMask; + + // NaN / anything = qNaN + if (aAbs > infRep) return @bitCast(@as(Z, @bitCast(a)) | quietBit); + // anything / NaN = qNaN + if (bAbs > infRep) return @bitCast(@as(Z, @bitCast(b)) | quietBit); + + if (aAbs == infRep) { + // infinity / infinity = NaN + if (bAbs == infRep) { + return @bitCast(qnanRep); + } + // infinity / anything else = +/- infinity + else { + return @bitCast(aAbs | quotientSign); + } + } + + // anything else / infinity = +/- 0 + if (bAbs == infRep) return @bitCast(quotientSign); + + if (aAbs == 0) { + // zero / zero = NaN + if (bAbs == 0) { + return @bitCast(qnanRep); + } + // zero / anything else = +/- zero + else { + return @bitCast(quotientSign); + } + } + // anything else / zero = +/- infinity + if (bAbs == 0) return @bitCast(infRep | quotientSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < integerBit) scale +%= normalize(T, &aSignificand); + if (bAbs < integerBit) scale -%= normalize(T, &bSignificand); + } + var quotientExponent: i32 = @as(i32, @bitCast(aExponent -% bExponent)) +% scale; + + // Align the significand of b as a Q63 fixed-point number in the range + // [1, 2.0) and get a Q64 approximate reciprocal using a small minimax + // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This + // is accurate to about 3.5 binary digits. + const q63b: u64 = @intCast(bSignificand); + var recip64 = @as(u64, 0x7504f333F9DE6484) -% q63b; + // 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2) + + // Now refine the reciprocal estimate using a Newton-Raphson iteration: + // + // x1 = x0 * (2 - x0 * b) + // + // This doubles the number of correct binary digits in the approximation + // with each iteration. + var correction64: u64 = undefined; + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + correction64 = @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1); + recip64 = @truncate(@as(u128, recip64) *% correction64 >> 63); + + // The reciprocal may have overflowed to zero if the upper half of b is + // exactly 1.0. This would sabatoge the full-width final stage of the + // computation that follows, so we adjust the reciprocal down by one bit. + recip64 -%= 1; + + // We need to perform one more iteration to get us to 112 binary digits; + // The last iteration needs to happen with extra precision. + + // NOTE: This operation is equivalent to __multi3, which is not implemented + // in some architechures + var reciprocal: u128 = undefined; + var correction: u128 = undefined; + var dummy: u128 = undefined; + wideMultiply(u128, recip64, q63b, &dummy, &correction); + + correction = -%correction; + + const cHi: u64 = @truncate(correction >> 64); + const cLo: u64 = @truncate(correction); + + var r64cH: u128 = undefined; + var r64cL: u128 = undefined; + wideMultiply(u128, recip64, cHi, &dummy, &r64cH); + wideMultiply(u128, recip64, cLo, &dummy, &r64cL); + + reciprocal = r64cH + (r64cL >> 64); + + // Adjust the final 128-bit reciprocal estimate downward to ensure that it + // is strictly smaller than the infinitely precise exact reciprocal. Because + // the computation of the Newton-Raphson step is truncating at every step, + // this adjustment is small; most of the work is already done. + reciprocal -%= 2; + + // The numerical reciprocal is accurate to within 2^-112, lies in the + // interval [0.5, 1.0), and is strictly smaller than the true reciprocal + // of b. Multiplying a by this reciprocal thus gives a numerical q = a/b + // in Q127 with the following properties: + // + // 1. q < a/b + // 2. q is in the interval [0.5, 2.0) + // 3. The error in q is bounded away from 2^-63 (actually, we have + // many bits to spare, but this is all we need). + + // We need a 128 x 128 multiply high to compute q. + var quotient128: u128 = undefined; + var quotientLo: u128 = undefined; + wideMultiply(u128, aSignificand << 2, reciprocal, "ient128, "ientLo); + + // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). + // Right shift the quotient if it falls in the [1,2) range and adjust the + // exponent accordingly. + const quotient: u64 = if (quotient128 < (integerBit << 1)) b: { + quotientExponent -= 1; + break :b @intCast(quotient128); + } else @intCast(quotient128 >> 1); + + // We are going to compute a residual of the form + // + // r = a - q*b + // + // We know from the construction of q that r satisfies: + // + // 0 <= r < ulp(q)*b + // + // If r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we + // already have the correct result. The exact halfway case cannot occur. + const residual: u64 = -%(quotient *% q63b); + + const writtenExponent = quotientExponent + exponentBias; + if (writtenExponent >= maxExponent) { + // If we have overflowed the exponent, return infinity. + return @bitCast(infRep | quotientSign); + } else if (writtenExponent < 1) { + if (writtenExponent == 0) { + // Check whether the rounded result is normal. + if (residual > (bSignificand >> 1)) { // round + if (quotient == (integerBit - 1)) // If the rounded result is normal, return it + return @bitCast(@as(Z, @bitCast(std.math.floatMin(T))) | quotientSign); + } + } + // Flush denormals to zero. In the future, it would be nice to add + // code to round them correctly. + return @bitCast(quotientSign); + } else { + const round = @intFromBool(residual > (bSignificand >> 1)); + // Insert the exponent + var absResult = quotient | (@as(Z, @intCast(writtenExponent)) << significandBits); + // Round + absResult +%= round; + // Insert the sign and return + return @bitCast(absResult | quotientSign | integerBit); + } +} + +test { + _ = @import("divxf3_test.zig"); +} diff --git a/build/compiler_rt/divxf3_test.zig b/build/compiler_rt/divxf3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/emutls.zig b/build/compiler_rt/emutls.zig new file mode 100644 index 00000000..0bb427b6 --- /dev/null +++ b/build/compiler_rt/emutls.zig @@ -0,0 +1,380 @@ +//! __emutls_get_address specific builtin +//! +//! derived work from LLVM Compiler Infrastructure - release 8.0 (MIT) +//! https://github.com/llvm-mirror/compiler-rt/blob/release_80/lib/builtins/emutls.c + +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +const abort = std.posix.abort; +const assert = std.debug.assert; +const expect = std.testing.expect; + +/// defined in C as: +/// typedef unsigned int gcc_word __attribute__((mode(word))); +const gcc_word = usize; + +pub const panic = common.panic; + +comptime { + if (builtin.link_libc and (builtin.abi.isAndroid() or builtin.abi.isOpenHarmony() or builtin.os.tag == .openbsd)) { + @export(&__emutls_get_address, .{ .name = "__emutls_get_address", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +/// public entrypoint for generated code using EmulatedTLS +pub fn __emutls_get_address(control: *emutls_control) callconv(.c) *anyopaque { + return control.getPointer(); +} + +/// Simple allocator interface, to avoid pulling in the while +/// std allocator implementation. +const simple_allocator = struct { + /// Allocate a memory chunk for requested type. Return a pointer on the data. + pub fn alloc(comptime T: type) *T { + return @ptrCast(@alignCast(advancedAlloc(@alignOf(T), @sizeOf(T)))); + } + + /// Allocate a slice of T, with len elements. + pub fn allocSlice(comptime T: type, len: usize) []T { + return @as([*]T, @ptrCast(@alignCast( + advancedAlloc(@alignOf(T), @sizeOf(T) * len), + )))[0 .. len - 1]; + } + + /// Allocate a memory chunk. + pub fn advancedAlloc(alignment: u29, size: usize) [*]u8 { + const minimal_alignment = @max(@alignOf(usize), alignment); + + var aligned_ptr: ?*anyopaque = undefined; + if (std.c.posix_memalign(&aligned_ptr, minimal_alignment, size) != 0) { + abort(); + } + + return @ptrCast(aligned_ptr); + } + + /// Resize a slice. + pub fn reallocSlice(comptime T: type, slice: []T, len: usize) []T { + const c_ptr: *anyopaque = @ptrCast(slice.ptr); + const new_array: [*]T = @ptrCast(@alignCast(std.c.realloc(c_ptr, @sizeOf(T) * len) orelse abort())); + return new_array[0..len]; + } + + /// Free a memory chunk allocated with simple_allocator. + pub fn free(ptr: anytype) void { + std.c.free(@ptrCast(ptr)); + } +}; + +/// Simple array of ?ObjectPointer with automatic resizing and +/// automatic storage allocation. +const ObjectArray = struct { + const ObjectPointer = *anyopaque; + + // content of the array + slots: []?ObjectPointer, + + /// create a new ObjectArray with n slots. must call deinit() to deallocate. + pub fn init(n: usize) *ObjectArray { + const array = simple_allocator.alloc(ObjectArray); + + array.* = ObjectArray{ + .slots = simple_allocator.allocSlice(?ObjectPointer, n), + }; + + for (array.slots) |*object| { + object.* = null; + } + + return array; + } + + /// deallocate the ObjectArray. + pub fn deinit(self: *ObjectArray) void { + // deallocated used objects in the array + for (self.slots) |*object| { + simple_allocator.free(object.*); + } + simple_allocator.free(self.slots); + simple_allocator.free(self); + } + + /// resize the ObjectArray if needed. + pub fn ensureLength(self: *ObjectArray, new_len: usize) *ObjectArray { + const old_len = self.slots.len; + + if (old_len > new_len) { + return self; + } + + // reallocate + self.slots = simple_allocator.reallocSlice(?ObjectPointer, self.slots, new_len); + + // init newly added slots + for (self.slots[old_len..]) |*object| { + object.* = null; + } + + return self; + } + + /// Retrieve the pointer at request index, using control to initialize it if needed. + pub fn getPointer(self: *ObjectArray, index: usize, control: *emutls_control) ObjectPointer { + if (self.slots[index] == null) { + // initialize the slot + const size = control.size; + const alignment: u29 = @truncate(control.alignment); + + var data = simple_allocator.advancedAlloc(alignment, size); + errdefer simple_allocator.free(data); + + if (control.default_value) |value| { + // default value: copy the content to newly allocated object. + @memcpy(data[0..size], @as([*]const u8, @ptrCast(value))); + } else { + // no default: return zeroed memory. + @memset(data[0..size], 0); + } + + self.slots[index] = data; + } + + return self.slots[index].?; + } +}; + +// Global structure for Thread Storage. +// It provides thread-safety for on-demand storage of Thread Objects. +const current_thread_storage = struct { + var key: std.c.pthread_key_t = undefined; + var init_once = std.once(current_thread_storage.init); + + /// Return a per thread ObjectArray with at least the expected index. + pub fn getArray(index: usize) *ObjectArray { + if (current_thread_storage.getspecific()) |array| { + // we already have a specific. just ensure the array is + // big enough for the wanted index. + return array.ensureLength(index); + } + + // no specific. we need to create a new array. + + // make it to contains at least 16 objects (to avoid too much + // reallocation at startup). + const size = @max(16, index); + + // create a new array and store it. + const array: *ObjectArray = ObjectArray.init(size); + current_thread_storage.setspecific(array); + return array; + } + + /// Return casted thread specific value. + fn getspecific() ?*ObjectArray { + return @ptrCast(@alignCast(std.c.pthread_getspecific(current_thread_storage.key))); + } + + /// Set casted thread specific value. + fn setspecific(new: ?*ObjectArray) void { + if (std.c.pthread_setspecific(current_thread_storage.key, @ptrCast(new)) != 0) { + abort(); + } + } + + /// Initialize pthread_key_t. + fn init() void { + if (std.c.pthread_key_create(¤t_thread_storage.key, current_thread_storage.deinit) != .SUCCESS) { + abort(); + } + } + + /// Invoked by pthread specific destructor. the passed argument is the ObjectArray pointer. + fn deinit(arrayPtr: *anyopaque) callconv(.c) void { + var array: *ObjectArray = @ptrCast(@alignCast(arrayPtr)); + array.deinit(); + } +}; + +const emutls_control = extern struct { + // A emutls_control value is a global value across all + // threads. The threads shares the index of TLS variable. The data + // array (containing address of allocated variables) is thread + // specific and stored using pthread_setspecific(). + + // size of the object in bytes + size: gcc_word, + + // alignment of the object in bytes + alignment: gcc_word, + + object: extern union { + // data[index-1] is the object address / 0 = uninit + index: usize, + + // object address, when in single thread env (not used) + address: *anyopaque, + }, + + // null or non-zero initial value for the object + default_value: ?*const anyopaque, + + // global Mutex used to serialize control.index initialization. + var mutex: std.c.pthread_mutex_t = std.c.PTHREAD_MUTEX_INITIALIZER; + + // global counter for keeping track of requested indexes. + // access should be done with mutex held. + var next_index: usize = 1; + + /// Simple wrapper for global lock. + fn lock() void { + if (std.c.pthread_mutex_lock(&emutls_control.mutex) != .SUCCESS) { + abort(); + } + } + + /// Simple wrapper for global unlock. + fn unlock() void { + if (std.c.pthread_mutex_unlock(&emutls_control.mutex) != .SUCCESS) { + abort(); + } + } + + /// Helper to retrieve nad initialize global unique index per emutls variable. + pub fn getIndex(self: *emutls_control) usize { + // Two threads could race against the same emutls_control. + + // Use atomic for reading coherent value lockless. + const index_lockless = @atomicLoad(usize, &self.object.index, .acquire); + + if (index_lockless != 0) { + // index is already initialized, return it. + return index_lockless; + } + + // index is uninitialized: take global lock to avoid possible race. + emutls_control.lock(); + defer emutls_control.unlock(); + + const index_locked = self.object.index; + if (index_locked != 0) { + // we lost a race, but index is already initialized: nothing particular to do. + return index_locked; + } + + // Store a new index atomically (for having coherent index_lockless reading). + @atomicStore(usize, &self.object.index, emutls_control.next_index, .release); + + // Increment the next available index + emutls_control.next_index += 1; + + return self.object.index; + } + + /// Simple helper for testing purpose. + pub fn init(comptime T: type, default_value: ?*const T) emutls_control { + return emutls_control{ + .size = @sizeOf(T), + .alignment = @alignOf(T), + .object = .{ .index = 0 }, + .default_value = @ptrCast(default_value), + }; + } + + /// Get the pointer on allocated storage for emutls variable. + pub fn getPointer(self: *emutls_control) *anyopaque { + // ensure current_thread_storage initialization is done + current_thread_storage.init_once.call(); + + const index = self.getIndex(); + var array = current_thread_storage.getArray(index); + + return array.getPointer(index - 1, self); + } + + /// Testing helper for retrieving typed pointer. + pub fn get_typed_pointer(self: *emutls_control, comptime T: type) *T { + assert(self.size == @sizeOf(T)); + assert(self.alignment == @alignOf(T)); + return @ptrCast(@alignCast(self.getPointer())); + } +}; + +test "simple_allocator" { + if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest; + + const data1: *[64]u8 = simple_allocator.alloc([64]u8); + defer simple_allocator.free(data1); + for (data1) |*c| { + c.* = 0xff; + } + + const data2: [*]u8 = simple_allocator.advancedAlloc(@alignOf(u8), 64); + defer simple_allocator.free(data2); + for (data2[0..63]) |*c| { + c.* = 0xff; + } +} + +test "__emutls_get_address zeroed" { + if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest; + + var ctl = emutls_control.init(usize, null); + try expect(ctl.object.index == 0); + + // retrieve a variable from ctl + const x: *usize = @ptrCast(@alignCast(__emutls_get_address(&ctl))); + try expect(ctl.object.index != 0); // index has been allocated for this ctl + try expect(x.* == 0); // storage has been zeroed + + // modify the storage + x.* = 1234; + + // retrieve a variable from ctl (same ctl) + const y: *usize = @ptrCast(@alignCast(__emutls_get_address(&ctl))); + + try expect(y.* == 1234); // same content that x.* + try expect(x == y); // same pointer +} + +test "__emutls_get_address with default_value" { + if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest; + + const value: usize = 5678; // default value + var ctl = emutls_control.init(usize, &value); + try expect(ctl.object.index == 0); + + const x: *usize = @ptrCast(@alignCast(__emutls_get_address(&ctl))); + try expect(ctl.object.index != 0); + try expect(x.* == 5678); // storage initialized with default value + + // modify the storage + x.* = 9012; + + try expect(value == 5678); // the default value didn't change + + const y: *usize = @ptrCast(@alignCast(__emutls_get_address(&ctl))); + try expect(y.* == 9012); // the modified storage persists +} + +test "test default_value with different sizes" { + if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest; + + const testType = struct { + fn _testType(comptime T: type, value: T) !void { + var ctl = emutls_control.init(T, &value); + const x = ctl.get_typed_pointer(T); + try expect(x.* == value); + } + }._testType; + + try testType(usize, 1234); + try testType(u32, 1234); + try testType(i16, -12); + try testType(f64, -12.0); + try testType( + @TypeOf("012345678901234567890123456789"), + "012345678901234567890123456789", + ); +} diff --git a/build/compiler_rt/exp.zig b/build/compiler_rt/exp.zig new file mode 100644 index 00000000..fa4356a3 --- /dev/null +++ b/build/compiler_rt/exp.zig @@ -0,0 +1,311 @@ +// Ported from musl, which is licensed under the MIT license: +// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +// +// https://git.musl-libc.org/cgit/musl/tree/src/math/expf.c +// https://git.musl-libc.org/cgit/musl/tree/src/math/exp.c + +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__exph, .{ .name = "__exph", .linkage = common.linkage, .visibility = common.visibility }); + @export(&expf, .{ .name = "expf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&exp, .{ .name = "exp", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__expx, .{ .name = "__expx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&expq, .{ .name = "expf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&expq, .{ .name = "expq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&expl, .{ .name = "expl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __exph(a: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(expf(a)); +} + +pub fn expf(x_: f32) callconv(.c) f32 { + const half = [_]f32{ 0.5, -0.5 }; + const ln2hi = 6.9314575195e-1; + const ln2lo = 1.4286067653e-6; + const invln2 = 1.4426950216e+0; + const P1 = 1.6666625440e-1; + const P2 = -2.7667332906e-3; + + var x = x_; + var hx: u32 = @bitCast(x); + const sign: i32 = @intCast(hx >> 31); + hx &= 0x7FFFFFFF; + + if (math.isNan(x)) { + return x; + } + + // |x| >= -87.33655 or nan + if (hx >= 0x42AEAC50) { + // nan + if (hx > 0x7F800000) { + return x; + } + // x >= 88.722839 + if (hx >= 0x42b17218 and sign == 0) { + return x * 0x1.0p127; + } + if (sign != 0) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(-0x1.0p-149 / x); // overflow + // x <= -103.972084 + if (hx >= 0x42CFF1B5) { + return 0; + } + } + } + + var k: i32 = undefined; + var hi: f32 = undefined; + var lo: f32 = undefined; + + // |x| > 0.5 * ln2 + if (hx > 0x3EB17218) { + // |x| > 1.5 * ln2 + if (hx > 0x3F851592) { + k = @intFromFloat(invln2 * x + half[@intCast(sign)]); + } else { + k = 1 - sign - sign; + } + + const fk: f32 = @floatFromInt(k); + hi = x - fk * ln2hi; + lo = fk * ln2lo; + x = hi - lo; + } + // |x| > 2^(-14) + else if (hx > 0x39000000) { + k = 0; + hi = x; + lo = 0; + } else { + if (common.want_float_exceptions) mem.doNotOptimizeAway(0x1.0p127 + x); // inexact + return 1 + x; + } + + const xx = x * x; + const c = x - xx * (P1 + xx * P2); + const y = 1 + (x * c / (2 - c) - lo + hi); + + if (k == 0) { + return y; + } else { + return math.scalbn(y, k); + } +} + +pub fn exp(x_: f64) callconv(.c) f64 { + const half = [_]f64{ 0.5, -0.5 }; + const ln2hi: f64 = 6.93147180369123816490e-01; + const ln2lo: f64 = 1.90821492927058770002e-10; + const invln2: f64 = 1.44269504088896338700e+00; + const P1: f64 = 1.66666666666666019037e-01; + const P2: f64 = -2.77777777770155933842e-03; + const P3: f64 = 6.61375632143793436117e-05; + const P4: f64 = -1.65339022054652515390e-06; + const P5: f64 = 4.13813679705723846039e-08; + + var x = x_; + const ux: u64 = @bitCast(x); + var hx = ux >> 32; + const sign: i32 = @intCast(hx >> 31); + hx &= 0x7FFFFFFF; + + if (math.isNan(x)) { + return x; + } + + // |x| >= 708.39 or nan + if (hx >= 0x4086232B) { + // nan + if (hx > 0x7FF00000) { + return x; + } + if (x > 709.782712893383973096) { + // overflow if x != inf + if (!math.isInf(x)) { + math.raiseOverflow(); + } + return math.inf(f64); + } + if (x < -708.39641853226410622) { + // underflow if x != -inf + // if (common.want_float_exceptions) mem.doNotOptimizeAway(@as(f32, -0x1.0p-149 / x)); + if (x < -745.13321910194110842) { + return 0; + } + } + } + + // argument reduction + var k: i32 = undefined; + var hi: f64 = undefined; + var lo: f64 = undefined; + + // |x| > 0.5 * ln2 + if (hx > 0x3FD62E42) { + // |x| >= 1.5 * ln2 + if (hx > 0x3FF0A2B2) { + k = @intFromFloat(invln2 * x + half[@intCast(sign)]); + } else { + k = 1 - sign - sign; + } + + const dk: f64 = @floatFromInt(k); + hi = x - dk * ln2hi; + lo = dk * ln2lo; + x = hi - lo; + } + // |x| > 2^(-28) + else if (hx > 0x3E300000) { + k = 0; + hi = x; + lo = 0; + } else { + // inexact if x != 0 + // if (common.want_float_exceptions) mem.doNotOptimizeAway(0x1.0p1023 + x); + return 1 + x; + } + + const xx = x * x; + const c = x - xx * (P1 + xx * (P2 + xx * (P3 + xx * (P4 + xx * P5)))); + const y = 1 + (x * c / (2 - c) - lo + hi); + + if (k == 0) { + return y; + } else { + return math.scalbn(y, k); + } +} + +pub fn __expx(a: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(expq(a)); +} + +pub fn expq(a: f128) callconv(.c) f128 { + // TODO: more correct implementation + return exp(@floatCast(a)); +} + +pub fn expl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __exph(x), + 32 => return expf(x), + 64 => return exp(x), + 80 => return __expx(x), + 128 => return expq(x), + else => @compileError("unreachable"), + } +} + +test "expf() special" { + try expectEqual(expf(0.0), 1.0); + try expectEqual(expf(-0.0), 1.0); + try expectEqual(expf(1.0), math.e); + try expectEqual(expf(math.ln2), 2.0); + try expectEqual(expf(math.inf(f32)), math.inf(f32)); + try expect(math.isPositiveZero(expf(-math.inf(f32)))); + try expect(math.isNan(expf(math.nan(f32)))); + try expect(math.isNan(expf(math.snan(f32)))); +} + +test "expf() sanity" { + try expectEqual(expf(-0x1.0223a0p+3), 0x1.490320p-12); + try expectEqual(expf(0x1.161868p+2), 0x1.34712ap+6); + try expectEqual(expf(-0x1.0c34b4p+3), 0x1.e06b1ap-13); + try expectEqual(expf(-0x1.a206f0p+2), 0x1.7dd484p-10); + try expectEqual(expf(0x1.288bbcp+3), 0x1.4abc80p+13); + try expectEqual(expf(0x1.52efd0p-1), 0x1.f04a9cp+0); + try expectEqual(expf(-0x1.a05cc8p-2), 0x1.54f1e0p-1); + try expectEqual(expf(0x1.1f9efap-1), 0x1.c0f628p+0); + try expectEqual(expf(0x1.8c5db0p-1), 0x1.1599b2p+1); + try expectEqual(expf(-0x1.5b86eap-1), 0x1.03b572p-1); + try expectEqual(expf(-0x1.57f25cp+2), 0x1.2fbea2p-8); + try expectEqual(expf(0x1.c7d310p+3), 0x1.76eefp+20); + try expectEqual(expf(0x1.19be70p+4), 0x1.52d3dep+25); + try expectEqual(expf(-0x1.ab6d70p+3), 0x1.a88adep-20); + try expectEqual(expf(-0x1.5ac18ep+2), 0x1.22b328p-8); + try expectEqual(expf(-0x1.925982p-1), 0x1.d2acc0p-2); + try expectEqual(expf(0x1.7221cep+3), 0x1.9c2ceap+16); + try expectEqual(expf(0x1.11a0d4p+4), 0x1.980ee6p+24); + try expectEqual(expf(-0x1.ae41a2p+1), 0x1.1c28d0p-5); + try expectEqual(expf(-0x1.329154p+4), 0x1.47ef94p-28); +} + +test "expf() boundary" { + try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite + try expectEqual(expf(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf + try expectEqual(expf(0x1.fffffep+127), math.inf(f32)); // Max input value + try expectEqual(expf(0x1p-149), 1.0); // Min positive input value + try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value + try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input + try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input + try expectEqual(expf(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero + try expectEqual(expf(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero + try expectEqual(expf(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal + try expectEqual(expf(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal + +} + +test "exp() special" { + try expectEqual(exp(0.0), 1.0); + try expectEqual(exp(-0.0), 1.0); + // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC + // try expectEqual(exp(1.0), math.e); + try expectEqual(exp(math.ln2), 2.0); + try expectEqual(exp(math.inf(f64)), math.inf(f64)); + try expect(math.isPositiveZero(exp(-math.inf(f64)))); + try expect(math.isNan(exp(math.nan(f64)))); + try expect(math.isNan(exp(math.snan(f64)))); +} + +test "exp() sanity" { + try expectEqual(exp(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12); + try expectEqual(exp(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6); + try expectEqual(exp(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13); + try expectEqual(exp(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10); + try expectEqual(exp(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13); + try expectEqual(exp(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0); + try expectEqual(exp(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1); + try expectEqual(exp(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0); + try expectEqual(exp(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1); + try expectEqual(exp(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1); + try expectEqual(exp(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8); + try expectEqual(exp(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20); + try expectEqual(exp(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25); + try expectEqual(exp(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20); + try expectEqual(exp(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8); + try expectEqual(exp(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2); + try expectEqual(exp(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16); + try expectEqual(exp(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24); + try expectEqual(exp(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5); + try expectEqual(exp(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28); +} + +test "exp() boundary" { + try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite + try expectEqual(exp(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf + try expectEqual(exp(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value + try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value + try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value + try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input + try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input + try expectEqual(exp(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero + try expectEqual(exp(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero + try expectEqual(exp(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal + try expectEqual(exp(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal +} diff --git a/build/compiler_rt/exp2.zig b/build/compiler_rt/exp2.zig new file mode 100644 index 00000000..ce79dff4 --- /dev/null +++ b/build/compiler_rt/exp2.zig @@ -0,0 +1,535 @@ +// Ported from musl, which is licensed under the MIT license: +// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +// +// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2f.c +// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2.c + +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__exp2h, .{ .name = "__exp2h", .linkage = common.linkage, .visibility = common.visibility }); + @export(&exp2f, .{ .name = "exp2f", .linkage = common.linkage, .visibility = common.visibility }); + @export(&exp2, .{ .name = "exp2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__exp2x, .{ .name = "__exp2x", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&exp2q, .{ .name = "exp2f128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&exp2q, .{ .name = "exp2q", .linkage = common.linkage, .visibility = common.visibility }); + @export(&exp2l, .{ .name = "exp2l", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __exp2h(x: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(exp2f(x)); +} + +pub fn exp2f(x: f32) callconv(.c) f32 { + const tblsiz: u32 = @intCast(exp2ft.len); + const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz)); + const P1: f32 = 0x1.62e430p-1; + const P2: f32 = 0x1.ebfbe0p-3; + const P3: f32 = 0x1.c6b348p-5; + const P4: f32 = 0x1.3b2c9cp-7; + + const u: u32 = @bitCast(x); + const ix = u & 0x7FFFFFFF; + + // |x| > 126 + if (ix > 0x42FC0000) { + // nan + if (ix > 0x7F800000) { + return x; + } + // x >= 128 + if (u >= 0x43000000 and u < 0x80000000) { + return x * 0x1.0p127; + } + // x < -126 + if (u >= 0x80000000) { + if (u >= 0xC3160000 or u & 0x000FFFF != 0) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(-0x1.0p-149 / x); + } + // x <= -150 + if (u >= 0xC3160000) { + return 0; + } + } + } + // |x| <= 0x1p-25 + else if (ix <= 0x33000000) { + return 1.0 + x; + } + + // NOTE: musl relies on unsafe behaviours which are replicated below + // (addition/bit-shift overflow). Appears that this produces the + // intended result but should confirm how GCC/Clang handle this to ensure. + + var uf = x + redux; + var i_0: u32 = @bitCast(uf); + i_0 +%= tblsiz / 2; + + const k = i_0 / tblsiz; + const uk: f64 = @bitCast(@as(u64, 0x3FF + k) << 52); + i_0 &= tblsiz - 1; + uf -= redux; + + const z: f64 = x - uf; + var r: f64 = exp2ft[@intCast(i_0)]; + const t: f64 = r * z; + r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4); + return @floatCast(r * uk); +} + +pub fn exp2(x: f64) callconv(.c) f64 { + const tblsiz: u32 = @intCast(exp2dt.len / 2); + const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz)); + const P1: f64 = 0x1.62e42fefa39efp-1; + const P2: f64 = 0x1.ebfbdff82c575p-3; + const P3: f64 = 0x1.c6b08d704a0a6p-5; + const P4: f64 = 0x1.3b2ab88f70400p-7; + const P5: f64 = 0x1.5d88003875c74p-10; + + const ux: u64 = @bitCast(x); + const ix = @as(u32, @intCast(ux >> 32)) & 0x7FFFFFFF; + + // TODO: This should be handled beneath. + if (math.isNan(x)) { + return math.nan(f64); + } + + // |x| >= 1022 or nan + if (ix >= 0x408FF000) { + // x >= 1024 or nan + if (ix >= 0x40900000 and ux >> 63 == 0) { + math.raiseOverflow(); + return math.inf(f64); + } + // -inf or -nan + if (ix >= 0x7FF00000) { + return -1 / x; + } + // x <= -1022 + if (ux >> 63 != 0) { + // underflow + if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(@as(f32, @floatCast(-0x1.0p-149 / x))); + } + if (x <= -1075) { + return 0; + } + } + } + // |x| < 0x1p-54 + else if (ix < 0x3C900000) { + return 1.0 + x; + } + + // NOTE: musl relies on unsafe behaviours which are replicated below + // (addition overflow, division truncation, casting). Appears that this + // produces the intended result but should confirm how GCC/Clang handle this + // to ensure. + + // reduce x + var uf: f64 = x + redux; + // NOTE: musl performs an implicit 64-bit to 32-bit u32 truncation here + var i_0: u32 = @truncate(@as(u64, @bitCast(uf))); + i_0 +%= tblsiz / 2; + + const k: u32 = i_0 / tblsiz * tblsiz; + const ik: i32 = @divTrunc(@as(i32, @bitCast(k)), tblsiz); + i_0 %= tblsiz; + uf -= redux; + + // r = exp2(y) = exp2t[i_0] * p(z - eps[i]) + var z: f64 = x - uf; + const t: f64 = exp2dt[@intCast(2 * i_0)]; + z -= exp2dt[@intCast(2 * i_0 + 1)]; + const r: f64 = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5)))); + + return math.scalbn(r, ik); +} + +pub fn __exp2x(x: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(exp2q(x)); +} + +pub fn exp2q(x: f128) callconv(.c) f128 { + // TODO: more correct implementation + return exp2(@floatCast(x)); +} + +pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __exp2h(x), + 32 => return exp2f(x), + 64 => return exp2(x), + 80 => return __exp2x(x), + 128 => return exp2q(x), + else => @compileError("unreachable"), + } +} + +const exp2ft = [_]f64{ + 0x1.6a09e667f3bcdp-1, + 0x1.7a11473eb0187p-1, + 0x1.8ace5422aa0dbp-1, + 0x1.9c49182a3f090p-1, + 0x1.ae89f995ad3adp-1, + 0x1.c199bdd85529cp-1, + 0x1.d5818dcfba487p-1, + 0x1.ea4afa2a490dap-1, + 0x1.0000000000000p+0, + 0x1.0b5586cf9890fp+0, + 0x1.172b83c7d517bp+0, + 0x1.2387a6e756238p+0, + 0x1.306fe0a31b715p+0, + 0x1.3dea64c123422p+0, + 0x1.4bfdad5362a27p+0, + 0x1.5ab07dd485429p+0, +}; + +const exp2dt = [_]f64{ + // exp2(z + eps) eps + 0x1.6a09e667f3d5dp-1, 0x1.9880p-44, + 0x1.6b052fa751744p-1, 0x1.8000p-50, + 0x1.6c012750bd9fep-1, -0x1.8780p-45, + 0x1.6cfdcddd476bfp-1, 0x1.ec00p-46, + 0x1.6dfb23c651a29p-1, -0x1.8000p-50, + 0x1.6ef9298593ae3p-1, -0x1.c000p-52, + 0x1.6ff7df9519386p-1, -0x1.fd80p-45, + 0x1.70f7466f42da3p-1, -0x1.c880p-45, + 0x1.71f75e8ec5fc3p-1, 0x1.3c00p-46, + 0x1.72f8286eacf05p-1, -0x1.8300p-44, + 0x1.73f9a48a58152p-1, -0x1.0c00p-47, + 0x1.74fbd35d7ccfcp-1, 0x1.f880p-45, + 0x1.75feb564267f1p-1, 0x1.3e00p-47, + 0x1.77024b1ab6d48p-1, -0x1.7d00p-45, + 0x1.780694fde5d38p-1, -0x1.d000p-50, + 0x1.790b938ac1d00p-1, 0x1.3000p-49, + 0x1.7a11473eb0178p-1, -0x1.d000p-49, + 0x1.7b17b0976d060p-1, 0x1.0400p-45, + 0x1.7c1ed0130c133p-1, 0x1.0000p-53, + 0x1.7d26a62ff8636p-1, -0x1.6900p-45, + 0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47, + 0x1.7f3878491c3e8p-1, -0x1.4580p-45, + 0x1.80427543e1b4ep-1, 0x1.3000p-44, + 0x1.814d2add1071ap-1, 0x1.f000p-47, + 0x1.82589994ccd7ep-1, -0x1.1c00p-45, + 0x1.8364c1eb942d0p-1, 0x1.9d00p-45, + 0x1.8471a4623cab5p-1, 0x1.7100p-43, + 0x1.857f4179f5bbcp-1, 0x1.2600p-45, + 0x1.868d99b4491afp-1, -0x1.2c40p-44, + 0x1.879cad931a395p-1, -0x1.3000p-45, + 0x1.88ac7d98a65b8p-1, -0x1.a800p-45, + 0x1.89bd0a4785800p-1, -0x1.d000p-49, + 0x1.8ace5422aa223p-1, 0x1.3280p-44, + 0x1.8be05bad619fap-1, 0x1.2b40p-43, + 0x1.8cf3216b54383p-1, -0x1.ed00p-45, + 0x1.8e06a5e08664cp-1, -0x1.0500p-45, + 0x1.8f1ae99157807p-1, 0x1.8280p-45, + 0x1.902fed0282c0ep-1, -0x1.cb00p-46, + 0x1.9145b0b91ff96p-1, -0x1.5e00p-47, + 0x1.925c353aa2ff9p-1, 0x1.5400p-48, + 0x1.93737b0cdc64ap-1, 0x1.7200p-46, + 0x1.948b82b5f98aep-1, -0x1.9000p-47, + 0x1.95a44cbc852cbp-1, 0x1.5680p-45, + 0x1.96bdd9a766f21p-1, -0x1.6d00p-44, + 0x1.97d829fde4e2ap-1, -0x1.1000p-47, + 0x1.98f33e47a23a3p-1, 0x1.d000p-45, + 0x1.9a0f170ca0604p-1, -0x1.8a40p-44, + 0x1.9b2bb4d53ff89p-1, 0x1.55c0p-44, + 0x1.9c49182a3f15bp-1, 0x1.6b80p-45, + 0x1.9d674194bb8c5p-1, -0x1.c000p-49, + 0x1.9e86319e3238ep-1, 0x1.7d00p-46, + 0x1.9fa5e8d07f302p-1, 0x1.6400p-46, + 0x1.a0c667b5de54dp-1, -0x1.5000p-48, + 0x1.a1e7aed8eb8f6p-1, 0x1.9e00p-47, + 0x1.a309bec4a2e27p-1, 0x1.ad80p-45, + 0x1.a42c980460a5dp-1, -0x1.af00p-46, + 0x1.a5503b23e259bp-1, 0x1.b600p-47, + 0x1.a674a8af46213p-1, 0x1.8880p-44, + 0x1.a799e1330b3a7p-1, 0x1.1200p-46, + 0x1.a8bfe53c12e8dp-1, 0x1.6c00p-47, + 0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45, + 0x1.ab0e521356fb8p-1, 0x1.b700p-45, + 0x1.ac36bbfd3f381p-1, 0x1.9000p-50, + 0x1.ad5ff3a3c2780p-1, 0x1.4000p-49, + 0x1.ae89f995ad2a3p-1, -0x1.c900p-45, + 0x1.afb4ce622f367p-1, 0x1.6500p-46, + 0x1.b0e07298db790p-1, 0x1.fd40p-45, + 0x1.b20ce6c9a89a9p-1, 0x1.2700p-46, + 0x1.b33a2b84f1a4bp-1, 0x1.d470p-43, + 0x1.b468415b747e7p-1, -0x1.8380p-44, + 0x1.b59728de5593ap-1, 0x1.8000p-54, + 0x1.b6c6e29f1c56ap-1, 0x1.ad00p-47, + 0x1.b7f76f2fb5e50p-1, 0x1.e800p-50, + 0x1.b928cf22749b2p-1, -0x1.4c00p-47, + 0x1.ba5b030a10603p-1, -0x1.d700p-47, + 0x1.bb8e0b79a6f66p-1, 0x1.d900p-47, + 0x1.bcc1e904bc1ffp-1, 0x1.2a00p-47, + 0x1.bdf69c3f3a16fp-1, -0x1.f780p-46, + 0x1.bf2c25bd71db8p-1, -0x1.0a00p-46, + 0x1.c06286141b2e9p-1, -0x1.1400p-46, + 0x1.c199bdd8552e0p-1, 0x1.be00p-47, + 0x1.c2d1cd9fa64eep-1, -0x1.9400p-47, + 0x1.c40ab5fffd02fp-1, -0x1.ed00p-47, + 0x1.c544778fafd15p-1, 0x1.9660p-44, + 0x1.c67f12e57d0cbp-1, -0x1.a100p-46, + 0x1.c7ba88988c1b6p-1, -0x1.8458p-42, + 0x1.c8f6d9406e733p-1, -0x1.a480p-46, + 0x1.ca3405751c4dfp-1, 0x1.b000p-51, + 0x1.cb720dcef9094p-1, 0x1.1400p-47, + 0x1.ccb0f2e6d1689p-1, 0x1.0200p-48, + 0x1.cdf0b555dc412p-1, 0x1.3600p-48, + 0x1.cf3155b5bab3bp-1, -0x1.6900p-47, + 0x1.d072d4a0789bcp-1, 0x1.9a00p-47, + 0x1.d1b532b08c8fap-1, -0x1.5e00p-46, + 0x1.d2f87080d8a85p-1, 0x1.d280p-46, + 0x1.d43c8eacaa203p-1, 0x1.1a00p-47, + 0x1.d5818dcfba491p-1, 0x1.f000p-50, + 0x1.d6c76e862e6a1p-1, -0x1.3a00p-47, + 0x1.d80e316c9834ep-1, -0x1.cd80p-47, + 0x1.d955d71ff6090p-1, 0x1.4c00p-48, + 0x1.da9e603db32aep-1, 0x1.f900p-48, + 0x1.dbe7cd63a8325p-1, 0x1.9800p-49, + 0x1.dd321f301b445p-1, -0x1.5200p-48, + 0x1.de7d5641c05bfp-1, -0x1.d700p-46, + 0x1.dfc97337b9aecp-1, -0x1.6140p-46, + 0x1.e11676b197d5ep-1, 0x1.b480p-47, + 0x1.e264614f5a3e7p-1, 0x1.0ce0p-43, + 0x1.e3b333b16ee5cp-1, 0x1.c680p-47, + 0x1.e502ee78b3fb4p-1, -0x1.9300p-47, + 0x1.e653924676d68p-1, -0x1.5000p-49, + 0x1.e7a51fbc74c44p-1, -0x1.7f80p-47, + 0x1.e8f7977cdb726p-1, -0x1.3700p-48, + 0x1.ea4afa2a490e8p-1, 0x1.5d00p-49, + 0x1.eb9f4867ccae4p-1, 0x1.61a0p-46, + 0x1.ecf482d8e680dp-1, 0x1.5500p-48, + 0x1.ee4aaa2188514p-1, 0x1.6400p-51, + 0x1.efa1bee615a13p-1, -0x1.e800p-49, + 0x1.f0f9c1cb64106p-1, -0x1.a880p-48, + 0x1.f252b376bb963p-1, -0x1.c900p-45, + 0x1.f3ac948dd7275p-1, 0x1.a000p-53, + 0x1.f50765b6e4524p-1, -0x1.4f00p-48, + 0x1.f6632798844fdp-1, 0x1.a800p-51, + 0x1.f7bfdad9cbe38p-1, 0x1.abc0p-48, + 0x1.f91d802243c82p-1, -0x1.4600p-50, + 0x1.fa7c1819e908ep-1, -0x1.b0c0p-47, + 0x1.fbdba3692d511p-1, -0x1.0e00p-51, + 0x1.fd3c22b8f7194p-1, -0x1.0de8p-46, + 0x1.fe9d96b2a23eep-1, 0x1.e430p-49, + 0x1.0000000000000p+0, 0x0.0000p+0, + 0x1.00b1afa5abcbep+0, -0x1.3400p-52, + 0x1.0163da9fb3303p+0, -0x1.2170p-46, + 0x1.02168143b0282p+0, 0x1.a400p-52, + 0x1.02c9a3e77806cp+0, 0x1.f980p-49, + 0x1.037d42e11bbcap+0, -0x1.7400p-51, + 0x1.04315e86e7f89p+0, 0x1.8300p-50, + 0x1.04e5f72f65467p+0, -0x1.a3f0p-46, + 0x1.059b0d315855ap+0, -0x1.2840p-47, + 0x1.0650a0e3c1f95p+0, 0x1.1600p-48, + 0x1.0706b29ddf71ap+0, 0x1.5240p-46, + 0x1.07bd42b72a82dp+0, -0x1.9a00p-49, + 0x1.0874518759bd0p+0, 0x1.6400p-49, + 0x1.092bdf66607c8p+0, -0x1.0780p-47, + 0x1.09e3ecac6f383p+0, -0x1.8000p-54, + 0x1.0a9c79b1f3930p+0, 0x1.fa00p-48, + 0x1.0b5586cf988fcp+0, -0x1.ac80p-48, + 0x1.0c0f145e46c8ap+0, 0x1.9c00p-50, + 0x1.0cc922b724816p+0, 0x1.5200p-47, + 0x1.0d83b23395dd8p+0, -0x1.ad00p-48, + 0x1.0e3ec32d3d1f3p+0, 0x1.bac0p-46, + 0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47, + 0x1.0fb66affed2f0p+0, -0x1.d300p-47, + 0x1.1073028d7234bp+0, 0x1.1500p-48, + 0x1.11301d0125b5bp+0, 0x1.c000p-49, + 0x1.11edbab5e2af9p+0, 0x1.6bc0p-46, + 0x1.12abdc06c31d5p+0, 0x1.8400p-49, + 0x1.136a814f2047dp+0, -0x1.ed00p-47, + 0x1.1429aaea92de9p+0, 0x1.8e00p-49, + 0x1.14e95934f3138p+0, 0x1.b400p-49, + 0x1.15a98c8a58e71p+0, 0x1.5300p-47, + 0x1.166a45471c3dfp+0, 0x1.3380p-47, + 0x1.172b83c7d5211p+0, 0x1.8d40p-45, + 0x1.17ed48695bb9fp+0, -0x1.5d00p-47, + 0x1.18af9388c8d93p+0, -0x1.c880p-46, + 0x1.1972658375d66p+0, 0x1.1f00p-46, + 0x1.1a35beb6fcba7p+0, 0x1.0480p-46, + 0x1.1af99f81387e3p+0, -0x1.7390p-43, + 0x1.1bbe084045d54p+0, 0x1.4e40p-45, + 0x1.1c82f95281c43p+0, -0x1.a200p-47, + 0x1.1d4873168b9b2p+0, 0x1.3800p-49, + 0x1.1e0e75eb44031p+0, 0x1.ac00p-49, + 0x1.1ed5022fcd938p+0, 0x1.1900p-47, + 0x1.1f9c18438cdf7p+0, -0x1.b780p-46, + 0x1.2063b88628d8fp+0, 0x1.d940p-45, + 0x1.212be3578a81ep+0, 0x1.8000p-50, + 0x1.21f49917ddd41p+0, 0x1.b340p-45, + 0x1.22bdda2791323p+0, 0x1.9f80p-46, + 0x1.2387a6e7561e7p+0, -0x1.9c80p-46, + 0x1.2451ffb821427p+0, 0x1.2300p-47, + 0x1.251ce4fb2a602p+0, -0x1.3480p-46, + 0x1.25e85711eceb0p+0, 0x1.2700p-46, + 0x1.26b4565e27d16p+0, 0x1.1d00p-46, + 0x1.2780e341de00fp+0, 0x1.1ee0p-44, + 0x1.284dfe1f5633ep+0, -0x1.4c00p-46, + 0x1.291ba7591bb30p+0, -0x1.3d80p-46, + 0x1.29e9df51fdf09p+0, 0x1.8b00p-47, + 0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45, + 0x1.2b87fd0dada3ap+0, 0x1.a340p-45, + 0x1.2c57e39771af9p+0, -0x1.0800p-46, + 0x1.2d285a6e402d9p+0, -0x1.ed00p-47, + 0x1.2df961f641579p+0, -0x1.4200p-48, + 0x1.2ecafa93e2ecfp+0, -0x1.4980p-45, + 0x1.2f9d24abd8822p+0, -0x1.6300p-46, + 0x1.306fe0a31b625p+0, -0x1.2360p-44, + 0x1.31432edeea50bp+0, -0x1.0df8p-40, + 0x1.32170fc4cd7b8p+0, -0x1.2480p-45, + 0x1.32eb83ba8e9a2p+0, -0x1.5980p-45, + 0x1.33c08b2641766p+0, 0x1.ed00p-46, + 0x1.3496266e3fa27p+0, -0x1.c000p-50, + 0x1.356c55f929f0fp+0, -0x1.0d80p-44, + 0x1.36431a2de88b9p+0, 0x1.2c80p-45, + 0x1.371a7373aaa39p+0, 0x1.0600p-45, + 0x1.37f26231e74fep+0, -0x1.6600p-46, + 0x1.38cae6d05d838p+0, -0x1.ae00p-47, + 0x1.39a401b713ec3p+0, -0x1.4720p-43, + 0x1.3a7db34e5a020p+0, 0x1.8200p-47, + 0x1.3b57fbfec6e95p+0, 0x1.e800p-44, + 0x1.3c32dc313a8f2p+0, 0x1.f800p-49, + 0x1.3d0e544ede122p+0, -0x1.7a00p-46, + 0x1.3dea64c1234bbp+0, 0x1.6300p-45, + 0x1.3ec70df1c4eccp+0, -0x1.8a60p-43, + 0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44, + 0x1.40822c367a0bbp+0, 0x1.5b80p-45, + 0x1.4160a21f72e95p+0, 0x1.ec00p-46, + 0x1.423fb27094646p+0, -0x1.3600p-46, + 0x1.431f5d950a920p+0, 0x1.3980p-45, + 0x1.43ffa3f84b9ebp+0, 0x1.a000p-48, + 0x1.44e0860618919p+0, -0x1.6c00p-48, + 0x1.45c2042a7d201p+0, -0x1.bc00p-47, + 0x1.46a41ed1d0016p+0, -0x1.2800p-46, + 0x1.4786d668b3326p+0, 0x1.0e00p-44, + 0x1.486a2b5c13c00p+0, -0x1.d400p-45, + 0x1.494e1e192af04p+0, 0x1.c200p-47, + 0x1.4a32af0d7d372p+0, -0x1.e500p-46, + 0x1.4b17dea6db801p+0, 0x1.7800p-47, + 0x1.4bfdad53629e1p+0, -0x1.3800p-46, + 0x1.4ce41b817c132p+0, 0x1.0800p-47, + 0x1.4dcb299fddddbp+0, 0x1.c700p-45, + 0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46, + 0x1.4f9b2769d2d02p+0, 0x1.9200p-46, + 0x1.508417f4531c1p+0, -0x1.8c00p-47, + 0x1.516daa2cf662ap+0, -0x1.a000p-48, + 0x1.5257de83f51eap+0, 0x1.a080p-43, + 0x1.5342b569d4edap+0, -0x1.6d80p-45, + 0x1.542e2f4f6ac1ap+0, -0x1.2440p-44, + 0x1.551a4ca5d94dbp+0, 0x1.83c0p-43, + 0x1.56070dde9116bp+0, 0x1.4b00p-45, + 0x1.56f4736b529dep+0, 0x1.15a0p-43, + 0x1.57e27dbe2c40ep+0, -0x1.9e00p-45, + 0x1.58d12d497c76fp+0, -0x1.3080p-45, + 0x1.59c0827ff0b4cp+0, 0x1.dec0p-43, + 0x1.5ab07dd485427p+0, -0x1.4000p-51, + 0x1.5ba11fba87af4p+0, 0x1.0080p-44, + 0x1.5c9268a59460bp+0, -0x1.6c80p-45, + 0x1.5d84590998e3fp+0, 0x1.69a0p-43, + 0x1.5e76f15ad20e1p+0, -0x1.b400p-46, + 0x1.5f6a320dcebcap+0, 0x1.7700p-46, + 0x1.605e1b976dcb8p+0, 0x1.6f80p-45, + 0x1.6152ae6cdf715p+0, 0x1.1000p-47, + 0x1.6247eb03a5531p+0, -0x1.5d00p-46, + 0x1.633dd1d1929b5p+0, -0x1.2d00p-46, + 0x1.6434634ccc313p+0, -0x1.a800p-49, + 0x1.652b9febc8efap+0, -0x1.8600p-45, + 0x1.6623882553397p+0, 0x1.1fe0p-40, + 0x1.671c1c708328ep+0, -0x1.7200p-44, + 0x1.68155d44ca97ep+0, 0x1.6800p-49, + 0x1.690f4b19e9471p+0, -0x1.9780p-45, +}; + +test "exp2f() special" { + try expectEqual(exp2f(0.0), 1.0); + try expectEqual(exp2f(-0.0), 1.0); + try expectEqual(exp2f(1.0), 2.0); + try expectEqual(exp2f(-1.0), 0.5); + try expectEqual(exp2f(math.inf(f32)), math.inf(f32)); + try expect(math.isPositiveZero(exp2f(-math.inf(f32)))); + try expect(math.isNan(exp2f(math.nan(f32)))); + try expect(math.isNan(exp2f(math.snan(f32)))); +} + +test "exp2f() sanity" { + try expectEqual(exp2f(-0x1.0223a0p+3), 0x1.e8d134p-9); + try expectEqual(exp2f(0x1.161868p+2), 0x1.453672p+4); + try expectEqual(exp2f(-0x1.0c34b4p+3), 0x1.890ca0p-9); + try expectEqual(exp2f(-0x1.a206f0p+2), 0x1.622d4ep-7); + try expectEqual(exp2f(0x1.288bbcp+3), 0x1.340ecep+9); + try expectEqual(exp2f(0x1.52efd0p-1), 0x1.950eeep+0); + try expectEqual(exp2f(-0x1.a05cc8p-2), 0x1.824056p-1); + try expectEqual(exp2f(0x1.1f9efap-1), 0x1.79dfa2p+0); + try expectEqual(exp2f(0x1.8c5db0p-1), 0x1.b5ceacp+0); + try expectEqual(exp2f(-0x1.5b86eap-1), 0x1.3fd8bap-1); +} + +test "exp2f() boundary" { + try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite + try expectEqual(exp2f(0x1p+7), math.inf(f32)); // The first value that gives infinite result + try expectEqual(exp2f(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero + try expectEqual(exp2f(-0x1.2cp+7), 0); // The first value at which the result flushes to zero + try expectEqual(exp2f(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal + try expectEqual(exp2f(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal + try expectEqual(exp2f(0x1.fffffep+127), math.inf(f32)); // Max input value + try expectEqual(exp2f(0x1p-149), 1); // Min positive input value + try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value + try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input + try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input +} + +test "exp2() special" { + try expectEqual(exp2(0.0), 1.0); + try expectEqual(exp2(-0.0), 1.0); + try expectEqual(exp2(1.0), 2.0); + try expectEqual(exp2(-1.0), 0.5); + try expectEqual(exp2(math.inf(f64)), math.inf(f64)); + try expect(math.isPositiveZero(exp2(-math.inf(f64)))); + try expect(math.isNan(exp2(math.nan(f64)))); + try expect(math.isNan(exp2(math.snan(f64)))); +} + +test "exp2() sanity" { + try expectEqual(exp2(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9); + try expectEqual(exp2(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4); + try expectEqual(exp2(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9); + try expectEqual(exp2(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7); + try expectEqual(exp2(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9); + try expectEqual(exp2(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0); + try expectEqual(exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1); + try expectEqual(exp2(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0); + try expectEqual(exp2(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0); + try expectEqual(exp2(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1); +} + +test "exp2() boundary" { + try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite + try expectEqual(exp2(0x1p+10), math.inf(f64)); // The first value that gives infinite result + try expectEqual(exp2(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero + try expectEqual(exp2(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero + try expectEqual(exp2(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal + try expectEqual(exp2(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal + try expectEqual(exp2(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value + try expectEqual(exp2(0x1p-1074), 1); // Min positive input value + try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value + try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input + try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input +} diff --git a/build/compiler_rt/extenddftf2.zig b/build/compiler_rt/extenddftf2.zig new file mode 100644 index 00000000..457a6452 --- /dev/null +++ b/build/compiler_rt/extenddftf2.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const extendf = @import("./extendf.zig").extendf; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__extenddftf2, .{ .name = "__extenddfkf2", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_dtoq, .{ .name = "_Qp_dtoq", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__extenddftf2, .{ .name = "__extenddftf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __extenddftf2(a: f64) callconv(.c) f128 { + return extendf(f128, f64, @as(u64, @bitCast(a))); +} + +fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void { + c.* = extendf(f128, f64, @as(u64, @bitCast(a))); +} diff --git a/build/compiler_rt/extenddfxf2.zig b/build/compiler_rt/extenddfxf2.zig new file mode 100644 index 00000000..55a1df56 --- /dev/null +++ b/build/compiler_rt/extenddfxf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const extend_f80 = @import("./extendf.zig").extend_f80; + +pub const panic = common.panic; + +comptime { + @export(&__extenddfxf2, .{ .name = "__extenddfxf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __extenddfxf2(a: f64) callconv(.c) f80 { + return extend_f80(f64, @as(u64, @bitCast(a))); +} diff --git a/build/compiler_rt/extendf.zig b/build/compiler_rt/extendf.zig new file mode 100644 index 00000000..6e546b18 --- /dev/null +++ b/build/compiler_rt/extendf.zig @@ -0,0 +1,139 @@ +const std = @import("std"); + +pub inline fn extendf( + comptime dst_t: type, + comptime src_t: type, + a: std.meta.Int(.unsigned, @typeInfo(src_t).float.bits), +) dst_t { + const src_rep_t = std.meta.Int(.unsigned, @typeInfo(src_t).float.bits); + const dst_rep_t = std.meta.Int(.unsigned, @typeInfo(dst_t).float.bits); + const srcSigBits = std.math.floatMantissaBits(src_t); + const dstSigBits = std.math.floatMantissaBits(dst_t); + + // Various constants whose values follow from the type parameters. + // Any reasonable optimizer will fold and propagate all of these. + const srcBits = @bitSizeOf(src_t); + const srcExpBits = srcBits - srcSigBits - 1; + const srcInfExp = (1 << srcExpBits) - 1; + const srcExpBias = srcInfExp >> 1; + + const srcMinNormal = 1 << srcSigBits; + const srcInfinity = srcInfExp << srcSigBits; + const srcSignMask = 1 << (srcSigBits + srcExpBits); + const srcAbsMask = srcSignMask - 1; + const srcQNaN = 1 << (srcSigBits - 1); + const srcNaNCode = srcQNaN - 1; + + const dstBits = @bitSizeOf(dst_t); + const dstExpBits = dstBits - dstSigBits - 1; + const dstInfExp = (1 << dstExpBits) - 1; + const dstExpBias = dstInfExp >> 1; + + const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits; + + // Break a into a sign and representation of the absolute value + const aRep: src_rep_t = @bitCast(a); + const aAbs: src_rep_t = aRep & srcAbsMask; + const sign: src_rep_t = aRep & srcSignMask; + var absResult: dst_rep_t = undefined; + + if (aAbs -% srcMinNormal < srcInfinity - srcMinNormal) { + // a is a normal number. + // Extend to the destination type by shifting the significand and + // exponent into the proper position and rebiasing the exponent. + absResult = @as(dst_rep_t, aAbs) << (dstSigBits - srcSigBits); + absResult += (dstExpBias - srcExpBias) << dstSigBits; + } else if (aAbs >= srcInfinity) { + // a is NaN or infinity. + // Conjure the result by beginning with infinity, then setting the qNaN + // bit (if needed) and right-aligning the rest of the trailing NaN + // payload field. + absResult = dstInfExp << dstSigBits; + absResult |= @as(dst_rep_t, aAbs & srcQNaN) << (dstSigBits - srcSigBits); + absResult |= @as(dst_rep_t, aAbs & srcNaNCode) << (dstSigBits - srcSigBits); + } else if (aAbs != 0) { + // a is denormal. + // renormalize the significand and clear the leading bit, then insert + // the correct adjusted exponent in the destination type. + const scale: u32 = @clz(aAbs) - @clz(@as(src_rep_t, srcMinNormal)); + absResult = @as(dst_rep_t, aAbs) << @intCast(dstSigBits - srcSigBits + scale); + absResult ^= dstMinNormal; + const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1; + absResult |= @as(dst_rep_t, @intCast(resultExponent)) << dstSigBits; + } else { + // a is zero. + absResult = 0; + } + + // Apply the signbit to (dst_t)abs(a). + const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits); + return @bitCast(result); +} + +pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeInfo(src_t).float.bits)) f80 { + const src_rep_t = std.meta.Int(.unsigned, @typeInfo(src_t).float.bits); + const src_sig_bits = std.math.floatMantissaBits(src_t); + const dst_int_bit = 0x8000000000000000; + const dst_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit + + const dst_exp_bias = 16383; + + const src_bits = @bitSizeOf(src_t); + const src_exp_bits = src_bits - src_sig_bits - 1; + const src_inf_exp = (1 << src_exp_bits) - 1; + const src_exp_bias = src_inf_exp >> 1; + + const src_min_normal = 1 << src_sig_bits; + const src_inf = src_inf_exp << src_sig_bits; + const src_sign_mask = 1 << (src_sig_bits + src_exp_bits); + const src_abs_mask = src_sign_mask - 1; + const src_qnan = 1 << (src_sig_bits - 1); + const src_nan_code = src_qnan - 1; + + var dst: std.math.F80 = undefined; + + // Break a into a sign and representation of the absolute value + const a_abs = a & src_abs_mask; + const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0; + + if (a_abs -% src_min_normal < src_inf - src_min_normal) { + // a is a normal number. + // Extend to the destination type by shifting the significand and + // exponent into the proper position and rebiasing the exponent. + dst.exp = @intCast(a_abs >> src_sig_bits); + dst.exp += dst_exp_bias - src_exp_bias; + dst.fraction = @as(u64, a_abs) << (dst_sig_bits - src_sig_bits); + dst.fraction |= dst_int_bit; // bit 64 is always set for normal numbers + } else if (a_abs >= src_inf) { + // a is NaN or infinity. + // Conjure the result by beginning with infinity, then setting the qNaN + // bit (if needed) and right-aligning the rest of the trailing NaN + // payload field. + dst.exp = 0x7fff; + dst.fraction = dst_int_bit; + dst.fraction |= @as(u64, a_abs & src_qnan) << (dst_sig_bits - src_sig_bits); + dst.fraction |= @as(u64, a_abs & src_nan_code) << (dst_sig_bits - src_sig_bits); + } else if (a_abs != 0) { + // a is denormal. + // renormalize the significand and clear the leading bit, then insert + // the correct adjusted exponent in the destination type. + const scale: u16 = @clz(a_abs) - @clz(@as(src_rep_t, src_min_normal)); + + dst.fraction = @as(u64, a_abs) << @intCast(dst_sig_bits - src_sig_bits + scale); + dst.fraction |= dst_int_bit; // bit 64 is always set for normal numbers + dst.exp = @truncate(a_abs >> @intCast(src_sig_bits - scale)); + dst.exp ^= 1; + dst.exp |= dst_exp_bias - src_exp_bias - scale + 1; + } else { + // a is zero. + dst.exp = 0; + dst.fraction = 0; + } + + dst.exp |= sign; + return dst.toFloat(); +} + +test { + _ = @import("extendf_test.zig"); +} diff --git a/build/compiler_rt/extendf_test.zig b/build/compiler_rt/extendf_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/extendhfdf2.zig b/build/compiler_rt/extendhfdf2.zig new file mode 100644 index 00000000..7b1a7929 --- /dev/null +++ b/build/compiler_rt/extendhfdf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const extendf = @import("./extendf.zig").extendf; + +pub const panic = common.panic; + +comptime { + @export(&__extendhfdf2, .{ .name = "__extendhfdf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __extendhfdf2(a: common.F16T(f64)) callconv(.c) f64 { + return extendf(f64, f16, @as(u16, @bitCast(a))); +} diff --git a/build/compiler_rt/extendhfsf2.zig b/build/compiler_rt/extendhfsf2.zig new file mode 100644 index 00000000..37f3d79c --- /dev/null +++ b/build/compiler_rt/extendhfsf2.zig @@ -0,0 +1,25 @@ +const common = @import("./common.zig"); +const extendf = @import("./extendf.zig").extendf; + +pub const panic = common.panic; + +comptime { + if (common.gnu_f16_abi) { + @export(&__gnu_h2f_ieee, .{ .name = "__gnu_h2f_ieee", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_aeabi) { + @export(&__aeabi_h2f, .{ .name = "__aeabi_h2f", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__extendhfsf2, .{ .name = "__extendhfsf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __extendhfsf2(a: common.F16T(f32)) callconv(.c) f32 { + return extendf(f32, f16, @as(u16, @bitCast(a))); +} + +fn __gnu_h2f_ieee(a: common.F16T(f32)) callconv(.c) f32 { + return extendf(f32, f16, @as(u16, @bitCast(a))); +} + +fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) f32 { + return extendf(f32, f16, @as(u16, @bitCast(a))); +} diff --git a/build/compiler_rt/extendhftf2.zig b/build/compiler_rt/extendhftf2.zig new file mode 100644 index 00000000..3b1f257f --- /dev/null +++ b/build/compiler_rt/extendhftf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const extendf = @import("./extendf.zig").extendf; + +pub const panic = common.panic; + +comptime { + @export(&__extendhftf2, .{ .name = "__extendhftf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __extendhftf2(a: common.F16T(f128)) callconv(.c) f128 { + return extendf(f128, f16, @as(u16, @bitCast(a))); +} diff --git a/build/compiler_rt/extendhfxf2.zig b/build/compiler_rt/extendhfxf2.zig new file mode 100644 index 00000000..74e4fb64 --- /dev/null +++ b/build/compiler_rt/extendhfxf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const extend_f80 = @import("./extendf.zig").extend_f80; + +pub const panic = common.panic; + +comptime { + @export(&__extendhfxf2, .{ .name = "__extendhfxf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __extendhfxf2(a: common.F16T(f80)) callconv(.c) f80 { + return extend_f80(f16, @as(u16, @bitCast(a))); +} diff --git a/build/compiler_rt/extendsfdf2.zig b/build/compiler_rt/extendsfdf2.zig new file mode 100644 index 00000000..c87b721c --- /dev/null +++ b/build/compiler_rt/extendsfdf2.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const extendf = @import("./extendf.zig").extendf; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__extendsfdf2, .{ .name = "__extendsfdf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +fn __extendsfdf2(a: f32) callconv(.c) f64 { + return extendf(f64, f32, @as(u32, @bitCast(a))); +} + +fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 { + return extendf(f64, f32, @as(u32, @bitCast(a))); +} diff --git a/build/compiler_rt/extendsftf2.zig b/build/compiler_rt/extendsftf2.zig new file mode 100644 index 00000000..4e45f850 --- /dev/null +++ b/build/compiler_rt/extendsftf2.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const extendf = @import("./extendf.zig").extendf; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__extendsftf2, .{ .name = "__extendsfkf2", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_stoq, .{ .name = "_Qp_stoq", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__extendsftf2, .{ .name = "__extendsftf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __extendsftf2(a: f32) callconv(.c) f128 { + return extendf(f128, f32, @as(u32, @bitCast(a))); +} + +fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void { + c.* = extendf(f128, f32, @as(u32, @bitCast(a))); +} diff --git a/build/compiler_rt/extendsfxf2.zig b/build/compiler_rt/extendsfxf2.zig new file mode 100644 index 00000000..b883034d --- /dev/null +++ b/build/compiler_rt/extendsfxf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const extend_f80 = @import("./extendf.zig").extend_f80; + +pub const panic = common.panic; + +comptime { + @export(&__extendsfxf2, .{ .name = "__extendsfxf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __extendsfxf2(a: f32) callconv(.c) f80 { + return extend_f80(f32, @as(u32, @bitCast(a))); +} diff --git a/build/compiler_rt/extendxftf2.zig b/build/compiler_rt/extendxftf2.zig new file mode 100644 index 00000000..39d66d39 --- /dev/null +++ b/build/compiler_rt/extendxftf2.zig @@ -0,0 +1,43 @@ +const std = @import("std"); +const common = @import("./common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__extendxftf2, .{ .name = "__extendxftf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __extendxftf2(a: f80) callconv(.c) f128 { + const src_int_bit: u64 = 0x8000000000000000; + const src_sig_mask = ~src_int_bit; + const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit + const dst_sig_bits = std.math.floatMantissaBits(f128); + + const dst_bits = @bitSizeOf(f128); + + // Break a into a sign and representation of the absolute value + var a_rep = std.math.F80.fromFloat(a); + const sign = a_rep.exp & 0x8000; + a_rep.exp &= 0x7FFF; + var abs_result: u128 = undefined; + + if (a_rep.exp == 0 and a_rep.fraction == 0) { + // zero + abs_result = 0; + } else if (a_rep.exp == 0x7FFF) { + // a is nan or infinite + abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); + abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; + } else if (a_rep.fraction & src_int_bit != 0) { + // a is a normal value + abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits); + abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; + } else { + // a is denormal + abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); + } + + // Apply the signbit to (dst_t)abs(a). + const result: u128 align(@alignOf(f128)) = abs_result | @as(u128, sign) << (dst_bits - 16); + return @bitCast(result); +} diff --git a/build/compiler_rt/fabs.zig b/build/compiler_rt/fabs.zig new file mode 100644 index 00000000..31c6cb97 --- /dev/null +++ b/build/compiler_rt/fabs.zig @@ -0,0 +1,57 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__fabsh, .{ .name = "__fabsh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fabsf, .{ .name = "fabsf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fabs, .{ .name = "fabs", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__fabsx, .{ .name = "__fabsx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&fabsq, .{ .name = "fabsf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&fabsq, .{ .name = "fabsq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fabsl, .{ .name = "fabsl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fabsh(a: f16) callconv(.c) f16 { + return generic_fabs(a); +} + +pub fn fabsf(a: f32) callconv(.c) f32 { + return generic_fabs(a); +} + +pub fn fabs(a: f64) callconv(.c) f64 { + return generic_fabs(a); +} + +pub fn __fabsx(a: f80) callconv(.c) f80 { + return generic_fabs(a); +} + +pub fn fabsq(a: f128) callconv(.c) f128 { + return generic_fabs(a); +} + +pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __fabsh(x), + 32 => return fabsf(x), + 64 => return fabs(x), + 80 => return __fabsx(x), + 128 => return fabsq(x), + else => @compileError("unreachable"), + } +} + +inline fn generic_fabs(x: anytype) @TypeOf(x) { + const T = @TypeOf(x); + const TBits = std.meta.Int(.unsigned, @typeInfo(T).float.bits); + const float_bits: TBits = @bitCast(x); + const remove_sign = ~@as(TBits, 0) >> 1; + return @bitCast(float_bits & remove_sign); +} diff --git a/build/compiler_rt/ffsdi2_test.zig b/build/compiler_rt/ffsdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/ffssi2_test.zig b/build/compiler_rt/ffssi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/ffsti2_test.zig b/build/compiler_rt/ffsti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/fixdfdi.zig b/build/compiler_rt/fixdfdi.zig new file mode 100644 index 00000000..50eb7888 --- /dev/null +++ b/build/compiler_rt/fixdfdi.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_d2lz, .{ .name = "__aeabi_d2lz", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixdfdi, .{ .name = if (common.want_windows_arm_abi) "__dtoi64" else "__fixdfdi", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixdfdi(a: f64) callconv(.c) i64 { + return intFromFloat(i64, a); +} + +fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { + return intFromFloat(i64, a); +} diff --git a/build/compiler_rt/fixdfei.zig b/build/compiler_rt/fixdfei.zig new file mode 100644 index 00000000..31c7994c --- /dev/null +++ b/build/compiler_rt/fixdfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixdfei, .{ .name = "__fixdfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixdfsi.zig b/build/compiler_rt/fixdfsi.zig new file mode 100644 index 00000000..5076cdc4 --- /dev/null +++ b/build/compiler_rt/fixdfsi.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_d2iz, .{ .name = "__aeabi_d2iz", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixdfsi, .{ .name = "__fixdfsi", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixdfsi(a: f64) callconv(.c) i32 { + return intFromFloat(i32, a); +} + +fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return intFromFloat(i32, a); +} diff --git a/build/compiler_rt/fixdfti.zig b/build/compiler_rt/fixdfti.zig new file mode 100644 index 00000000..46b17505 --- /dev/null +++ b/build/compiler_rt/fixdfti.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixdfti_windows_x86_64, .{ .name = "__fixdfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixdfti, .{ .name = "__fixdfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixdfti(a: f64) callconv(.c) i128 { + return intFromFloat(i128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixdfti_windows_x86_64(a: f64) callconv(.c) v2u64 { + return @bitCast(intFromFloat(i128, a)); +} diff --git a/build/compiler_rt/fixhfdi.zig b/build/compiler_rt/fixhfdi.zig new file mode 100644 index 00000000..154bb501 --- /dev/null +++ b/build/compiler_rt/fixhfdi.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixhfdi, .{ .name = "__fixhfdi", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __fixhfdi(a: f16) callconv(.c) i64 { + return intFromFloat(i64, a); +} diff --git a/build/compiler_rt/fixhfei.zig b/build/compiler_rt/fixhfei.zig new file mode 100644 index 00000000..c7f30055 --- /dev/null +++ b/build/compiler_rt/fixhfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixhfei, .{ .name = "__fixhfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixhfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixhfsi.zig b/build/compiler_rt/fixhfsi.zig new file mode 100644 index 00000000..253e7b64 --- /dev/null +++ b/build/compiler_rt/fixhfsi.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixhfsi, .{ .name = "__fixhfsi", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __fixhfsi(a: f16) callconv(.c) i32 { + return intFromFloat(i32, a); +} diff --git a/build/compiler_rt/fixhfti.zig b/build/compiler_rt/fixhfti.zig new file mode 100644 index 00000000..01586578 --- /dev/null +++ b/build/compiler_rt/fixhfti.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixhfti_windows_x86_64, .{ .name = "__fixhfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixhfti, .{ .name = "__fixhfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixhfti(a: f16) callconv(.c) i128 { + return intFromFloat(i128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixhfti_windows_x86_64(a: f16) callconv(.c) v2u64 { + return @bitCast(intFromFloat(i128, a)); +} diff --git a/build/compiler_rt/fixint_test.zig b/build/compiler_rt/fixint_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/fixsfdi.zig b/build/compiler_rt/fixsfdi.zig new file mode 100644 index 00000000..877e7a6d --- /dev/null +++ b/build/compiler_rt/fixsfdi.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_f2lz, .{ .name = "__aeabi_f2lz", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixsfdi, .{ .name = if (common.want_windows_arm_abi) "__stoi64" else "__fixsfdi", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixsfdi(a: f32) callconv(.c) i64 { + return intFromFloat(i64, a); +} + +fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { + return intFromFloat(i64, a); +} diff --git a/build/compiler_rt/fixsfei.zig b/build/compiler_rt/fixsfei.zig new file mode 100644 index 00000000..c72e002f --- /dev/null +++ b/build/compiler_rt/fixsfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixsfei, .{ .name = "__fixsfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixsfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixsfsi.zig b/build/compiler_rt/fixsfsi.zig new file mode 100644 index 00000000..fb83d692 --- /dev/null +++ b/build/compiler_rt/fixsfsi.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_f2iz, .{ .name = "__aeabi_f2iz", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixsfsi, .{ .name = "__fixsfsi", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixsfsi(a: f32) callconv(.c) i32 { + return intFromFloat(i32, a); +} + +fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return intFromFloat(i32, a); +} diff --git a/build/compiler_rt/fixsfti.zig b/build/compiler_rt/fixsfti.zig new file mode 100644 index 00000000..e1d4e718 --- /dev/null +++ b/build/compiler_rt/fixsfti.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixsfti_windows_x86_64, .{ .name = "__fixsfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixsfti, .{ .name = "__fixsfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixsfti(a: f32) callconv(.c) i128 { + return intFromFloat(i128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixsfti_windows_x86_64(a: f32) callconv(.c) v2u64 { + return @bitCast(intFromFloat(i128, a)); +} diff --git a/build/compiler_rt/fixtfdi.zig b/build/compiler_rt/fixtfdi.zig new file mode 100644 index 00000000..ebb7484c --- /dev/null +++ b/build/compiler_rt/fixtfdi.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__fixtfdi, .{ .name = "__fixkfdi", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_qtox, .{ .name = "_Qp_qtox", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__fixtfdi, .{ .name = "__fixtfdi", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixtfdi(a: f128) callconv(.c) i64 { + return intFromFloat(i64, a); +} + +fn _Qp_qtox(a: *const f128) callconv(.c) i64 { + return intFromFloat(i64, a.*); +} diff --git a/build/compiler_rt/fixtfei.zig b/build/compiler_rt/fixtfei.zig new file mode 100644 index 00000000..8daf3754 --- /dev/null +++ b/build/compiler_rt/fixtfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixtfei, .{ .name = "__fixtfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixtfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixtfsi.zig b/build/compiler_rt/fixtfsi.zig new file mode 100644 index 00000000..a6d2daf0 --- /dev/null +++ b/build/compiler_rt/fixtfsi.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__fixtfsi, .{ .name = "__fixkfsi", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_qtoi, .{ .name = "_Qp_qtoi", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__fixtfsi, .{ .name = "__fixtfsi", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixtfsi(a: f128) callconv(.c) i32 { + return intFromFloat(i32, a); +} + +fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { + return intFromFloat(i32, a.*); +} diff --git a/build/compiler_rt/fixtfti.zig b/build/compiler_rt/fixtfti.zig new file mode 100644 index 00000000..44f88e8d --- /dev/null +++ b/build/compiler_rt/fixtfti.zig @@ -0,0 +1,25 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixtfti_windows_x86_64, .{ .name = "__fixtfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + if (common.want_ppc_abi) + @export(&__fixtfti, .{ .name = "__fixkfti", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__fixtfti, .{ .name = "__fixtfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixtfti(a: f128) callconv(.c) i128 { + return intFromFloat(i128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixtfti_windows_x86_64(a: f128) callconv(.c) v2u64 { + return @bitCast(intFromFloat(i128, a)); +} diff --git a/build/compiler_rt/fixunsdfdi.zig b/build/compiler_rt/fixunsdfdi.zig new file mode 100644 index 00000000..e25a194b --- /dev/null +++ b/build/compiler_rt/fixunsdfdi.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_d2ulz, .{ .name = "__aeabi_d2ulz", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixunsdfdi, .{ .name = if (common.want_windows_arm_abi) "__dtou64" else "__fixunsdfdi", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunsdfdi(a: f64) callconv(.c) u64 { + return intFromFloat(u64, a); +} + +fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { + return intFromFloat(u64, a); +} diff --git a/build/compiler_rt/fixunsdfei.zig b/build/compiler_rt/fixunsdfei.zig new file mode 100644 index 00000000..886feab6 --- /dev/null +++ b/build/compiler_rt/fixunsdfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunsdfei, .{ .name = "__fixunsdfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixunsdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixunsdfsi.zig b/build/compiler_rt/fixunsdfsi.zig new file mode 100644 index 00000000..246cbf97 --- /dev/null +++ b/build/compiler_rt/fixunsdfsi.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_d2uiz, .{ .name = "__aeabi_d2uiz", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixunsdfsi, .{ .name = "__fixunsdfsi", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunsdfsi(a: f64) callconv(.c) u32 { + return intFromFloat(u32, a); +} + +fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { + return intFromFloat(u32, a); +} diff --git a/build/compiler_rt/fixunsdfti.zig b/build/compiler_rt/fixunsdfti.zig new file mode 100644 index 00000000..b4429a9d --- /dev/null +++ b/build/compiler_rt/fixunsdfti.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixunsdfti_windows_x86_64, .{ .name = "__fixunsdfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunsdfti(a: f64) callconv(.c) u128 { + return intFromFloat(u128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixunsdfti_windows_x86_64(a: f64) callconv(.c) v2u64 { + return @bitCast(intFromFloat(u128, a)); +} diff --git a/build/compiler_rt/fixunshfdi.zig b/build/compiler_rt/fixunshfdi.zig new file mode 100644 index 00000000..dca13e17 --- /dev/null +++ b/build/compiler_rt/fixunshfdi.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunshfdi, .{ .name = "__fixunshfdi", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __fixunshfdi(a: f16) callconv(.c) u64 { + return intFromFloat(u64, a); +} diff --git a/build/compiler_rt/fixunshfei.zig b/build/compiler_rt/fixunshfei.zig new file mode 100644 index 00000000..788605a6 --- /dev/null +++ b/build/compiler_rt/fixunshfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunshfei, .{ .name = "__fixunshfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixunshfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixunshfsi.zig b/build/compiler_rt/fixunshfsi.zig new file mode 100644 index 00000000..27db8435 --- /dev/null +++ b/build/compiler_rt/fixunshfsi.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunshfsi, .{ .name = "__fixunshfsi", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __fixunshfsi(a: f16) callconv(.c) u32 { + return intFromFloat(u32, a); +} diff --git a/build/compiler_rt/fixunshfti.zig b/build/compiler_rt/fixunshfti.zig new file mode 100644 index 00000000..c9203921 --- /dev/null +++ b/build/compiler_rt/fixunshfti.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixunshfti_windows_x86_64, .{ .name = "__fixunshfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixunshfti, .{ .name = "__fixunshfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunshfti(a: f16) callconv(.c) u128 { + return intFromFloat(u128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixunshfti_windows_x86_64(a: f16) callconv(.c) v2u64 { + return @bitCast(intFromFloat(u128, a)); +} diff --git a/build/compiler_rt/fixunssfdi.zig b/build/compiler_rt/fixunssfdi.zig new file mode 100644 index 00000000..e8a206d7 --- /dev/null +++ b/build/compiler_rt/fixunssfdi.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_f2ulz, .{ .name = "__aeabi_f2ulz", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixunssfdi, .{ .name = if (common.want_windows_arm_abi) "__stou64" else "__fixunssfdi", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunssfdi(a: f32) callconv(.c) u64 { + return intFromFloat(u64, a); +} + +fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { + return intFromFloat(u64, a); +} diff --git a/build/compiler_rt/fixunssfei.zig b/build/compiler_rt/fixunssfei.zig new file mode 100644 index 00000000..bb89fc28 --- /dev/null +++ b/build/compiler_rt/fixunssfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunssfei, .{ .name = "__fixunssfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixunssfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixunssfsi.zig b/build/compiler_rt/fixunssfsi.zig new file mode 100644 index 00000000..d0038add --- /dev/null +++ b/build/compiler_rt/fixunssfsi.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_f2uiz, .{ .name = "__aeabi_f2uiz", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixunssfsi, .{ .name = "__fixunssfsi", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunssfsi(a: f32) callconv(.c) u32 { + return intFromFloat(u32, a); +} + +fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { + return intFromFloat(u32, a); +} diff --git a/build/compiler_rt/fixunssfti.zig b/build/compiler_rt/fixunssfti.zig new file mode 100644 index 00000000..3137fb3b --- /dev/null +++ b/build/compiler_rt/fixunssfti.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixunssfti_windows_x86_64, .{ .name = "__fixunssfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixunssfti, .{ .name = "__fixunssfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunssfti(a: f32) callconv(.c) u128 { + return intFromFloat(u128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixunssfti_windows_x86_64(a: f32) callconv(.c) v2u64 { + return @bitCast(intFromFloat(u128, a)); +} diff --git a/build/compiler_rt/fixunstfdi.zig b/build/compiler_rt/fixunstfdi.zig new file mode 100644 index 00000000..87a06bc3 --- /dev/null +++ b/build/compiler_rt/fixunstfdi.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__fixunstfdi, .{ .name = "__fixunskfdi", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_qtoux, .{ .name = "_Qp_qtoux", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__fixunstfdi, .{ .name = "__fixunstfdi", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixunstfdi(a: f128) callconv(.c) u64 { + return intFromFloat(u64, a); +} + +fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { + return intFromFloat(u64, a.*); +} diff --git a/build/compiler_rt/fixunstfei.zig b/build/compiler_rt/fixunstfei.zig new file mode 100644 index 00000000..997a100a --- /dev/null +++ b/build/compiler_rt/fixunstfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunstfei, .{ .name = "__fixunstfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixunstfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixunstfsi.zig b/build/compiler_rt/fixunstfsi.zig new file mode 100644 index 00000000..8a57e2db --- /dev/null +++ b/build/compiler_rt/fixunstfsi.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__fixunstfsi, .{ .name = "__fixunskfsi", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_qtoui, .{ .name = "_Qp_qtoui", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__fixunstfsi, .{ .name = "__fixunstfsi", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixunstfsi(a: f128) callconv(.c) u32 { + return intFromFloat(u32, a); +} + +fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { + return intFromFloat(u32, a.*); +} diff --git a/build/compiler_rt/fixunstfti.zig b/build/compiler_rt/fixunstfti.zig new file mode 100644 index 00000000..2c182e3a --- /dev/null +++ b/build/compiler_rt/fixunstfti.zig @@ -0,0 +1,25 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixunstfti_windows_x86_64, .{ .name = "__fixunstfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + if (common.want_ppc_abi) + @export(&__fixunstfti, .{ .name = "__fixunskfti", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__fixunstfti, .{ .name = "__fixunstfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunstfti(a: f128) callconv(.c) u128 { + return intFromFloat(u128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixunstfti_windows_x86_64(a: f128) callconv(.c) v2u64 { + return @bitCast(intFromFloat(u128, a)); +} diff --git a/build/compiler_rt/fixunsxfdi.zig b/build/compiler_rt/fixunsxfdi.zig new file mode 100644 index 00000000..1e10786f --- /dev/null +++ b/build/compiler_rt/fixunsxfdi.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunsxfdi, .{ .name = "__fixunsxfdi", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __fixunsxfdi(a: f80) callconv(.c) u64 { + return intFromFloat(u64, a); +} diff --git a/build/compiler_rt/fixunsxfei.zig b/build/compiler_rt/fixunsxfei.zig new file mode 100644 index 00000000..88c7f182 --- /dev/null +++ b/build/compiler_rt/fixunsxfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunsxfei, .{ .name = "__fixunsxfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixunsxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixunsxfsi.zig b/build/compiler_rt/fixunsxfsi.zig new file mode 100644 index 00000000..c876ea0d --- /dev/null +++ b/build/compiler_rt/fixunsxfsi.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixunsxfsi, .{ .name = "__fixunsxfsi", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __fixunsxfsi(a: f80) callconv(.c) u32 { + return intFromFloat(u32, a); +} diff --git a/build/compiler_rt/fixunsxfti.zig b/build/compiler_rt/fixunsxfti.zig new file mode 100644 index 00000000..bfe8a2c6 --- /dev/null +++ b/build/compiler_rt/fixunsxfti.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixunsxfti_windows_x86_64, .{ .name = "__fixunsxfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixunsxfti, .{ .name = "__fixunsxfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixunsxfti(a: f80) callconv(.c) u128 { + return intFromFloat(u128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixunsxfti_windows_x86_64(a: f80) callconv(.c) v2u64 { + return @bitCast(intFromFloat(u128, a)); +} diff --git a/build/compiler_rt/fixxfdi.zig b/build/compiler_rt/fixxfdi.zig new file mode 100644 index 00000000..2477a4bb --- /dev/null +++ b/build/compiler_rt/fixxfdi.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixxfdi, .{ .name = "__fixxfdi", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __fixxfdi(a: f80) callconv(.c) i64 { + return intFromFloat(i64, a); +} diff --git a/build/compiler_rt/fixxfei.zig b/build/compiler_rt/fixxfei.zig new file mode 100644 index 00000000..6f28153a --- /dev/null +++ b/build/compiler_rt/fixxfei.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixxfei, .{ .name = "__fixxfei", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fixxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); +} diff --git a/build/compiler_rt/fixxfsi.zig b/build/compiler_rt/fixxfsi.zig new file mode 100644 index 00000000..846df4d0 --- /dev/null +++ b/build/compiler_rt/fixxfsi.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + @export(&__fixxfsi, .{ .name = "__fixxfsi", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __fixxfsi(a: f80) callconv(.c) i32 { + return intFromFloat(i32, a); +} diff --git a/build/compiler_rt/fixxfti.zig b/build/compiler_rt/fixxfti.zig new file mode 100644 index 00000000..e1db47dc --- /dev/null +++ b/build/compiler_rt/fixxfti.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const intFromFloat = @import("./int_from_float.zig").intFromFloat; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__fixxfti_windows_x86_64, .{ .name = "__fixxfti", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__fixxfti, .{ .name = "__fixxfti", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __fixxfti(a: f80) callconv(.c) i128 { + return intFromFloat(i128, a); +} + +const v2u64 = @Vector(2, u64); + +fn __fixxfti_windows_x86_64(a: f80) callconv(.c) v2u64 { + return @bitCast(intFromFloat(i128, a)); +} diff --git a/build/compiler_rt/float_from_int.zig b/build/compiler_rt/float_from_int.zig new file mode 100644 index 00000000..98659d27 --- /dev/null +++ b/build/compiler_rt/float_from_int.zig @@ -0,0 +1,107 @@ +const std = @import("std"); +const Int = std.meta.Int; +const math = std.math; + +pub fn floatFromInt(comptime T: type, x: anytype) T { + if (x == 0) return 0; + + // Various constants whose values follow from the type parameters. + // Any reasonable optimizer will fold and propagate all of these. + const Z = Int(.unsigned, @bitSizeOf(@TypeOf(x))); + const uT = Int(.unsigned, @bitSizeOf(T)); + const inf = math.inf(T); + const float_bits = @bitSizeOf(T); + const int_bits = @bitSizeOf(@TypeOf(x)); + const exp_bits = math.floatExponentBits(T); + const fractional_bits = math.floatFractionalBits(T); + const exp_bias = math.maxInt(Int(.unsigned, exp_bits - 1)); + const implicit_bit = if (T != f80) @as(uT, 1) << fractional_bits else 0; + const max_exp = exp_bias; + + // Sign + const abs_val = @abs(x); + const sign_bit = if (x < 0) @as(uT, 1) << (float_bits - 1) else 0; + var result: uT = sign_bit; + + // Compute significand + const exp = int_bits - @clz(abs_val) - 1; + if (int_bits <= fractional_bits or exp <= fractional_bits) { + const shift_amt = fractional_bits - @as(math.Log2Int(uT), @intCast(exp)); + + // Shift up result to line up with the significand - no rounding required + result = @as(uT, @intCast(abs_val)) << shift_amt; + result ^= implicit_bit; // Remove implicit integer bit + } else { + const shift_amt: math.Log2Int(Z) = @intCast(exp - fractional_bits); + const exact_tie: bool = @ctz(abs_val) == shift_amt - 1; + + // Shift down result and remove implicit integer bit + result = @as(uT, @intCast((abs_val >> (shift_amt - 1)))) ^ (implicit_bit << 1); + + // Round result, including round-to-even for exact ties + result = ((result + 1) >> 1) & ~@as(uT, @intFromBool(exact_tie)); + } + + // Compute exponent + if ((int_bits > max_exp) and (exp > max_exp)) // If exponent too large, overflow to infinity + return @bitCast(sign_bit | @as(uT, @bitCast(inf))); + + result += (@as(uT, exp) + exp_bias) << math.floatMantissaBits(T); + + // If the result included a carry, we need to restore the explicit integer bit + if (T == f80) result |= 1 << fractional_bits; + + return @bitCast(sign_bit | result); +} + +const endian = @import("builtin").cpu.arch.endian(); +inline fn limb(limbs: []const u32, index: usize) u32 { + return switch (endian) { + .little => limbs[index], + .big => limbs[limbs.len - 1 - index], + }; +} + +pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin.Signedness, x: []const u32) T { + switch (x.len) { + 0 => return 0, + inline 1...4 => |limbs_len| return @floatFromInt(@as( + @Type(.{ .int = .{ .signedness = signedness, .bits = 32 * limbs_len } }), + @bitCast(x[0..limbs_len].*), + )), + else => {}, + } + + // sign implicit fraction round sticky + const I = comptime @Type(.{ .int = .{ + .signedness = signedness, + .bits = @as(u16, @intFromBool(signedness == .signed)) + 1 + math.floatFractionalBits(T) + 1 + 1, + } }); + + const clrsb = clrsb: { + var clsb: usize = 0; + const sign_bits: u32 = switch (signedness) { + .signed => @bitCast(@as(i32, @bitCast(limb(x, x.len - 1))) >> 31), + .unsigned => 0, + }; + for (0..x.len) |limb_index| { + const l = limb(x, x.len - 1 - limb_index) ^ sign_bits; + clsb += @clz(l); + if (l != 0) break; + } + break :clrsb clsb - @intFromBool(signedness == .signed); + }; + const active_bits = 32 * x.len - clrsb; + const exponent = active_bits -| @bitSizeOf(I); + const exponent_limb = exponent / 32; + const sticky = for (0..exponent_limb) |limb_index| { + if (limb(x, limb_index) != 0) break true; + } else limb(x, exponent_limb) & ((@as(u32, 1) << @truncate(exponent)) - 1) != 0; + return math.ldexp(@as(T, @floatFromInt( + std.mem.readPackedIntNative(I, std.mem.sliceAsBytes(x), exponent) | @intFromBool(sticky), + )), @intCast(exponent)); +} + +test { + _ = @import("float_from_int_test.zig"); +} diff --git a/build/compiler_rt/float_from_int_test.zig b/build/compiler_rt/float_from_int_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/floatdidf.zig b/build/compiler_rt/floatdidf.zig new file mode 100644 index 00000000..50b6fc1a --- /dev/null +++ b/build/compiler_rt/floatdidf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatdidf, .{ .name = if (common.want_windows_arm_abi) "__i64tod" else "__floatdidf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatdidf(a: i64) callconv(.c) f64 { + return floatFromInt(f64, a); +} + +fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 { + return floatFromInt(f64, a); +} diff --git a/build/compiler_rt/floatdihf.zig b/build/compiler_rt/floatdihf.zig new file mode 100644 index 00000000..37a03e4e --- /dev/null +++ b/build/compiler_rt/floatdihf.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatdihf, .{ .name = "__floatdihf", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __floatdihf(a: i64) callconv(.c) f16 { + return floatFromInt(f16, a); +} diff --git a/build/compiler_rt/floatdisf.zig b/build/compiler_rt/floatdisf.zig new file mode 100644 index 00000000..54f57cc3 --- /dev/null +++ b/build/compiler_rt/floatdisf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_l2f, .{ .name = "__aeabi_l2f", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatdisf, .{ .name = if (common.want_windows_arm_abi) "__i64tos" else "__floatdisf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatdisf(a: i64) callconv(.c) f32 { + return floatFromInt(f32, a); +} + +fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 { + return floatFromInt(f32, a); +} diff --git a/build/compiler_rt/floatditf.zig b/build/compiler_rt/floatditf.zig new file mode 100644 index 00000000..b5cc262f --- /dev/null +++ b/build/compiler_rt/floatditf.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__floatditf, .{ .name = "__floatdikf", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_xtoq, .{ .name = "_Qp_xtoq", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__floatditf, .{ .name = "__floatditf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatditf(a: i64) callconv(.c) f128 { + return floatFromInt(f128, a); +} + +fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void { + c.* = floatFromInt(f128, a); +} diff --git a/build/compiler_rt/floatdixf.zig b/build/compiler_rt/floatdixf.zig new file mode 100644 index 00000000..eba666c0 --- /dev/null +++ b/build/compiler_rt/floatdixf.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatdixf, .{ .name = "__floatdixf", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __floatdixf(a: i64) callconv(.c) f80 { + return floatFromInt(f80, a); +} diff --git a/build/compiler_rt/floateidf.zig b/build/compiler_rt/floateidf.zig new file mode 100644 index 00000000..96411ae8 --- /dev/null +++ b/build/compiler_rt/floateidf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floateidf, .{ .name = "__floateidf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) f64 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floateihf.zig b/build/compiler_rt/floateihf.zig new file mode 100644 index 00000000..ac9fd355 --- /dev/null +++ b/build/compiler_rt/floateihf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floateihf, .{ .name = "__floateihf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) f16 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floateisf.zig b/build/compiler_rt/floateisf.zig new file mode 100644 index 00000000..f53b7564 --- /dev/null +++ b/build/compiler_rt/floateisf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floateisf, .{ .name = "__floateisf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) f32 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floateitf.zig b/build/compiler_rt/floateitf.zig new file mode 100644 index 00000000..3e07c6be --- /dev/null +++ b/build/compiler_rt/floateitf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floateitf, .{ .name = "__floateitf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) f128 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floateixf.zig b/build/compiler_rt/floateixf.zig new file mode 100644 index 00000000..65585e2e --- /dev/null +++ b/build/compiler_rt/floateixf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floateixf, .{ .name = "__floateixf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) f80 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floatsidf.zig b/build/compiler_rt/floatsidf.zig new file mode 100644 index 00000000..c3f249a4 --- /dev/null +++ b/build/compiler_rt/floatsidf.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatsidf, .{ .name = "__floatsidf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatsidf(a: i32) callconv(.c) f64 { + return floatFromInt(f64, a); +} + +fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 { + return floatFromInt(f64, a); +} diff --git a/build/compiler_rt/floatsihf.zig b/build/compiler_rt/floatsihf.zig new file mode 100644 index 00000000..a5d5d2ba --- /dev/null +++ b/build/compiler_rt/floatsihf.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatsihf, .{ .name = "__floatsihf", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __floatsihf(a: i32) callconv(.c) f16 { + return floatFromInt(f16, a); +} diff --git a/build/compiler_rt/floatsisf.zig b/build/compiler_rt/floatsisf.zig new file mode 100644 index 00000000..133bfaab --- /dev/null +++ b/build/compiler_rt/floatsisf.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_i2f, .{ .name = "__aeabi_i2f", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatsisf, .{ .name = "__floatsisf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatsisf(a: i32) callconv(.c) f32 { + return floatFromInt(f32, a); +} + +fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 { + return floatFromInt(f32, a); +} diff --git a/build/compiler_rt/floatsitf.zig b/build/compiler_rt/floatsitf.zig new file mode 100644 index 00000000..6a5f81ae --- /dev/null +++ b/build/compiler_rt/floatsitf.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__floatsitf, .{ .name = "__floatsikf", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_itoq, .{ .name = "_Qp_itoq", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__floatsitf, .{ .name = "__floatsitf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatsitf(a: i32) callconv(.c) f128 { + return floatFromInt(f128, a); +} + +fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void { + c.* = floatFromInt(f128, a); +} diff --git a/build/compiler_rt/floatsixf.zig b/build/compiler_rt/floatsixf.zig new file mode 100644 index 00000000..31791eb9 --- /dev/null +++ b/build/compiler_rt/floatsixf.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatsixf, .{ .name = "__floatsixf", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __floatsixf(a: i32) callconv(.c) f80 { + return floatFromInt(f80, a); +} diff --git a/build/compiler_rt/floattidf.zig b/build/compiler_rt/floattidf.zig new file mode 100644 index 00000000..420ef9b2 --- /dev/null +++ b/build/compiler_rt/floattidf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floattidf_windows_x86_64, .{ .name = "__floattidf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floattidf, .{ .name = "__floattidf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floattidf(a: i128) callconv(.c) f64 { + return floatFromInt(f64, a); +} + +fn __floattidf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f64 { + return floatFromInt(f64, @as(i128, @bitCast(a))); +} diff --git a/build/compiler_rt/floattihf.zig b/build/compiler_rt/floattihf.zig new file mode 100644 index 00000000..63f079b3 --- /dev/null +++ b/build/compiler_rt/floattihf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floattihf_windows_x86_64, .{ .name = "__floattihf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floattihf, .{ .name = "__floattihf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floattihf(a: i128) callconv(.c) f16 { + return floatFromInt(f16, a); +} + +fn __floattihf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f16 { + return floatFromInt(f16, @as(i128, @bitCast(a))); +} diff --git a/build/compiler_rt/floattisf.zig b/build/compiler_rt/floattisf.zig new file mode 100644 index 00000000..284580c4 --- /dev/null +++ b/build/compiler_rt/floattisf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floattisf_windows_x86_64, .{ .name = "__floattisf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floattisf, .{ .name = "__floattisf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floattisf(a: i128) callconv(.c) f32 { + return floatFromInt(f32, a); +} + +fn __floattisf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f32 { + return floatFromInt(f32, @as(i128, @bitCast(a))); +} diff --git a/build/compiler_rt/floattitf.zig b/build/compiler_rt/floattitf.zig new file mode 100644 index 00000000..c8d20904 --- /dev/null +++ b/build/compiler_rt/floattitf.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floattitf_windows_x86_64, .{ .name = "__floattitf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + if (common.want_ppc_abi) + @export(&__floattitf, .{ .name = "__floattikf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__floattitf, .{ .name = "__floattitf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floattitf(a: i128) callconv(.c) f128 { + return floatFromInt(f128, a); +} + +fn __floattitf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f128 { + return floatFromInt(f128, @as(i128, @bitCast(a))); +} diff --git a/build/compiler_rt/floattixf.zig b/build/compiler_rt/floattixf.zig new file mode 100644 index 00000000..ebf83446 --- /dev/null +++ b/build/compiler_rt/floattixf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floattixf_windows_x86_64, .{ .name = "__floattixf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floattixf, .{ .name = "__floattixf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floattixf(a: i128) callconv(.c) f80 { + return floatFromInt(f80, a); +} + +fn __floattixf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f80 { + return floatFromInt(f80, @as(i128, @bitCast(a))); +} diff --git a/build/compiler_rt/floatundidf.zig b/build/compiler_rt/floatundidf.zig new file mode 100644 index 00000000..2aa1c959 --- /dev/null +++ b/build/compiler_rt/floatundidf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatundidf, .{ .name = if (common.want_windows_arm_abi) "__u64tod" else "__floatundidf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatundidf(a: u64) callconv(.c) f64 { + return floatFromInt(f64, a); +} + +fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 { + return floatFromInt(f64, a); +} diff --git a/build/compiler_rt/floatundihf.zig b/build/compiler_rt/floatundihf.zig new file mode 100644 index 00000000..5fefedec --- /dev/null +++ b/build/compiler_rt/floatundihf.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatundihf, .{ .name = "__floatundihf", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __floatundihf(a: u64) callconv(.c) f16 { + return floatFromInt(f16, a); +} diff --git a/build/compiler_rt/floatundisf.zig b/build/compiler_rt/floatundisf.zig new file mode 100644 index 00000000..3f5b01a4 --- /dev/null +++ b/build/compiler_rt/floatundisf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_ul2f, .{ .name = "__aeabi_ul2f", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatundisf, .{ .name = if (common.want_windows_arm_abi) "__u64tos" else "__floatundisf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatundisf(a: u64) callconv(.c) f32 { + return floatFromInt(f32, a); +} + +fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 { + return floatFromInt(f32, a); +} diff --git a/build/compiler_rt/floatunditf.zig b/build/compiler_rt/floatunditf.zig new file mode 100644 index 00000000..aadb2513 --- /dev/null +++ b/build/compiler_rt/floatunditf.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__floatunditf, .{ .name = "__floatundikf", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_uxtoq, .{ .name = "_Qp_uxtoq", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__floatunditf, .{ .name = "__floatunditf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatunditf(a: u64) callconv(.c) f128 { + return floatFromInt(f128, a); +} + +fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void { + c.* = floatFromInt(f128, a); +} diff --git a/build/compiler_rt/floatundixf.zig b/build/compiler_rt/floatundixf.zig new file mode 100644 index 00000000..7f801fd6 --- /dev/null +++ b/build/compiler_rt/floatundixf.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatundixf, .{ .name = "__floatundixf", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __floatundixf(a: u64) callconv(.c) f80 { + return floatFromInt(f80, a); +} diff --git a/build/compiler_rt/floatuneidf.zig b/build/compiler_rt/floatuneidf.zig new file mode 100644 index 00000000..c7b1e032 --- /dev/null +++ b/build/compiler_rt/floatuneidf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatuneidf, .{ .name = "__floatuneidf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) f64 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floatuneihf.zig b/build/compiler_rt/floatuneihf.zig new file mode 100644 index 00000000..00c53a19 --- /dev/null +++ b/build/compiler_rt/floatuneihf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatuneihf, .{ .name = "__floatuneihf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) f16 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floatuneisf.zig b/build/compiler_rt/floatuneisf.zig new file mode 100644 index 00000000..4acb0fa7 --- /dev/null +++ b/build/compiler_rt/floatuneisf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatuneisf, .{ .name = "__floatuneisf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) f32 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floatuneitf.zig b/build/compiler_rt/floatuneitf.zig new file mode 100644 index 00000000..323f4461 --- /dev/null +++ b/build/compiler_rt/floatuneitf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatuneitf, .{ .name = "__floatuneitf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) f128 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floatuneixf.zig b/build/compiler_rt/floatuneixf.zig new file mode 100644 index 00000000..12157d20 --- /dev/null +++ b/build/compiler_rt/floatuneixf.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatuneixf, .{ .name = "__floatuneixf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) f80 { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); +} diff --git a/build/compiler_rt/floatunsidf.zig b/build/compiler_rt/floatunsidf.zig new file mode 100644 index 00000000..c712428c --- /dev/null +++ b/build/compiler_rt/floatunsidf.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_ui2d, .{ .name = "__aeabi_ui2d", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatunsidf, .{ .name = "__floatunsidf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatunsidf(a: u32) callconv(.c) f64 { + return floatFromInt(f64, a); +} + +fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 { + return floatFromInt(f64, a); +} diff --git a/build/compiler_rt/floatunsihf.zig b/build/compiler_rt/floatunsihf.zig new file mode 100644 index 00000000..5c5778a4 --- /dev/null +++ b/build/compiler_rt/floatunsihf.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatunsihf, .{ .name = "__floatunsihf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatunsihf(a: u32) callconv(.c) f16 { + return floatFromInt(f16, a); +} diff --git a/build/compiler_rt/floatunsisf.zig b/build/compiler_rt/floatunsisf.zig new file mode 100644 index 00000000..9fa213ed --- /dev/null +++ b/build/compiler_rt/floatunsisf.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_ui2f, .{ .name = "__aeabi_ui2f", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatunsisf, .{ .name = "__floatunsisf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatunsisf(a: u32) callconv(.c) f32 { + return floatFromInt(f32, a); +} + +fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 { + return floatFromInt(f32, a); +} diff --git a/build/compiler_rt/floatunsitf.zig b/build/compiler_rt/floatunsitf.zig new file mode 100644 index 00000000..d09d31d0 --- /dev/null +++ b/build/compiler_rt/floatunsitf.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__floatunsitf, .{ .name = "__floatunsikf", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_uitoq, .{ .name = "_Qp_uitoq", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__floatunsitf, .{ .name = "__floatunsitf", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floatunsitf(a: u32) callconv(.c) f128 { + return floatFromInt(f128, a); +} + +fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void { + c.* = floatFromInt(f128, a); +} diff --git a/build/compiler_rt/floatunsixf.zig b/build/compiler_rt/floatunsixf.zig new file mode 100644 index 00000000..678085ad --- /dev/null +++ b/build/compiler_rt/floatunsixf.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + @export(&__floatunsixf, .{ .name = "__floatunsixf", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __floatunsixf(a: u32) callconv(.c) f80 { + return floatFromInt(f80, a); +} diff --git a/build/compiler_rt/floatuntidf.zig b/build/compiler_rt/floatuntidf.zig new file mode 100644 index 00000000..cee154ed --- /dev/null +++ b/build/compiler_rt/floatuntidf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floatuntidf_windows_x86_64, .{ .name = "__floatuntidf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatuntidf, .{ .name = "__floatuntidf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatuntidf(a: u128) callconv(.c) f64 { + return floatFromInt(f64, a); +} + +fn __floatuntidf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f64 { + return floatFromInt(f64, @as(u128, @bitCast(a))); +} diff --git a/build/compiler_rt/floatuntihf.zig b/build/compiler_rt/floatuntihf.zig new file mode 100644 index 00000000..63cfdb60 --- /dev/null +++ b/build/compiler_rt/floatuntihf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floatuntihf_windows_x86_64, .{ .name = "__floatuntihf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatuntihf, .{ .name = "__floatuntihf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatuntihf(a: u128) callconv(.c) f16 { + return floatFromInt(f16, a); +} + +fn __floatuntihf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f16 { + return floatFromInt(f16, @as(u128, @bitCast(a))); +} diff --git a/build/compiler_rt/floatuntisf.zig b/build/compiler_rt/floatuntisf.zig new file mode 100644 index 00000000..1e65576f --- /dev/null +++ b/build/compiler_rt/floatuntisf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floatuntisf_windows_x86_64, .{ .name = "__floatuntisf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatuntisf, .{ .name = "__floatuntisf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatuntisf(a: u128) callconv(.c) f32 { + return floatFromInt(f32, a); +} + +fn __floatuntisf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f32 { + return floatFromInt(f32, @as(u128, @bitCast(a))); +} diff --git a/build/compiler_rt/floatuntitf.zig b/build/compiler_rt/floatuntitf.zig new file mode 100644 index 00000000..41c48bee --- /dev/null +++ b/build/compiler_rt/floatuntitf.zig @@ -0,0 +1,23 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floatuntitf_windows_x86_64, .{ .name = "__floatuntitf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + if (common.want_ppc_abi) + @export(&__floatuntitf, .{ .name = "__floatuntikf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__floatuntitf, .{ .name = "__floatuntitf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatuntitf(a: u128) callconv(.c) f128 { + return floatFromInt(f128, a); +} + +fn __floatuntitf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f128 { + return floatFromInt(f128, @as(u128, @bitCast(a))); +} diff --git a/build/compiler_rt/floatuntixf.zig b/build/compiler_rt/floatuntixf.zig new file mode 100644 index 00000000..353a3c3c --- /dev/null +++ b/build/compiler_rt/floatuntixf.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); +const floatFromInt = @import("./float_from_int.zig").floatFromInt; + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__floatuntixf_windows_x86_64, .{ .name = "__floatuntixf", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__floatuntixf, .{ .name = "__floatuntixf", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __floatuntixf(a: u128) callconv(.c) f80 { + return floatFromInt(f80, a); +} + +fn __floatuntixf_windows_x86_64(a: @Vector(2, u64)) callconv(.c) f80 { + return floatFromInt(f80, @as(u128, @bitCast(a))); +} diff --git a/build/compiler_rt/floor.zig b/build/compiler_rt/floor.zig new file mode 100644 index 00000000..ba186908 --- /dev/null +++ b/build/compiler_rt/floor.zig @@ -0,0 +1,238 @@ +//! Ported from musl, which is licensed under the MIT license: +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/floorf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/floor.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/floorl.c + +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__floorh, .{ .name = "__floorh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&floorf, .{ .name = "floorf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&floor, .{ .name = "floor", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__floorx, .{ .name = "__floorx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&floorq, .{ .name = "floorf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&floorq, .{ .name = "floorq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&floorl, .{ .name = "floorl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __floorh(x: f16) callconv(.c) f16 { + var u: u16 = @bitCast(x); + const e = @as(i16, @intCast((u >> 10) & 31)) - 15; + var m: u16 = undefined; + + if (e >= 10) return x; + + if (e >= 0) { + m = @as(u16, 0x03FF) >> @intCast(e); + if (u & m == 0) return x; + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120); + if (u >> 15 != 0) u += m; + return @bitCast(u & ~m); + } else { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120); + return if (u >> 15 == 0) 0.0 else if (u << 1 != 0) -1.0 else x; + } +} + +pub fn floorf(x: f32) callconv(.c) f32 { + var u: u32 = @bitCast(x); + const e = @as(i32, @intCast((u >> 23) & 0xFF)) - 0x7F; + var m: u32 = undefined; + + if (e >= 23) return x; + + if (e >= 0) { + m = @as(u32, 0x007FFFFF) >> @intCast(e); + if (u & m == 0) return x; + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120); + if (u >> 31 != 0) u += m; + return @bitCast(u & ~m); + } else { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120); + return if (u >> 31 == 0) 0.0 else if (u << 1 != 0) -1.0 else x; + } +} + +pub fn floor(x: f64) callconv(.c) f64 { + const f64_toint = 1.0 / math.floatEps(f64); + + const u: u64 = @bitCast(x); + const e = (u >> 52) & 0x7FF; + var y: f64 = undefined; + + if (e >= 0x3FF + 52 or x == 0) { + return x; + } + + if (u >> 63 != 0) { + y = x - f64_toint + f64_toint - x; + } else { + y = x + f64_toint - f64_toint - x; + } + + if (e <= 0x3FF - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(y); + if (u >> 63 != 0) { + return -1.0; + } else { + return 0.0; + } + } else if (y > 0) { + return x + y - 1; + } else { + return x + y; + } +} + +pub fn __floorx(x: f80) callconv(.c) f80 { + const f80_toint = 1.0 / math.floatEps(f80); + + const u: u80 = @bitCast(x); + const e = (u >> 64) & 0x7FFF; + var y: f80 = undefined; + + if (e >= 0x3FFF + 64 or x == 0) { + return x; + } + + if (u >> 79 != 0) { + y = x - f80_toint + f80_toint - x; + } else { + y = x + f80_toint - f80_toint - x; + } + + if (e <= 0x3FFF - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(y); + if (u >> 79 != 0) { + return -1.0; + } else { + return 0.0; + } + } else if (y > 0) { + return x + y - 1; + } else { + return x + y; + } +} + +pub fn floorq(x: f128) callconv(.c) f128 { + const f128_toint = 1.0 / math.floatEps(f128); + + const u: u128 = @bitCast(x); + const e = (u >> 112) & 0x7FFF; + var y: f128 = undefined; + + if (e >= 0x3FFF + 112 or x == 0) return x; + + if (u >> 127 != 0) { + y = x - f128_toint + f128_toint - x; + } else { + y = x + f128_toint - f128_toint - x; + } + + if (e <= 0x3FFF - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(y); + if (u >> 127 != 0) { + return -1.0; + } else { + return 0.0; + } + } else if (y > 0) { + return x + y - 1; + } else { + return x + y; + } +} + +pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __floorh(x), + 32 => return floorf(x), + 64 => return floor(x), + 80 => return __floorx(x), + 128 => return floorq(x), + else => @compileError("unreachable"), + } +} + +test "floor16" { + try expect(__floorh(1.3) == 1.0); + try expect(__floorh(-1.3) == -2.0); + try expect(__floorh(0.2) == 0.0); +} + +test "floor32" { + try expect(floorf(1.3) == 1.0); + try expect(floorf(-1.3) == -2.0); + try expect(floorf(0.2) == 0.0); +} + +test "floor64" { + try expect(floor(1.3) == 1.0); + try expect(floor(-1.3) == -2.0); + try expect(floor(0.2) == 0.0); +} + +test "floor80" { + try expect(__floorx(1.3) == 1.0); + try expect(__floorx(-1.3) == -2.0); + try expect(__floorx(0.2) == 0.0); +} + +test "floor128" { + try expect(floorq(1.3) == 1.0); + try expect(floorq(-1.3) == -2.0); + try expect(floorq(0.2) == 0.0); +} + +test "floor16.special" { + try expect(__floorh(0.0) == 0.0); + try expect(__floorh(-0.0) == -0.0); + try expect(math.isPositiveInf(__floorh(math.inf(f16)))); + try expect(math.isNegativeInf(__floorh(-math.inf(f16)))); + try expect(math.isNan(__floorh(math.nan(f16)))); +} + +test "floor32.special" { + try expect(floorf(0.0) == 0.0); + try expect(floorf(-0.0) == -0.0); + try expect(math.isPositiveInf(floorf(math.inf(f32)))); + try expect(math.isNegativeInf(floorf(-math.inf(f32)))); + try expect(math.isNan(floorf(math.nan(f32)))); +} + +test "floor64.special" { + try expect(floor(0.0) == 0.0); + try expect(floor(-0.0) == -0.0); + try expect(math.isPositiveInf(floor(math.inf(f64)))); + try expect(math.isNegativeInf(floor(-math.inf(f64)))); + try expect(math.isNan(floor(math.nan(f64)))); +} + +test "floor80.special" { + try expect(__floorx(0.0) == 0.0); + try expect(__floorx(-0.0) == -0.0); + try expect(math.isPositiveInf(__floorx(math.inf(f80)))); + try expect(math.isNegativeInf(__floorx(-math.inf(f80)))); + try expect(math.isNan(__floorx(math.nan(f80)))); +} + +test "floor128.special" { + try expect(floorq(0.0) == 0.0); + try expect(floorq(-0.0) == -0.0); + try expect(math.isPositiveInf(floorq(math.inf(f128)))); + try expect(math.isNegativeInf(floorq(-math.inf(f128)))); + try expect(math.isNan(floorq(math.nan(f128)))); +} diff --git a/build/compiler_rt/fma.zig b/build/compiler_rt/fma.zig new file mode 100644 index 00000000..79a120d5 --- /dev/null +++ b/build/compiler_rt/fma.zig @@ -0,0 +1,353 @@ +//! Ported from musl, which is MIT licensed: +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/fmal.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/fmaf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/fma.c + +const std = @import("std"); +const math = std.math; +const expect = std.testing.expect; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__fmah, .{ .name = "__fmah", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmaf, .{ .name = "fmaf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fma, .{ .name = "fma", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__fmax, .{ .name = "__fmax", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&fmaq, .{ .name = "fmaf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&fmaq, .{ .name = "fmaq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmal, .{ .name = "fmal", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fmah(x: f16, y: f16, z: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(fmaf(x, y, z)); +} + +pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { + const xy = @as(f64, x) * y; + const xy_z = xy + z; + const u = @as(u64, @bitCast(xy_z)); + const e = (u >> 52) & 0x7FF; + + if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or (xy_z - xy == z and xy_z - z == xy)) { + return @floatCast(xy_z); + } else { + // TODO: Handle inexact case with double-rounding + return @floatCast(xy_z); + } +} + +/// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately. +pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { + if (!math.isFinite(x) or !math.isFinite(y)) { + return x * y + z; + } + if (!math.isFinite(z)) { + return z; + } + if (x == 0.0 or y == 0.0) { + return x * y + z; + } + if (z == 0.0) { + return x * y; + } + + const x1 = math.frexp(x); + const ex = x1.exponent; + const xs = x1.significand; + const x2 = math.frexp(y); + const ey = x2.exponent; + const ys = x2.significand; + const x3 = math.frexp(z); + const ez = x3.exponent; + var zs = x3.significand; + + var spread = ex + ey - ez; + if (spread <= 53 * 2) { + zs = math.scalbn(zs, -spread); + } else { + zs = math.copysign(math.floatMin(f64), zs); + } + + const xy = dd_mul(xs, ys); + const r = dd_add(xy.hi, zs); + spread = ex + ey; + + if (r.hi == 0.0) { + return xy.hi + zs + math.scalbn(xy.lo, spread); + } + + const adj = add_adjusted(r.lo, xy.lo); + if (spread + math.ilogb(r.hi) > -1023) { + return math.scalbn(r.hi + adj, spread); + } else { + return add_and_denorm(r.hi, adj, spread); + } +} + +pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(fmaq(a, b, c)); +} + +/// Fused multiply-add: Compute x * y + z with a single rounding error. +/// +/// We use scaling to avoid overflow/underflow, along with the +/// canonical precision-doubling technique adapted from: +/// +/// Dekker, T. A Floating-Point Technique for Extending the +/// Available Precision. Numer. Math. 18, 224-242 (1971). +pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { + if (!math.isFinite(x) or !math.isFinite(y)) { + return x * y + z; + } + if (!math.isFinite(z)) { + return z; + } + if (x == 0.0 or y == 0.0) { + return x * y + z; + } + if (z == 0.0) { + return x * y; + } + + const x1 = math.frexp(x); + const ex = x1.exponent; + const xs = x1.significand; + const x2 = math.frexp(y); + const ey = x2.exponent; + const ys = x2.significand; + const x3 = math.frexp(z); + const ez = x3.exponent; + var zs = x3.significand; + + var spread = ex + ey - ez; + if (spread <= 113 * 2) { + zs = math.scalbn(zs, -spread); + } else { + zs = math.copysign(math.floatMin(f128), zs); + } + + const xy = dd_mul128(xs, ys); + const r = dd_add128(xy.hi, zs); + spread = ex + ey; + + if (r.hi == 0.0) { + return xy.hi + zs + math.scalbn(xy.lo, spread); + } + + const adj = add_adjusted128(r.lo, xy.lo); + if (spread + math.ilogb(r.hi) > -16383) { + return math.scalbn(r.hi + adj, spread); + } else { + return add_and_denorm128(r.hi, adj, spread); + } +} + +pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __fmah(x, y, z), + 32 => return fmaf(x, y, z), + 64 => return fma(x, y, z), + 80 => return __fmax(x, y, z), + 128 => return fmaq(x, y, z), + else => @compileError("unreachable"), + } +} + +const dd = struct { + hi: f64, + lo: f64, +}; + +fn dd_add(a: f64, b: f64) dd { + var ret: dd = undefined; + ret.hi = a + b; + const s = ret.hi - a; + ret.lo = (a - (ret.hi - s)) + (b - s); + return ret; +} + +fn dd_mul(a: f64, b: f64) dd { + var ret: dd = undefined; + const split: f64 = 0x1.0p27 + 1.0; + + var p = a * split; + var ha = a - p; + ha += p; + const la = a - ha; + + p = b * split; + var hb = b - p; + hb += p; + const lb = b - hb; + + p = ha * hb; + const q = ha * lb + la * hb; + + ret.hi = p + q; + ret.lo = p - ret.hi + q + la * lb; + return ret; +} + +fn add_adjusted(a: f64, b: f64) f64 { + var sum = dd_add(a, b); + if (sum.lo != 0) { + var uhii: u64 = @bitCast(sum.hi); + if (uhii & 1 == 0) { + // hibits += copysign(1.0, sum.hi, sum.lo) + const uloi: u64 = @bitCast(sum.lo); + uhii = uhii + 1 - ((uhii ^ uloi) >> 62); + sum.hi = @bitCast(uhii); + } + } + return sum.hi; +} + +fn add_and_denorm(a: f64, b: f64, scale: i32) f64 { + var sum = dd_add(a, b); + if (sum.lo != 0) { + var uhii: u64 = @bitCast(sum.hi); + const bits_lost = -@as(i32, @intCast((uhii >> 52) & 0x7FF)) - scale + 1; + if ((bits_lost != 1) == (uhii & 1 != 0)) { + const uloi: u64 = @bitCast(sum.lo); + uhii = uhii + 1 - (((uhii ^ uloi) >> 62) & 2); + sum.hi = @bitCast(uhii); + } + } + return math.scalbn(sum.hi, scale); +} + +/// A struct that represents a floating-point number with twice the precision +/// of f128. We maintain the invariant that "hi" stores the high-order +/// bits of the result. +const dd128 = struct { + hi: f128, + lo: f128, +}; + +/// Compute a+b exactly, returning the exact result in a struct dd. We assume +/// that both a and b are finite, but make no assumptions about their relative +/// magnitudes. +fn dd_add128(a: f128, b: f128) dd128 { + var ret: dd128 = undefined; + ret.hi = a + b; + const s = ret.hi - a; + ret.lo = (a - (ret.hi - s)) + (b - s); + return ret; +} + +/// Compute a+b, with a small tweak: The least significant bit of the +/// result is adjusted into a sticky bit summarizing all the bits that +/// were lost to rounding. This adjustment negates the effects of double +/// rounding when the result is added to another number with a higher +/// exponent. For an explanation of round and sticky bits, see any reference +/// on FPU design, e.g., +/// +/// J. Coonen. An Implementation Guide to a Proposed Standard for +/// Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. +fn add_adjusted128(a: f128, b: f128) f128 { + var sum = dd_add128(a, b); + if (sum.lo != 0) { + var uhii: u128 = @bitCast(sum.hi); + if (uhii & 1 == 0) { + // hibits += copysign(1.0, sum.hi, sum.lo) + const uloi: u128 = @bitCast(sum.lo); + uhii = uhii + 1 - ((uhii ^ uloi) >> 126); + sum.hi = @bitCast(uhii); + } + } + return sum.hi; +} + +/// Compute ldexp(a+b, scale) with a single rounding error. It is assumed +/// that the result will be subnormal, and care is taken to ensure that +/// double rounding does not occur. +fn add_and_denorm128(a: f128, b: f128, scale: i32) f128 { + var sum = dd_add128(a, b); + // If we are losing at least two bits of accuracy to denormalization, + // then the first lost bit becomes a round bit, and we adjust the + // lowest bit of sum.hi to make it a sticky bit summarizing all the + // bits in sum.lo. With the sticky bit adjusted, the hardware will + // break any ties in the correct direction. + // + // If we are losing only one bit to denormalization, however, we must + // break the ties manually. + if (sum.lo != 0) { + var uhii: u128 = @bitCast(sum.hi); + const bits_lost = -@as(i32, @intCast((uhii >> 112) & 0x7FFF)) - scale + 1; + if ((bits_lost != 1) == (uhii & 1 != 0)) { + const uloi: u128 = @bitCast(sum.lo); + uhii = uhii + 1 - (((uhii ^ uloi) >> 126) & 2); + sum.hi = @bitCast(uhii); + } + } + return math.scalbn(sum.hi, scale); +} + +/// Compute a*b exactly, returning the exact result in a struct dd. We assume +/// that both a and b are normalized, so no underflow or overflow will occur. +/// The current rounding mode must be round-to-nearest. +fn dd_mul128(a: f128, b: f128) dd128 { + var ret: dd128 = undefined; + const split: f128 = 0x1.0p57 + 1.0; + + var p = a * split; + var ha = a - p; + ha += p; + const la = a - ha; + + p = b * split; + var hb = b - p; + hb += p; + const lb = b - hb; + + p = ha * hb; + const q = ha * lb + la * hb; + + ret.hi = p + q; + ret.lo = p - ret.hi + q + la * lb; + return ret; +} + +test "32" { + const epsilon = 0.000001; + + try expect(math.approxEqAbs(f32, fmaf(0.0, 5.0, 9.124), 9.124, epsilon)); + try expect(math.approxEqAbs(f32, fmaf(0.2, 5.0, 9.124), 10.124, epsilon)); + try expect(math.approxEqAbs(f32, fmaf(0.8923, 5.0, 9.124), 13.5855, epsilon)); + try expect(math.approxEqAbs(f32, fmaf(1.5, 5.0, 9.124), 16.624, epsilon)); + try expect(math.approxEqAbs(f32, fmaf(37.45, 5.0, 9.124), 196.374004, epsilon)); + try expect(math.approxEqAbs(f32, fmaf(89.123, 5.0, 9.124), 454.739005, epsilon)); + try expect(math.approxEqAbs(f32, fmaf(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); +} + +test "64" { + const epsilon = 0.000001; + + try expect(math.approxEqAbs(f64, fma(0.0, 5.0, 9.124), 9.124, epsilon)); + try expect(math.approxEqAbs(f64, fma(0.2, 5.0, 9.124), 10.124, epsilon)); + try expect(math.approxEqAbs(f64, fma(0.8923, 5.0, 9.124), 13.5855, epsilon)); + try expect(math.approxEqAbs(f64, fma(1.5, 5.0, 9.124), 16.624, epsilon)); + try expect(math.approxEqAbs(f64, fma(37.45, 5.0, 9.124), 196.374, epsilon)); + try expect(math.approxEqAbs(f64, fma(89.123, 5.0, 9.124), 454.739, epsilon)); + try expect(math.approxEqAbs(f64, fma(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); +} + +test "128" { + const epsilon = 0.000001; + + try expect(math.approxEqAbs(f128, fmaq(0.0, 5.0, 9.124), 9.124, epsilon)); + try expect(math.approxEqAbs(f128, fmaq(0.2, 5.0, 9.124), 10.124, epsilon)); + try expect(math.approxEqAbs(f128, fmaq(0.8923, 5.0, 9.124), 13.5855, epsilon)); + try expect(math.approxEqAbs(f128, fmaq(1.5, 5.0, 9.124), 16.624, epsilon)); + try expect(math.approxEqAbs(f128, fmaq(37.45, 5.0, 9.124), 196.374, epsilon)); + try expect(math.approxEqAbs(f128, fmaq(89.123, 5.0, 9.124), 454.739, epsilon)); + try expect(math.approxEqAbs(f128, fmaq(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); +} diff --git a/build/compiler_rt/fmax.zig b/build/compiler_rt/fmax.zig new file mode 100644 index 00000000..02e7d1d7 --- /dev/null +++ b/build/compiler_rt/fmax.zig @@ -0,0 +1,77 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__fmaxh, .{ .name = "__fmaxh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmaxf, .{ .name = "fmaxf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmax, .{ .name = "fmax", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__fmaxx, .{ .name = "__fmaxx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&fmaxq, .{ .name = "fmaxf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&fmaxq, .{ .name = "fmaxq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmaxl, .{ .name = "fmaxl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fmaxh(x: f16, y: f16) callconv(.c) f16 { + return generic_fmax(f16, x, y); +} + +pub fn fmaxf(x: f32, y: f32) callconv(.c) f32 { + return generic_fmax(f32, x, y); +} + +pub fn fmax(x: f64, y: f64) callconv(.c) f64 { + return generic_fmax(f64, x, y); +} + +pub fn __fmaxx(x: f80, y: f80) callconv(.c) f80 { + return generic_fmax(f80, x, y); +} + +pub fn fmaxq(x: f128, y: f128) callconv(.c) f128 { + return generic_fmax(f128, x, y); +} + +pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __fmaxh(x, y), + 32 => return fmaxf(x, y), + 64 => return fmax(x, y), + 80 => return __fmaxx(x, y), + 128 => return fmaxq(x, y), + else => @compileError("unreachable"), + } +} + +inline fn generic_fmax(comptime T: type, x: T, y: T) T { + if (math.isNan(x)) + return y; + if (math.isNan(y)) + return x; + if (math.signbit(x) != math.signbit(y)) + return if (math.signbit(x)) y else x; + return if (x < y) y else x; +} + +test "generic_fmax" { + inline for ([_]type{ f32, f64, c_longdouble, f80, f128 }) |T| { + const nan_val = math.nan(T); + const Int = std.meta.Int(.unsigned, @bitSizeOf(T)); + + try std.testing.expect(math.isNan(generic_fmax(T, nan_val, nan_val))); + try std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, nan_val, 1.0)); + try std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, 1.0, nan_val)); + + try std.testing.expectEqual(@as(T, 10.0), generic_fmax(T, 1.0, 10.0)); + try std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, 1.0, -1.0)); + + try std.testing.expectEqual(@as(Int, @bitCast(@as(T, 0.0))), @as(Int, @bitCast(generic_fmax(T, 0.0, -0.0)))); + try std.testing.expectEqual(@as(Int, @bitCast(@as(T, 0.0))), @as(Int, @bitCast(generic_fmax(T, -0.0, 0.0)))); + } +} diff --git a/build/compiler_rt/fmin.zig b/build/compiler_rt/fmin.zig new file mode 100644 index 00000000..71f9ef58 --- /dev/null +++ b/build/compiler_rt/fmin.zig @@ -0,0 +1,77 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__fminh, .{ .name = "__fminh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fminf, .{ .name = "fminf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmin, .{ .name = "fmin", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__fminx, .{ .name = "__fminx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&fminq, .{ .name = "fminf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&fminq, .{ .name = "fminq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fminl, .{ .name = "fminl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fminh(x: f16, y: f16) callconv(.c) f16 { + return generic_fmin(f16, x, y); +} + +pub fn fminf(x: f32, y: f32) callconv(.c) f32 { + return generic_fmin(f32, x, y); +} + +pub fn fmin(x: f64, y: f64) callconv(.c) f64 { + return generic_fmin(f64, x, y); +} + +pub fn __fminx(x: f80, y: f80) callconv(.c) f80 { + return generic_fmin(f80, x, y); +} + +pub fn fminq(x: f128, y: f128) callconv(.c) f128 { + return generic_fmin(f128, x, y); +} + +pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __fminh(x, y), + 32 => return fminf(x, y), + 64 => return fmin(x, y), + 80 => return __fminx(x, y), + 128 => return fminq(x, y), + else => @compileError("unreachable"), + } +} + +inline fn generic_fmin(comptime T: type, x: T, y: T) T { + if (math.isNan(x)) + return y; + if (math.isNan(y)) + return x; + if (math.signbit(x) != math.signbit(y)) + return if (math.signbit(x)) x else y; + return if (x < y) x else y; +} + +test "generic_fmin" { + inline for ([_]type{ f32, f64, c_longdouble, f80, f128 }) |T| { + const nan_val = math.nan(T); + const Int = std.meta.Int(.unsigned, @bitSizeOf(T)); + + try std.testing.expect(math.isNan(generic_fmin(T, nan_val, nan_val))); + try std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, nan_val, 1.0)); + try std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, 1.0, nan_val)); + + try std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, 1.0, 10.0)); + try std.testing.expectEqual(@as(T, -1.0), generic_fmin(T, 1.0, -1.0)); + + try std.testing.expectEqual(@as(Int, @bitCast(@as(T, -0.0))), @as(Int, @bitCast(generic_fmin(T, 0.0, -0.0)))); + try std.testing.expectEqual(@as(Int, @bitCast(@as(T, -0.0))), @as(Int, @bitCast(generic_fmin(T, -0.0, 0.0)))); + } +} diff --git a/build/compiler_rt/fmod.zig b/build/compiler_rt/fmod.zig new file mode 100644 index 00000000..5c055049 --- /dev/null +++ b/build/compiler_rt/fmod.zig @@ -0,0 +1,389 @@ +const builtin = @import("builtin"); +const std = @import("std"); +const math = std.math; +const assert = std.debug.assert; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); +const normalize = common.normalize; + +pub const panic = common.panic; + +comptime { + @export(&__fmodh, .{ .name = "__fmodh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmodf, .{ .name = "fmodf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmod, .{ .name = "fmod", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__fmodx, .{ .name = "__fmodx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&fmodq, .{ .name = "fmodf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&fmodq, .{ .name = "fmodq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&fmodl, .{ .name = "fmodl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __fmodh(x: f16, y: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(fmodf(x, y)); +} + +pub fn fmodf(x: f32, y: f32) callconv(.c) f32 { + return generic_fmod(f32, x, y); +} + +pub fn fmod(x: f64, y: f64) callconv(.c) f64 { + return generic_fmod(f64, x, y); +} + +/// fmodx - floating modulo large, returns the remainder of division for f80 types +/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits +pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { + const T = f80; + const Z = std.meta.Int(.unsigned, @bitSizeOf(T)); + + const significandBits = math.floatMantissaBits(T); + const fractionalBits = math.floatFractionalBits(T); + const exponentBits = math.floatExponentBits(T); + + const signBit = (@as(Z, 1) << (significandBits + exponentBits)); + const maxExponent = ((1 << exponentBits) - 1); + + var aRep: Z = @bitCast(a); + var bRep: Z = @bitCast(b); + + const signA = aRep & signBit; + var expA: i32 = @intCast((@as(Z, @bitCast(a)) >> significandBits) & maxExponent); + var expB: i32 = @intCast((@as(Z, @bitCast(b)) >> significandBits) & maxExponent); + + // There are 3 cases where the answer is undefined, check for: + // - fmodx(val, 0) + // - fmodx(val, NaN) + // - fmodx(inf, val) + // The sign on checked values does not matter. + // Doing (a * b) / (a * b) produces undefined results + // because the three cases always produce undefined calculations: + // - 0 / 0 + // - val * NaN + // - inf / inf + if (b == 0 or math.isNan(b) or expA == maxExponent) { + return (a * b) / (a * b); + } + + // Remove the sign from both + aRep &= ~signBit; + bRep &= ~signBit; + if (aRep <= bRep) { + if (aRep == bRep) { + return 0 * a; + } + return a; + } + + if (expA == 0) expA = normalize(f80, &aRep); + if (expB == 0) expB = normalize(f80, &bRep); + + var highA: u64 = 0; + const highB: u64 = 0; + var lowA: u64 = @truncate(aRep); + const lowB: u64 = @truncate(bRep); + + while (expA > expB) : (expA -= 1) { + var high = highA -% highB; + const low = lowA -% lowB; + if (lowA < lowB) { + high -%= 1; + } + if (high >> 63 == 0) { + if ((high | low) == 0) { + return 0 * a; + } + highA = 2 *% high + (low >> 63); + lowA = 2 *% low; + } else { + highA = 2 *% highA + (lowA >> 63); + lowA = 2 *% lowA; + } + } + + var high = highA -% highB; + const low = lowA -% lowB; + if (lowA < lowB) { + high -%= 1; + } + if (high >> 63 == 0) { + if ((high | low) == 0) { + return 0 * a; + } + highA = high; + lowA = low; + } + + while ((lowA >> fractionalBits) == 0) { + lowA = 2 *% lowA; + expA = expA - 1; + } + + // Combine the exponent with the sign and significand, normalize if happened to be denormalized + if (expA < -fractionalBits) { + return @bitCast(signA); + } else if (expA <= 0) { + return @bitCast((lowA >> @intCast(1 - expA)) | signA); + } else { + return @bitCast(lowA | (@as(Z, @as(u16, @intCast(expA))) << significandBits) | signA); + } +} + +/// fmodq - floating modulo large, returns the remainder of division for f128 types +/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits +pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { + var amod = a; + var bmod = b; + const aPtr_u64: [*]u64 = @ptrCast(&amod); + const bPtr_u64: [*]u64 = @ptrCast(&bmod); + const aPtr_u16: [*]u16 = @ptrCast(&amod); + const bPtr_u16: [*]u16 = @ptrCast(&bmod); + + const exp_and_sign_index = comptime switch (builtin.target.cpu.arch.endian()) { + .little => 7, + .big => 0, + }; + const low_index = comptime switch (builtin.target.cpu.arch.endian()) { + .little => 0, + .big => 1, + }; + const high_index = comptime switch (builtin.target.cpu.arch.endian()) { + .little => 1, + .big => 0, + }; + + const signA = aPtr_u16[exp_and_sign_index] & 0x8000; + var expA: i32 = @intCast((aPtr_u16[exp_and_sign_index] & 0x7fff)); + var expB: i32 = @intCast((bPtr_u16[exp_and_sign_index] & 0x7fff)); + + // There are 3 cases where the answer is undefined, check for: + // - fmodq(val, 0) + // - fmodq(val, NaN) + // - fmodq(inf, val) + // The sign on checked values does not matter. + // Doing (a * b) / (a * b) produces undefined results + // because the three cases always produce undefined calculations: + // - 0 / 0 + // - val * NaN + // - inf / inf + if (b == 0 or std.math.isNan(b) or expA == 0x7fff) { + return (a * b) / (a * b); + } + + // Remove the sign from both + aPtr_u16[exp_and_sign_index] = @bitCast(@as(i16, @intCast(expA))); + bPtr_u16[exp_and_sign_index] = @bitCast(@as(i16, @intCast(expB))); + if (amod <= bmod) { + if (amod == bmod) { + return 0 * a; + } + return a; + } + + if (expA == 0) { + amod *= 0x1p120; + expA = @as(i32, aPtr_u16[exp_and_sign_index]) - 120; + } + + if (expB == 0) { + bmod *= 0x1p120; + expB = @as(i32, bPtr_u16[exp_and_sign_index]) - 120; + } + + // OR in extra non-stored mantissa digit + var highA: u64 = (aPtr_u64[high_index] & (std.math.maxInt(u64) >> 16)) | 1 << 48; + const highB: u64 = (bPtr_u64[high_index] & (std.math.maxInt(u64) >> 16)) | 1 << 48; + var lowA: u64 = aPtr_u64[low_index]; + const lowB: u64 = bPtr_u64[low_index]; + + while (expA > expB) : (expA -= 1) { + var high = highA -% highB; + const low = lowA -% lowB; + if (lowA < lowB) { + high -%= 1; + } + if (high >> 63 == 0) { + if ((high | low) == 0) { + return 0 * a; + } + highA = 2 *% high + (low >> 63); + lowA = 2 *% low; + } else { + highA = 2 *% highA + (lowA >> 63); + lowA = 2 *% lowA; + } + } + + var high = highA -% highB; + const low = lowA -% lowB; + if (lowA < lowB) { + high -= 1; + } + if (high >> 63 == 0) { + if ((high | low) == 0) { + return 0 * a; + } + highA = high; + lowA = low; + } + + while (highA >> 48 == 0) { + highA = 2 *% highA + (lowA >> 63); + lowA = 2 *% lowA; + expA = expA - 1; + } + + // Overwrite the current amod with the values in highA and lowA + aPtr_u64[high_index] = highA; + aPtr_u64[low_index] = lowA; + + // Combine the exponent with the sign, normalize if happened to be denormalized + if (expA <= 0) { + aPtr_u16[exp_and_sign_index] = @as(u16, @truncate(@as(u32, @bitCast((expA +% 120))))) | signA; + amod *= 0x1p-120; + } else { + aPtr_u16[exp_and_sign_index] = @as(u16, @truncate(@as(u32, @bitCast(expA)))) | signA; + } + + return amod; +} + +pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __fmodh(a, b), + 32 => return fmodf(a, b), + 64 => return fmod(a, b), + 80 => return __fmodx(a, b), + 128 => return fmodq(a, b), + else => @compileError("unreachable"), + } +} + +inline fn generic_fmod(comptime T: type, x: T, y: T) T { + const bits = @typeInfo(T).float.bits; + const uint = std.meta.Int(.unsigned, bits); + comptime assert(T == f32 or T == f64); + const digits = if (T == f32) 23 else 52; + const exp_bits = if (T == f32) 9 else 12; + const bits_minus_1 = bits - 1; + const mask = if (T == f32) 0xff else 0x7ff; + var ux: uint = @bitCast(x); + var uy: uint = @bitCast(y); + var ex: i32 = @intCast((ux >> digits) & mask); + var ey: i32 = @intCast((uy >> digits) & mask); + const sx = if (T == f32) @as(u32, @intCast(ux & 0x80000000)) else @as(i32, @intCast(ux >> bits_minus_1)); + var i: uint = undefined; + + if (uy << 1 == 0 or math.isNan(@as(T, @bitCast(uy))) or ex == mask) + return (x * y) / (x * y); + + if (ux << 1 <= uy << 1) { + if (ux << 1 == uy << 1) + return 0 * x; + return x; + } + + // normalize x and y + if (ex == 0) { + i = ux << exp_bits; + while (i >> bits_minus_1 == 0) : ({ + ex -= 1; + i <<= 1; + }) {} + ux <<= @intCast(@as(u32, @bitCast(-ex + 1))); + } else { + ux &= math.maxInt(uint) >> exp_bits; + ux |= 1 << digits; + } + if (ey == 0) { + i = uy << exp_bits; + while (i >> bits_minus_1 == 0) : ({ + ey -= 1; + i <<= 1; + }) {} + uy <<= @intCast(@as(u32, @bitCast(-ey + 1))); + } else { + uy &= math.maxInt(uint) >> exp_bits; + uy |= 1 << digits; + } + + // x mod y + while (ex > ey) : (ex -= 1) { + i = ux -% uy; + if (i >> bits_minus_1 == 0) { + if (i == 0) + return 0 * x; + ux = i; + } + ux <<= 1; + } + i = ux -% uy; + if (i >> bits_minus_1 == 0) { + if (i == 0) + return 0 * x; + ux = i; + } + while (ux >> digits == 0) : ({ + ux <<= 1; + ex -= 1; + }) {} + + // scale result up + if (ex > 0) { + ux -%= 1 << digits; + ux |= @as(uint, @as(u32, @bitCast(ex))) << digits; + } else { + ux >>= @intCast(@as(u32, @bitCast(-ex + 1))); + } + if (T == f32) { + ux |= sx; + } else { + ux |= @as(uint, @intCast(sx)) << bits_minus_1; + } + return @bitCast(ux); +} + +test "fmodf" { + const nan_val = math.nan(f32); + const inf_val = math.inf(f32); + + try std.testing.expect(math.isNan(fmodf(nan_val, 1.0))); + try std.testing.expect(math.isNan(fmodf(1.0, nan_val))); + try std.testing.expect(math.isNan(fmodf(inf_val, 1.0))); + try std.testing.expect(math.isNan(fmodf(0.0, 0.0))); + try std.testing.expect(math.isNan(fmodf(1.0, 0.0))); + + try std.testing.expectEqual(@as(f32, 0.0), fmodf(0.0, 2.0)); + try std.testing.expectEqual(@as(f32, -0.0), fmodf(-0.0, 2.0)); + + try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, 10.0)); + try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, -10.0)); + try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, 10.0)); + try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, -10.0)); +} + +test "fmod" { + const nan_val = math.nan(f64); + const inf_val = math.inf(f64); + + try std.testing.expect(math.isNan(fmod(nan_val, 1.0))); + try std.testing.expect(math.isNan(fmod(1.0, nan_val))); + try std.testing.expect(math.isNan(fmod(inf_val, 1.0))); + try std.testing.expect(math.isNan(fmod(0.0, 0.0))); + try std.testing.expect(math.isNan(fmod(1.0, 0.0))); + + try std.testing.expectEqual(@as(f64, 0.0), fmod(0.0, 2.0)); + try std.testing.expectEqual(@as(f64, -0.0), fmod(-0.0, 2.0)); + + try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, 10.0)); + try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, -10.0)); + try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, 10.0)); + try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, -10.0)); +} + +test { + _ = @import("fmodq_test.zig"); + _ = @import("fmodx_test.zig"); +} diff --git a/build/compiler_rt/fmodq_test.zig b/build/compiler_rt/fmodq_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/fmodx_test.zig b/build/compiler_rt/fmodx_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/gedf2.zig b/build/compiler_rt/gedf2.zig new file mode 100644 index 00000000..33b4fa99 --- /dev/null +++ b/build/compiler_rt/gedf2.zig @@ -0,0 +1,36 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_dcmpge, .{ .name = "__aeabi_dcmpge", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_dcmpgt, .{ .name = "__aeabi_dcmpgt", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__gedf2, .{ .name = "__gedf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__gtdf2, .{ .name = "__gtdf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +/// "These functions return a value greater than or equal to zero if neither +/// argument is NaN, and a is greater than or equal to b." +pub fn __gedf2(a: f64, b: f64) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f64, comparef.GE, a, b)); +} + +/// "These functions return a value greater than zero if neither argument is NaN, +/// and a is strictly greater than b." +pub fn __gtdf2(a: f64, b: f64) callconv(.c) i32 { + return __gedf2(a, b); +} + +fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) != .Less); +} + +fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) == .Greater); +} diff --git a/build/compiler_rt/gehf2.zig b/build/compiler_rt/gehf2.zig new file mode 100644 index 00000000..12eccf98 --- /dev/null +++ b/build/compiler_rt/gehf2.zig @@ -0,0 +1,23 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__gehf2, .{ .name = "__gehf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__gthf2, .{ .name = "__gthf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +/// "These functions return a value greater than or equal to zero if neither +/// argument is NaN, and a is greater than or equal to b." +pub fn __gehf2(a: f16, b: f16) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f16, comparef.GE, a, b)); +} + +/// "These functions return a value greater than zero if neither argument is NaN, +/// and a is strictly greater than b." +pub fn __gthf2(a: f16, b: f16) callconv(.c) i32 { + return __gehf2(a, b); +} diff --git a/build/compiler_rt/gesf2.zig b/build/compiler_rt/gesf2.zig new file mode 100644 index 00000000..5f9aefef --- /dev/null +++ b/build/compiler_rt/gesf2.zig @@ -0,0 +1,36 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_fcmpge, .{ .name = "__aeabi_fcmpge", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_fcmpgt, .{ .name = "__aeabi_fcmpgt", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__gesf2, .{ .name = "__gesf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__gtsf2, .{ .name = "__gtsf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +/// "These functions return a value greater than or equal to zero if neither +/// argument is NaN, and a is greater than or equal to b." +pub fn __gesf2(a: f32, b: f32) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f32, comparef.GE, a, b)); +} + +/// "These functions return a value greater than zero if neither argument is NaN, +/// and a is strictly greater than b." +pub fn __gtsf2(a: f32, b: f32) callconv(.c) i32 { + return __gesf2(a, b); +} + +fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f32, comparef.GE, a, b) != .Less); +} + +fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(comparef.cmpf2(f32, comparef.LE, a, b) == .Greater); +} diff --git a/build/compiler_rt/getf2.zig b/build/compiler_rt/getf2.zig new file mode 100644 index 00000000..3a178437 --- /dev/null +++ b/build/compiler_rt/getf2.zig @@ -0,0 +1,30 @@ +///! The quoted behavior definitions are from +///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__getf2, .{ .name = "__gekf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__gttf2, .{ .name = "__gtkf2", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + // These exports are handled in cmptf2.zig because gt and ge on sparc + // are based on calling _Qp_cmp. + } + @export(&__getf2, .{ .name = "__getf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__gttf2, .{ .name = "__gttf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +/// "These functions return a value greater than or equal to zero if neither +/// argument is NaN, and a is greater than or equal to b." +fn __getf2(a: f128, b: f128) callconv(.c) i32 { + return @intFromEnum(comparef.cmpf2(f128, comparef.GE, a, b)); +} + +/// "These functions return a value greater than zero if neither argument is NaN, +/// and a is strictly greater than b." +fn __gttf2(a: f128, b: f128) callconv(.c) i32 { + return __getf2(a, b); +} diff --git a/build/compiler_rt/gexf2.zig b/build/compiler_rt/gexf2.zig new file mode 100644 index 00000000..7ea0d6ee --- /dev/null +++ b/build/compiler_rt/gexf2.zig @@ -0,0 +1,17 @@ +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__gexf2, .{ .name = "__gexf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__gtxf2, .{ .name = "__gtxf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __gexf2(a: f80, b: f80) callconv(.c) i32 { + return @intFromEnum(comparef.cmp_f80(comparef.GE, a, b)); +} + +fn __gtxf2(a: f80, b: f80) callconv(.c) i32 { + return __gexf2(a, b); +} diff --git a/build/compiler_rt/hexagon.zig b/build/compiler_rt/hexagon.zig new file mode 100644 index 00000000..de7fd964 --- /dev/null +++ b/build/compiler_rt/hexagon.zig @@ -0,0 +1,1787 @@ +const builtin = @import("builtin"); +const common = @import("./common.zig"); + +fn __hexagon_divsi3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ p0 = cmp.ge(r0,#0) + \\ p1 = cmp.ge(r1,#0) + \\ r1 = abs(r0) + \\ r2 = abs(r1) + \\ } + \\ { + \\ r3 = cl0(r1) + \\ r4 = cl0(r2) + \\ r5 = sub(r1,r2) + \\ p2 = cmp.gtu(r2,r1) + \\ } + \\ { + \\ r0 = #0 + \\ p1 = xor(p0,p1) + \\ p0 = cmp.gtu(r2,r5) + \\ if (p2) jumpr r31 + \\ } + \\ + \\ { + \\ r0 = mux(p1,#-1,#1) + \\ if (p0) jumpr r31 + \\ r4 = sub(r4,r3) + \\ r3 = #1 + \\ } + \\ { + \\ r0 = #0 + \\ r3:2 = vlslw(r3:2,r4) + \\ loop0(1f,r4) + \\ } + \\ .falign + \\ 1: + \\ { + \\ p0 = cmp.gtu(r2,r1) + \\ if (!p0.new) r1 = sub(r1,r2) + \\ if (!p0.new) r0 = add(r0,r3) + \\ r3:2 = vlsrw(r3:2,#1) + \\ }:endloop0 + \\ { + \\ p0 = cmp.gtu(r2,r1) + \\ if (!p0.new) r0 = add(r0,r3) + \\ if (!p1) jumpr r31 + \\ } + \\ { + \\ r0 = neg(r0) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_umodsi3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r2 = cl0(r0) + \\ r3 = cl0(r1) + \\ p0 = cmp.gtu(r1,r0) + \\ } + \\ { + \\ r2 = sub(r3,r2) + \\ if (p0) jumpr r31 + \\ } + \\ { + \\ loop0(1f,r2) + \\ p1 = cmp.eq(r2,#0) + \\ r2 = lsl(r1,r2) + \\ } + \\ .falign + \\ 1: + \\ { + \\ p0 = cmp.gtu(r2,r0) + \\ if (!p0.new) r0 = sub(r0,r2) + \\ r2 = lsr(r2,#1) + \\ if (p1) r1 = #0 + \\ }:endloop0 + \\ { + \\ p0 = cmp.gtu(r2,r0) + \\ if (!p0.new) r0 = sub(r0,r1) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_sqrtf() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r3,p0 = sfinvsqrta(r0) + \\ r5 = sffixupr(r0) + \\ r4 = ##0x3f000000 + \\ r1:0 = combine(#0,#0) + \\ } + \\ { + \\ r0 += sfmpy(r3,r5):lib + \\ r1 += sfmpy(r3,r4):lib + \\ r2 = r4 + \\ r3 = r5 + \\ } + \\ { + \\ r2 -= sfmpy(r0,r1):lib + \\ p1 = sfclass(r5,#1) + \\ + \\ } + \\ { + \\ r0 += sfmpy(r0,r2):lib + \\ r1 += sfmpy(r1,r2):lib + \\ r2 = r4 + \\ r3 = r5 + \\ } + \\ { + \\ r2 -= sfmpy(r0,r1):lib + \\ r3 -= sfmpy(r0,r0):lib + \\ } + \\ { + \\ r0 += sfmpy(r1,r3):lib + \\ r1 += sfmpy(r1,r2):lib + \\ r2 = r4 + \\ r3 = r5 + \\ } + \\ { + \\ + \\ r3 -= sfmpy(r0,r0):lib + \\ if (p1) r0 = or(r0,r5) + \\ } + \\ { + \\ r0 += sfmpy(r1,r3,p0):scale + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_moddi3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ p3 = tstbit(r1,#31) + \\ } + \\ { + \\ r1:0 = abs(r1:0) + \\ r3:2 = abs(r3:2) + \\ } + \\ { + \\ r6 = cl0(r1:0) + \\ r7 = cl0(r3:2) + \\ r5:4 = r3:2 + \\ r3:2 = r1:0 + \\ } + \\ { + \\ r10 = sub(r7,r6) + \\ r1:0 = #0 + \\ r15:14 = #1 + \\ } + \\ { + \\ r11 = add(r10,#1) + \\ r13:12 = lsl(r5:4,r10) + \\ r15:14 = lsl(r15:14,r10) + \\ } + \\ { + \\ p0 = cmp.gtu(r5:4,r3:2) + \\ loop0(1f,r11) + \\ } + \\ { + \\ if (p0) jump .hexagon_moddi3_return + \\ } + \\ .falign + \\ 1: + \\ { + \\ p0 = cmp.gtu(r13:12,r3:2) + \\ } + \\ { + \\ r7:6 = sub(r3:2, r13:12) + \\ r9:8 = add(r1:0, r15:14) + \\ } + \\ { + \\ r1:0 = vmux(p0, r1:0, r9:8) + \\ r3:2 = vmux(p0, r3:2, r7:6) + \\ } + \\ { + \\ r15:14 = lsr(r15:14, #1) + \\ r13:12 = lsr(r13:12, #1) + \\ }:endloop0 + \\ + \\ .hexagon_moddi3_return: + \\ { + \\ r1:0 = neg(r3:2) + \\ } + \\ { + \\ r1:0 = vmux(p3,r1:0,r3:2) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_divdi3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ p2 = tstbit(r1,#31) + \\ p3 = tstbit(r3,#31) + \\ } + \\ { + \\ r1:0 = abs(r1:0) + \\ r3:2 = abs(r3:2) + \\ } + \\ { + \\ r6 = cl0(r1:0) + \\ r7 = cl0(r3:2) + \\ r5:4 = r3:2 + \\ r3:2 = r1:0 + \\ } + \\ { + \\ p3 = xor(p2,p3) + \\ r10 = sub(r7,r6) + \\ r1:0 = #0 + \\ r15:14 = #1 + \\ } + \\ { + \\ r11 = add(r10,#1) + \\ r13:12 = lsl(r5:4,r10) + \\ r15:14 = lsl(r15:14,r10) + \\ } + \\ { + \\ p0 = cmp.gtu(r5:4,r3:2) + \\ loop0(1f,r11) + \\ } + \\ { + \\ if (p0) jump .hexagon_divdi3_return + \\ } + \\ .falign + \\ 1: + \\ { + \\ p0 = cmp.gtu(r13:12,r3:2) + \\ } + \\ { + \\ r7:6 = sub(r3:2, r13:12) + \\ r9:8 = add(r1:0, r15:14) + \\ } + \\ { + \\ r1:0 = vmux(p0, r1:0, r9:8) + \\ r3:2 = vmux(p0, r3:2, r7:6) + \\ } + \\ { + \\ r15:14 = lsr(r15:14, #1) + \\ r13:12 = lsr(r13:12, #1) + \\ }:endloop0 + \\ + \\ .hexagon_divdi3_return: + \\ { + \\ r3:2 = neg(r1:0) + \\ } + \\ { + \\ r1:0 = vmux(p3,r3:2,r1:0) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_divsf3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r2,p0 = sfrecipa(r0,r1) + \\ r4 = sffixupd(r0,r1) + \\ r3 = ##0x3f800000 + \\ } + \\ { + \\ r5 = sffixupn(r0,r1) + \\ r3 -= sfmpy(r4,r2):lib + \\ r6 = ##0x80000000 + \\ r7 = r3 + \\ } + \\ { + \\ r2 += sfmpy(r3,r2):lib + \\ r3 = r7 + \\ r6 = r5 + \\ r0 = and(r6,r5) + \\ } + \\ { + \\ r3 -= sfmpy(r4,r2):lib + \\ r0 += sfmpy(r5,r2):lib + \\ } + \\ { + \\ r2 += sfmpy(r3,r2):lib + \\ r6 -= sfmpy(r0,r4):lib + \\ } + \\ { + \\ r0 += sfmpy(r6,r2):lib + \\ } + \\ { + \\ r5 -= sfmpy(r0,r4):lib + \\ } + \\ { + \\ r0 += sfmpy(r5,r2,p0):scale + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_udivdi3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r6 = cl0(r1:0) + \\ r7 = cl0(r3:2) + \\ r5:4 = r3:2 + \\ r3:2 = r1:0 + \\ } + \\ { + \\ r10 = sub(r7,r6) + \\ r1:0 = #0 + \\ r15:14 = #1 + \\ } + \\ { + \\ r11 = add(r10,#1) + \\ r13:12 = lsl(r5:4,r10) + \\ r15:14 = lsl(r15:14,r10) + \\ } + \\ { + \\ p0 = cmp.gtu(r5:4,r3:2) + \\ loop0(1f,r11) + \\ } + \\ { + \\ if (p0) jumpr r31 + \\ } + \\ .falign + \\ 1: + \\ { + \\ p0 = cmp.gtu(r13:12,r3:2) + \\ } + \\ { + \\ r7:6 = sub(r3:2, r13:12) + \\ r9:8 = add(r1:0, r15:14) + \\ } + \\ { + \\ r1:0 = vmux(p0, r1:0, r9:8) + \\ r3:2 = vmux(p0, r3:2, r7:6) + \\ } + \\ { + \\ r15:14 = lsr(r15:14, #1) + \\ r13:12 = lsr(r13:12, #1) + \\ }:endloop0 + \\ { + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_umoddi3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r6 = cl0(r1:0) + \\ r7 = cl0(r3:2) + \\ r5:4 = r3:2 + \\ r3:2 = r1:0 + \\ } + \\ { + \\ r10 = sub(r7,r6) + \\ r1:0 = #0 + \\ r15:14 = #1 + \\ } + \\ { + \\ r11 = add(r10,#1) + \\ r13:12 = lsl(r5:4,r10) + \\ r15:14 = lsl(r15:14,r10) + \\ } + \\ { + \\ p0 = cmp.gtu(r5:4,r3:2) + \\ loop0(1f,r11) + \\ } + \\ { + \\ if (p0) jump .hexagon_umoddi3_return + \\ } + \\ .falign + \\ 1: + \\ { + \\ p0 = cmp.gtu(r13:12,r3:2) + \\ } + \\ { + \\ r7:6 = sub(r3:2, r13:12) + \\ r9:8 = add(r1:0, r15:14) + \\ } + \\ { + \\ r1:0 = vmux(p0, r1:0, r9:8) + \\ r3:2 = vmux(p0, r3:2, r7:6) + \\ } + \\ { + \\ r15:14 = lsr(r15:14, #1) + \\ r13:12 = lsr(r13:12, #1) + \\ }:endloop0 + \\ + \\ .hexagon_umoddi3_return: + \\ { + \\ r1:0 = r3:2 + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_modsi3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ p2 = cmp.ge(r0,#0) + \\ r2 = abs(r0) + \\ r1 = abs(r1) + \\ } + \\ { + \\ r3 = cl0(r2) + \\ r4 = cl0(r1) + \\ p0 = cmp.gtu(r1,r2) + \\ } + \\ { + \\ r3 = sub(r4,r3) + \\ if (p0) jumpr r31 + \\ } + \\ { + \\ p1 = cmp.eq(r3,#0) + \\ loop0(1f,r3) + \\ r0 = r2 + \\ r2 = lsl(r1,r3) + \\ } + \\ .falign + \\ 1: + \\ { + \\ p0 = cmp.gtu(r2,r0) + \\ if (!p0.new) r0 = sub(r0,r2) + \\ r2 = lsr(r2,#1) + \\ if (p1) r1 = #0 + \\ }:endloop0 + \\ { + \\ p0 = cmp.gtu(r2,r0) + \\ if (!p0.new) r0 = sub(r0,r1) + \\ if (p2) jumpr r31 + \\ } + \\ { + \\ r0 = neg(r0) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_memcpy_likely_aligned_min32bytes_mult8bytes() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ p0 = bitsclr(r1,#7) + \\ p0 = bitsclr(r0,#7) + \\ if (p0.new) r5:4 = memd(r1) + \\ r3 = #-3 + \\ } + \\ { + \\ if (!p0) jump .Lmemcpy_call + \\ if (p0) memd(r0++#8) = r5:4 + \\ if (p0) r5:4 = memd(r1+#8) + \\ r3 += lsr(r2,#3) + \\ } + \\ { + \\ memd(r0++#8) = r5:4 + \\ r5:4 = memd(r1+#16) + \\ r1 = add(r1,#24) + \\ loop0(1f,r3) + \\ } + \\ .falign + \\ 1: + \\ { + \\ memd(r0++#8) = r5:4 + \\ r5:4 = memd(r1++#8) + \\ }:endloop0 + \\ { + \\ memd(r0) = r5:4 + \\ r0 -= add(r2,#-8) + \\ jumpr r31 + \\ } + \\ .Lmemcpy_call: + \\ jump memcpy@PLT + ); +} + +fn __hexagon_udivsi3() callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r2 = cl0(r0) + \\ r3 = cl0(r1) + \\ r5:4 = combine(#1,#0) + \\ p0 = cmp.gtu(r1,r0) + \\ } + \\ { + \\ r6 = sub(r3,r2) + \\ r4 = r1 + \\ r1:0 = combine(r0,r4) + \\ if (p0) jumpr r31 + \\ } + \\ { + \\ r3:2 = vlslw(r5:4,r6) + \\ loop0(1f,r6) + \\ } + \\ .falign + \\ 1: + \\ { + \\ p0 = cmp.gtu(r2,r1) + \\ if (!p0.new) r1 = sub(r1,r2) + \\ if (!p0.new) r0 = add(r0,r3) + \\ r3:2 = vlsrw(r3:2,#1) + \\ }:endloop0 + \\ { + \\ p0 = cmp.gtu(r2,r1) + \\ if (!p0.new) r0 = add(r0,r3) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_adddf3() align(32) callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r4 = extractu(r1,#11,#20) + \\ r5 = extractu(r3,#11,#20) + \\ r13:12 = combine(##0x20000000,#0) + \\ } + \\ { + \\ p3 = dfclass(r1:0,#2) + \\ p3 = dfclass(r3:2,#2) + \\ r9:8 = r13:12 + \\ p2 = cmp.gtu(r5,r4) + \\ } + \\ { + \\ if (!p3) jump .Ladd_abnormal + \\ if (p2) r1:0 = r3:2 + \\ if (p2) r3:2 = r1:0 + \\ if (p2) r5:4 = combine(r4,r5) + \\ } + \\ { + \\ r13:12 = insert(r1:0,#52,#11 -2) + \\ r9:8 = insert(r3:2,#52,#11 -2) + \\ r15 = sub(r4,r5) + \\ r7:6 = combine(#62,#1) + \\ } + \\ + \\ + \\ + \\ + \\ + \\ .Ladd_continue: + \\ { + \\ r15 = min(r15,r7) + \\ + \\ r11:10 = neg(r13:12) + \\ p2 = cmp.gt(r1,#-1) + \\ r14 = #0 + \\ } + \\ { + \\ if (!p2) r13:12 = r11:10 + \\ r11:10 = extractu(r9:8,r15:14) + \\ r9:8 = ASR(r9:8,r15) + \\ + \\ + \\ + \\ + \\ r15:14 = #0 + \\ } + \\ { + \\ p1 = cmp.eq(r11:10,r15:14) + \\ if (!p1.new) r8 = or(r8,r6) + \\ r5 = add(r4,#-1024 -60) + \\ p3 = cmp.gt(r3,#-1) + \\ } + \\ { + \\ r13:12 = add(r13:12,r9:8) + \\ r11:10 = sub(r13:12,r9:8) + \\ r7:6 = combine(#54,##2045) + \\ } + \\ { + \\ p0 = cmp.gtu(r4,r7) + \\ p0 = !cmp.gtu(r4,r6) + \\ if (!p0.new) jump:nt .Ladd_ovf_unf + \\ if (!p3) r13:12 = r11:10 + \\ } + \\ { + \\ r1:0 = convert_d2df(r13:12) + \\ p0 = cmp.eq(r13,#0) + \\ p0 = cmp.eq(r12,#0) + \\ if (p0.new) jump:nt .Ladd_zero + \\ } + \\ { + \\ r1 += asl(r5,#20) + \\ jumpr r31 + \\ } + \\ + \\ .falign + \\ .Ladd_zero: + \\ + \\ + \\ { + \\ r28 = USR + \\ r1:0 = #0 + \\ r3 = #1 + \\ } + \\ { + \\ r28 = extractu(r28,#2,#22) + \\ r3 = asl(r3,#31) + \\ } + \\ { + \\ p0 = cmp.eq(r28,#2) + \\ if (p0.new) r1 = xor(r1,r3) + \\ jumpr r31 + \\ } + \\ .falign + \\ .Ladd_ovf_unf: + \\ { + \\ r1:0 = convert_d2df(r13:12) + \\ p0 = cmp.eq(r13,#0) + \\ p0 = cmp.eq(r12,#0) + \\ if (p0.new) jump:nt .Ladd_zero + \\ } + \\ { + \\ r28 = extractu(r1,#11,#20) + \\ r1 += asl(r5,#20) + \\ } + \\ { + \\ r5 = add(r5,r28) + \\ r3:2 = combine(##0x00100000,#0) + \\ } + \\ { + \\ p0 = cmp.gt(r5,##1024 +1024 -2) + \\ if (p0.new) jump:nt .Ladd_ovf + \\ } + \\ { + \\ p0 = cmp.gt(r5,#0) + \\ if (p0.new) jumpr:t r31 + \\ r28 = sub(#1,r5) + \\ } + \\ { + \\ r3:2 = insert(r1:0,#52,#0) + \\ r1:0 = r13:12 + \\ } + \\ { + \\ r3:2 = lsr(r3:2,r28) + \\ } + \\ { + \\ r1:0 = insert(r3:2,#63,#0) + \\ jumpr r31 + \\ } + \\ .falign + \\ .Ladd_ovf: + \\ + \\ { + \\ r1:0 = r13:12 + \\ r28 = USR + \\ r13:12 = combine(##0x7fefffff,#-1) + \\ } + \\ { + \\ r5 = extractu(r28,#2,#22) + \\ r28 = or(r28,#0x28) + \\ r9:8 = combine(##0x7ff00000,#0) + \\ } + \\ { + \\ USR = r28 + \\ r5 ^= lsr(r1,#31) + \\ r28 = r5 + \\ } + \\ { + \\ p0 = !cmp.eq(r28,#1) + \\ p0 = !cmp.eq(r5,#2) + \\ if (p0.new) r13:12 = r9:8 + \\ } + \\ { + \\ r1:0 = insert(r13:12,#63,#0) + \\ } + \\ { + \\ p0 = dfcmp.eq(r1:0,r1:0) + \\ jumpr r31 + \\ } + \\ + \\ .Ladd_abnormal: + \\ { + \\ r13:12 = extractu(r1:0,#63,#0) + \\ r9:8 = extractu(r3:2,#63,#0) + \\ } + \\ { + \\ p3 = cmp.gtu(r13:12,r9:8) + \\ if (!p3.new) r1:0 = r3:2 + \\ if (!p3.new) r3:2 = r1:0 + \\ } + \\ { + \\ + \\ p0 = dfclass(r1:0,#0x0f) + \\ if (!p0.new) jump:nt .Linvalid_nan_add + \\ if (!p3) r13:12 = r9:8 + \\ if (!p3) r9:8 = r13:12 + \\ } + \\ { + \\ + \\ + \\ p1 = dfclass(r1:0,#0x08) + \\ if (p1.new) jump:nt .Linf_add + \\ } + \\ { + \\ p2 = dfclass(r3:2,#0x01) + \\ if (p2.new) jump:nt .LB_zero + \\ r13:12 = #0 + \\ } + \\ + \\ { + \\ p0 = dfclass(r1:0,#4) + \\ if (p0.new) jump:nt .Ladd_two_subnormal + \\ r13:12 = combine(##0x20000000,#0) + \\ } + \\ { + \\ r4 = extractu(r1,#11,#20) + \\ r5 = #1 + \\ + \\ r9:8 = asl(r9:8,#11 -2) + \\ } + \\ + \\ + \\ + \\ { + \\ r13:12 = insert(r1:0,#52,#11 -2) + \\ r15 = sub(r4,r5) + \\ r7:6 = combine(#62,#1) + \\ jump .Ladd_continue + \\ } + \\ + \\ .Ladd_two_subnormal: + \\ { + \\ r13:12 = extractu(r1:0,#63,#0) + \\ r9:8 = extractu(r3:2,#63,#0) + \\ } + \\ { + \\ r13:12 = neg(r13:12) + \\ r9:8 = neg(r9:8) + \\ p0 = cmp.gt(r1,#-1) + \\ p1 = cmp.gt(r3,#-1) + \\ } + \\ { + \\ if (p0) r13:12 = r1:0 + \\ if (p1) r9:8 = r3:2 + \\ } + \\ { + \\ r13:12 = add(r13:12,r9:8) + \\ } + \\ { + \\ r9:8 = neg(r13:12) + \\ p0 = cmp.gt(r13,#-1) + \\ r3:2 = #0 + \\ } + \\ { + \\ if (!p0) r1:0 = r9:8 + \\ if (p0) r1:0 = r13:12 + \\ r3 = ##0x80000000 + \\ } + \\ { + \\ if (!p0) r1 = or(r1,r3) + \\ p0 = dfcmp.eq(r1:0,r3:2) + \\ if (p0.new) jump:nt .Lzero_plus_zero + \\ } + \\ { + \\ jumpr r31 + \\ } + \\ + \\ .Linvalid_nan_add: + \\ { + \\ r28 = convert_df2sf(r1:0) + \\ p0 = dfclass(r3:2,#0x0f) + \\ if (p0.new) r3:2 = r1:0 + \\ } + \\ { + \\ r2 = convert_df2sf(r3:2) + \\ r1:0 = #-1 + \\ jumpr r31 + \\ } + \\ .falign + \\ .LB_zero: + \\ { + \\ p0 = dfcmp.eq(r13:12,r1:0) + \\ if (!p0.new) jumpr:t r31 + \\ } + \\ + \\ + \\ + \\ + \\ .Lzero_plus_zero: + \\ { + \\ p0 = cmp.eq(r1:0,r3:2) + \\ if (p0.new) jumpr:t r31 + \\ } + \\ { + \\ r28 = USR + \\ } + \\ { + \\ r28 = extractu(r28,#2,#22) + \\ r1:0 = #0 + \\ } + \\ { + \\ p0 = cmp.eq(r28,#2) + \\ if (p0.new) r1 = ##0x80000000 + \\ jumpr r31 + \\ } + \\ .Linf_add: + \\ + \\ { + \\ p0 = !cmp.eq(r1,r3) + \\ p0 = dfclass(r3:2,#8) + \\ if (!p0.new) jumpr:t r31 + \\ } + \\ { + \\ r2 = ##0x7f800001 + \\ } + \\ { + \\ r1:0 = convert_sf2df(r2) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_subdf3() align(32) callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r3 = togglebit(r3,#31) + \\ jump ##__hexagon_adddf3 + \\ } + ); +} + +fn __hexagon_divdf3() align(32) callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ p2 = dfclass(r1:0,#0x02) + \\ p2 = dfclass(r3:2,#0x02) + \\ r13:12 = combine(r3,r1) + \\ r28 = xor(r1,r3) + \\ } + \\ { + \\ if (!p2) jump .Ldiv_abnormal + \\ r7:6 = extractu(r3:2,#23,#52 -23) + \\ r8 = ##0x3f800001 + \\ } + \\ { + \\ r9 = or(r8,r6) + \\ r13 = extractu(r13,#11,#52 -32) + \\ r12 = extractu(r12,#11,#52 -32) + \\ p3 = cmp.gt(r28,#-1) + \\ } + \\ + \\ + \\ .Ldenorm_continue: + \\ { + \\ r11,p0 = sfrecipa(r8,r9) + \\ r10 = and(r8,#-2) + \\ r28 = #1 + \\ r12 = sub(r12,r13) + \\ } + \\ + \\ + \\ { + \\ r10 -= sfmpy(r11,r9):lib + \\ r1 = insert(r28,#11 +1,#52 -32) + \\ r13 = ##0x00800000 << 3 + \\ } + \\ { + \\ r11 += sfmpy(r11,r10):lib + \\ r3 = insert(r28,#11 +1,#52 -32) + \\ r10 = and(r8,#-2) + \\ } + \\ { + \\ r10 -= sfmpy(r11,r9):lib + \\ r5 = #-0x3ff +1 + \\ r4 = #0x3ff -1 + \\ } + \\ { + \\ r11 += sfmpy(r11,r10):lib + \\ p1 = cmp.gt(r12,r5) + \\ p1 = !cmp.gt(r12,r4) + \\ } + \\ { + \\ r13 = insert(r11,#23,#3) + \\ r5:4 = #0 + \\ r12 = add(r12,#-61) + \\ } + \\ + \\ + \\ + \\ + \\ { + \\ r13 = add(r13,#((-3) << 3)) + \\ } + \\ { r7:6 = mpyu(r13,r1); r1:0 = asl(r1:0,# ( 15 )); }; { r6 = # 0; r1:0 -= mpyu(r7,r2); r15:14 = mpyu(r7,r3); }; { r5:4 += ASL(r7:6, # ( 14 )); r1:0 -= asl(r15:14, # 32); } + \\ { r7:6 = mpyu(r13,r1); r1:0 = asl(r1:0,# ( 15 )); }; { r6 = # 0; r1:0 -= mpyu(r7,r2); r15:14 = mpyu(r7,r3); }; { r5:4 += ASR(r7:6, # ( 1 )); r1:0 -= asl(r15:14, # 32); } + \\ { r7:6 = mpyu(r13,r1); r1:0 = asl(r1:0,# ( 15 )); }; { r6 = # 0; r1:0 -= mpyu(r7,r2); r15:14 = mpyu(r7,r3); }; { r5:4 += ASR(r7:6, # ( 16 )); r1:0 -= asl(r15:14, # 32); } + \\ { r7:6 = mpyu(r13,r1); r1:0 = asl(r1:0,# ( 15 )); }; { r6 = # 0; r1:0 -= mpyu(r7,r2); r15:14 = mpyu(r7,r3); }; { r5:4 += ASR(r7:6, # ( 31 )); r1:0 -= asl(r15:14, # 32); r7:6=# ( 0 ); } + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ { + \\ + \\ r15:14 = sub(r1:0,r3:2) + \\ p0 = cmp.gtu(r3:2,r1:0) + \\ + \\ if (!p0.new) r6 = #2 + \\ } + \\ { + \\ r5:4 = add(r5:4,r7:6) + \\ if (!p0) r1:0 = r15:14 + \\ r15:14 = #0 + \\ } + \\ { + \\ p0 = cmp.eq(r1:0,r15:14) + \\ if (!p0.new) r4 = or(r4,r28) + \\ } + \\ { + \\ r7:6 = neg(r5:4) + \\ } + \\ { + \\ if (!p3) r5:4 = r7:6 + \\ } + \\ { + \\ r1:0 = convert_d2df(r5:4) + \\ if (!p1) jump .Ldiv_ovf_unf + \\ } + \\ { + \\ r1 += asl(r12,#52 -32) + \\ jumpr r31 + \\ } + \\ + \\ .Ldiv_ovf_unf: + \\ { + \\ r1 += asl(r12,#52 -32) + \\ r13 = extractu(r1,#11,#52 -32) + \\ } + \\ { + \\ r7:6 = abs(r5:4) + \\ r12 = add(r12,r13) + \\ } + \\ { + \\ p0 = cmp.gt(r12,##0x3ff +0x3ff) + \\ if (p0.new) jump:nt .Ldiv_ovf + \\ } + \\ { + \\ p0 = cmp.gt(r12,#0) + \\ if (p0.new) jump:nt .Ldiv_possible_unf + \\ } + \\ { + \\ r13 = add(clb(r7:6),#-1) + \\ r12 = sub(#7,r12) + \\ r10 = USR + \\ r11 = #63 + \\ } + \\ { + \\ r13 = min(r12,r11) + \\ r11 = or(r10,#0x030) + \\ r7:6 = asl(r7:6,r13) + \\ r12 = #0 + \\ } + \\ { + \\ r15:14 = extractu(r7:6,r13:12) + \\ r7:6 = lsr(r7:6,r13) + \\ r3:2 = #1 + \\ } + \\ { + \\ p0 = cmp.gtu(r3:2,r15:14) + \\ if (!p0.new) r6 = or(r2,r6) + \\ r7 = setbit(r7,#52 -32+4) + \\ } + \\ { + \\ r5:4 = neg(r7:6) + \\ p0 = bitsclr(r6,#(1<<4)-1) + \\ if (!p0.new) r10 = r11 + \\ } + \\ { + \\ USR = r10 + \\ if (p3) r5:4 = r7:6 + \\ r10 = #-0x3ff -(52 +4) + \\ } + \\ { + \\ r1:0 = convert_d2df(r5:4) + \\ } + \\ { + \\ r1 += asl(r10,#52 -32) + \\ jumpr r31 + \\ } + \\ + \\ + \\ .Ldiv_possible_unf: + \\ + \\ + \\ { + \\ r3:2 = extractu(r1:0,#63,#0) + \\ r15:14 = combine(##0x00100000,#0) + \\ r10 = #0x7FFF + \\ } + \\ { + \\ p0 = dfcmp.eq(r15:14,r3:2) + \\ p0 = bitsset(r7,r10) + \\ } + \\ + \\ + \\ + \\ + \\ + \\ + \\ { + \\ if (!p0) jumpr r31 + \\ r10 = USR + \\ } + \\ + \\ { + \\ r10 = or(r10,#0x30) + \\ } + \\ { + \\ USR = r10 + \\ } + \\ { + \\ p0 = dfcmp.eq(r1:0,r1:0) + \\ jumpr r31 + \\ } + \\ + \\ .Ldiv_ovf: + \\ + \\ + \\ + \\ { + \\ r10 = USR + \\ r3:2 = combine(##0x7fefffff,#-1) + \\ r1 = mux(p3,#0,#-1) + \\ } + \\ { + \\ r7:6 = combine(##0x7ff00000,#0) + \\ r5 = extractu(r10,#2,#22) + \\ r10 = or(r10,#0x28) + \\ } + \\ { + \\ USR = r10 + \\ r5 ^= lsr(r1,#31) + \\ r4 = r5 + \\ } + \\ { + \\ p0 = !cmp.eq(r4,#1) + \\ p0 = !cmp.eq(r5,#2) + \\ if (p0.new) r3:2 = r7:6 + \\ p0 = dfcmp.eq(r3:2,r3:2) + \\ } + \\ { + \\ r1:0 = insert(r3:2,#63,#0) + \\ jumpr r31 + \\ } + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ .Ldiv_abnormal: + \\ { + \\ p0 = dfclass(r1:0,#0x0F) + \\ p0 = dfclass(r3:2,#0x0F) + \\ p3 = cmp.gt(r28,#-1) + \\ } + \\ { + \\ p1 = dfclass(r1:0,#0x08) + \\ p1 = dfclass(r3:2,#0x08) + \\ } + \\ { + \\ p2 = dfclass(r1:0,#0x01) + \\ p2 = dfclass(r3:2,#0x01) + \\ } + \\ { + \\ if (!p0) jump .Ldiv_nan + \\ if (p1) jump .Ldiv_invalid + \\ } + \\ { + \\ if (p2) jump .Ldiv_invalid + \\ } + \\ { + \\ p2 = dfclass(r1:0,#(0x0F ^ 0x01)) + \\ p2 = dfclass(r3:2,#(0x0F ^ 0x08)) + \\ } + \\ { + \\ p1 = dfclass(r1:0,#(0x0F ^ 0x08)) + \\ p1 = dfclass(r3:2,#(0x0F ^ 0x01)) + \\ } + \\ { + \\ if (!p2) jump .Ldiv_zero_result + \\ if (!p1) jump .Ldiv_inf_result + \\ } + \\ + \\ + \\ + \\ + \\ + \\ { + \\ p0 = dfclass(r1:0,#0x02) + \\ p1 = dfclass(r3:2,#0x02) + \\ r10 = ##0x00100000 + \\ } + \\ { + \\ r13:12 = combine(r3,r1) + \\ r1 = insert(r10,#11 +1,#52 -32) + \\ r3 = insert(r10,#11 +1,#52 -32) + \\ } + \\ { + \\ if (p0) r1 = or(r1,r10) + \\ if (p1) r3 = or(r3,r10) + \\ } + \\ { + \\ r5 = add(clb(r1:0),#-11) + \\ r4 = add(clb(r3:2),#-11) + \\ r10 = #1 + \\ } + \\ { + \\ r12 = extractu(r12,#11,#52 -32) + \\ r13 = extractu(r13,#11,#52 -32) + \\ } + \\ { + \\ r1:0 = asl(r1:0,r5) + \\ r3:2 = asl(r3:2,r4) + \\ if (!p0) r12 = sub(r10,r5) + \\ if (!p1) r13 = sub(r10,r4) + \\ } + \\ { + \\ r7:6 = extractu(r3:2,#23,#52 -23) + \\ } + \\ { + \\ r9 = or(r8,r6) + \\ jump .Ldenorm_continue + \\ } + \\ + \\ .Ldiv_zero_result: + \\ { + \\ r1 = xor(r1,r3) + \\ r3:2 = #0 + \\ } + \\ { + \\ r1:0 = insert(r3:2,#63,#0) + \\ jumpr r31 + \\ } + \\ .Ldiv_inf_result: + \\ { + \\ p2 = dfclass(r3:2,#0x01) + \\ p2 = dfclass(r1:0,#(0x0F ^ 0x08)) + \\ } + \\ { + \\ r10 = USR + \\ if (!p2) jump 1f + \\ r1 = xor(r1,r3) + \\ } + \\ { + \\ r10 = or(r10,#0x04) + \\ } + \\ { + \\ USR = r10 + \\ } + \\ 1: + \\ { + \\ r3:2 = combine(##0x7ff00000,#0) + \\ p0 = dfcmp.uo(r3:2,r3:2) + \\ } + \\ { + \\ r1:0 = insert(r3:2,#63,#0) + \\ jumpr r31 + \\ } + \\ .Ldiv_nan: + \\ { + \\ p0 = dfclass(r1:0,#0x10) + \\ p1 = dfclass(r3:2,#0x10) + \\ if (!p0.new) r1:0 = r3:2 + \\ if (!p1.new) r3:2 = r1:0 + \\ } + \\ { + \\ r5 = convert_df2sf(r1:0) + \\ r4 = convert_df2sf(r3:2) + \\ } + \\ { + \\ r1:0 = #-1 + \\ jumpr r31 + \\ } + \\ + \\ .Ldiv_invalid: + \\ { + \\ r10 = ##0x7f800001 + \\ } + \\ { + \\ r1:0 = convert_sf2df(r10) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_muldf3() align(32) callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ p0 = dfclass(r1:0,#2) + \\ p0 = dfclass(r3:2,#2) + \\ r13:12 = combine(##0x40000000,#0) + \\ } + \\ { + \\ r13:12 = insert(r1:0,#52,#11 -1) + \\ r5:4 = asl(r3:2,#11 -1) + \\ r28 = #-1024 + \\ r9:8 = #1 + \\ } + \\ { + \\ r7:6 = mpyu(r4,r13) + \\ r5:4 = insert(r9:8,#2,#62) + \\ } + \\ + \\ + \\ + \\ + \\ { + \\ r15:14 = mpyu(r12,r4) + \\ r7:6 += mpyu(r12,r5) + \\ } + \\ { + \\ r7:6 += lsr(r15:14,#32) + \\ r11:10 = mpyu(r13,r5) + \\ r5:4 = combine(##1024 +1024 -4,#0) + \\ } + \\ { + \\ r11:10 += lsr(r7:6,#32) + \\ if (!p0) jump .Lmul_abnormal + \\ p1 = cmp.eq(r14,#0) + \\ p1 = cmp.eq(r6,#0) + \\ } + \\ { + \\ if (!p1) r10 = or(r10,r8) + \\ r6 = extractu(r1,#11,#20) + \\ r7 = extractu(r3,#11,#20) + \\ } + \\ { + \\ r15:14 = neg(r11:10) + \\ r6 += add(r28,r7) + \\ r28 = xor(r1,r3) + \\ } + \\ { + \\ if (!p2.new) r11:10 = r15:14 + \\ p2 = cmp.gt(r28,#-1) + \\ p0 = !cmp.gt(r6,r5) + \\ p0 = cmp.gt(r6,r4) + \\ if (!p0.new) jump:nt .Lmul_ovf_unf + \\ } + \\ { + \\ r1:0 = convert_d2df(r11:10) + \\ r6 = add(r6,#-1024 -58) + \\ } + \\ { + \\ r1 += asl(r6,#20) + \\ jumpr r31 + \\ } + \\ + \\ .falign + \\ .Lmul_possible_unf: + \\ { + \\ p0 = cmp.eq(r0,#0) + \\ p0 = bitsclr(r1,r4) + \\ if (!p0.new) jumpr:t r31 + \\ r5 = #0x7fff + \\ } + \\ { + \\ p0 = bitsset(r13,r5) + \\ r4 = USR + \\ r5 = #0x030 + \\ } + \\ { + \\ if (p0) r4 = or(r4,r5) + \\ } + \\ { + \\ USR = r4 + \\ } + \\ { + \\ p0 = dfcmp.eq(r1:0,r1:0) + \\ jumpr r31 + \\ } + \\ .falign + \\ .Lmul_ovf_unf: + \\ { + \\ r1:0 = convert_d2df(r11:10) + \\ r13:12 = abs(r11:10) + \\ r7 = add(r6,#-1024 -58) + \\ } + \\ { + \\ r1 += asl(r7,#20) + \\ r7 = extractu(r1,#11,#20) + \\ r4 = ##0x7FEFFFFF + \\ } + \\ { + \\ r7 += add(r6,##-1024 -58) + \\ + \\ r5 = #0 + \\ } + \\ { + \\ p0 = cmp.gt(r7,##1024 +1024 -2) + \\ if (p0.new) jump:nt .Lmul_ovf + \\ } + \\ { + \\ p0 = cmp.gt(r7,#0) + \\ if (p0.new) jump:nt .Lmul_possible_unf + \\ r5 = sub(r6,r5) + \\ r28 = #63 + \\ } + \\ { + \\ r4 = #0 + \\ r5 = sub(#5,r5) + \\ } + \\ { + \\ p3 = cmp.gt(r11,#-1) + \\ r5 = min(r5,r28) + \\ r11:10 = r13:12 + \\ } + \\ { + \\ r28 = USR + \\ r15:14 = extractu(r11:10,r5:4) + \\ } + \\ { + \\ r11:10 = asr(r11:10,r5) + \\ r4 = #0x0030 + \\ r1 = insert(r9,#11,#20) + \\ } + \\ { + \\ p0 = cmp.gtu(r9:8,r15:14) + \\ if (!p0.new) r10 = or(r10,r8) + \\ r11 = setbit(r11,#20 +3) + \\ } + \\ { + \\ r15:14 = neg(r11:10) + \\ p1 = bitsclr(r10,#0x7) + \\ if (!p1.new) r28 = or(r4,r28) + \\ } + \\ { + \\ if (!p3) r11:10 = r15:14 + \\ USR = r28 + \\ } + \\ { + \\ r1:0 = convert_d2df(r11:10) + \\ p0 = dfcmp.eq(r1:0,r1:0) + \\ } + \\ { + \\ r1 = insert(r9,#11 -1,#20 +1) + \\ jumpr r31 + \\ } + \\ .falign + \\ .Lmul_ovf: + \\ + \\ { + \\ r28 = USR + \\ r13:12 = combine(##0x7fefffff,#-1) + \\ r1:0 = r11:10 + \\ } + \\ { + \\ r14 = extractu(r28,#2,#22) + \\ r28 = or(r28,#0x28) + \\ r5:4 = combine(##0x7ff00000,#0) + \\ } + \\ { + \\ USR = r28 + \\ r14 ^= lsr(r1,#31) + \\ r28 = r14 + \\ } + \\ { + \\ p0 = !cmp.eq(r28,#1) + \\ p0 = !cmp.eq(r14,#2) + \\ if (p0.new) r13:12 = r5:4 + \\ p0 = dfcmp.eq(r1:0,r1:0) + \\ } + \\ { + \\ r1:0 = insert(r13:12,#63,#0) + \\ jumpr r31 + \\ } + \\ + \\ .Lmul_abnormal: + \\ { + \\ r13:12 = extractu(r1:0,#63,#0) + \\ r5:4 = extractu(r3:2,#63,#0) + \\ } + \\ { + \\ p3 = cmp.gtu(r13:12,r5:4) + \\ if (!p3.new) r1:0 = r3:2 + \\ if (!p3.new) r3:2 = r1:0 + \\ } + \\ { + \\ + \\ p0 = dfclass(r1:0,#0x0f) + \\ if (!p0.new) jump:nt .Linvalid_nan + \\ if (!p3) r13:12 = r5:4 + \\ if (!p3) r5:4 = r13:12 + \\ } + \\ { + \\ + \\ p1 = dfclass(r1:0,#0x08) + \\ p1 = dfclass(r3:2,#0x0e) + \\ } + \\ { + \\ + \\ + \\ p0 = dfclass(r1:0,#0x08) + \\ p0 = dfclass(r3:2,#0x01) + \\ } + \\ { + \\ if (p1) jump .Ltrue_inf + \\ p2 = dfclass(r3:2,#0x01) + \\ } + \\ { + \\ if (p0) jump .Linvalid_zeroinf + \\ if (p2) jump .Ltrue_zero + \\ r28 = ##0x7c000000 + \\ } + \\ + \\ + \\ + \\ + \\ + \\ { + \\ p0 = bitsclr(r1,r28) + \\ if (p0.new) jump:nt .Lmul_tiny + \\ } + \\ { + \\ r28 = cl0(r5:4) + \\ } + \\ { + \\ r28 = add(r28,#-11) + \\ } + \\ { + \\ r5:4 = asl(r5:4,r28) + \\ } + \\ { + \\ r3:2 = insert(r5:4,#63,#0) + \\ r1 -= asl(r28,#20) + \\ } + \\ jump __hexagon_muldf3 + \\ .Lmul_tiny: + \\ { + \\ r28 = USR + \\ r1:0 = xor(r1:0,r3:2) + \\ } + \\ { + \\ r28 = or(r28,#0x30) + \\ r1:0 = insert(r9:8,#63,#0) + \\ r5 = extractu(r28,#2,#22) + \\ } + \\ { + \\ USR = r28 + \\ p0 = cmp.gt(r5,#1) + \\ if (!p0.new) r0 = #0 + \\ r5 ^= lsr(r1,#31) + \\ } + \\ { + \\ p0 = cmp.eq(r5,#3) + \\ if (!p0.new) r0 = #0 + \\ jumpr r31 + \\ } + \\ .Linvalid_zeroinf: + \\ { + \\ r28 = USR + \\ } + \\ { + \\ r1:0 = #-1 + \\ r28 = or(r28,#2) + \\ } + \\ { + \\ USR = r28 + \\ } + \\ { + \\ p0 = dfcmp.uo(r1:0,r1:0) + \\ jumpr r31 + \\ } + \\ .Linvalid_nan: + \\ { + \\ p0 = dfclass(r3:2,#0x0f) + \\ r28 = convert_df2sf(r1:0) + \\ if (p0.new) r3:2 = r1:0 + \\ } + \\ { + \\ r2 = convert_df2sf(r3:2) + \\ r1:0 = #-1 + \\ jumpr r31 + \\ } + \\ .falign + \\ .Ltrue_zero: + \\ { + \\ r1:0 = r3:2 + \\ r3:2 = r1:0 + \\ } + \\ .Ltrue_inf: + \\ { + \\ r3 = extract(r3,#1,#31) + \\ } + \\ { + \\ r1 ^= asl(r3,#31) + \\ jumpr r31 + \\ } + ); +} + +fn __hexagon_sqrtdf2() align(32) callconv(.naked) noreturn { + asm volatile ( + \\ { + \\ r15:14 = extractu(r1:0,#23 +1,#52 -23) + \\ r28 = extractu(r1,#11,#52 -32) + \\ r5:4 = combine(##0x3f000004,#1) + \\ } + \\ { + \\ p2 = dfclass(r1:0,#0x02) + \\ p2 = cmp.gt(r1,#-1) + \\ if (!p2.new) jump:nt .Lsqrt_abnormal + \\ r9 = or(r5,r14) + \\ } + \\ + \\ .Ldenormal_restart: + \\ { + \\ r11:10 = r1:0 + \\ r7,p0 = sfinvsqrta(r9) + \\ r5 = and(r5,#-16) + \\ r3:2 = #0 + \\ } + \\ { + \\ r3 += sfmpy(r7,r9):lib + \\ r2 += sfmpy(r7,r5):lib + \\ r6 = r5 + \\ + \\ + \\ r9 = and(r28,#1) + \\ } + \\ { + \\ r6 -= sfmpy(r3,r2):lib + \\ r11 = insert(r4,#11 +1,#52 -32) + \\ p1 = cmp.gtu(r9,#0) + \\ } + \\ { + \\ r3 += sfmpy(r3,r6):lib + \\ r2 += sfmpy(r2,r6):lib + \\ r6 = r5 + \\ r9 = mux(p1,#8,#9) + \\ } + \\ { + \\ r6 -= sfmpy(r3,r2):lib + \\ r11:10 = asl(r11:10,r9) + \\ r9 = mux(p1,#3,#2) + \\ } + \\ { + \\ r2 += sfmpy(r2,r6):lib + \\ + \\ r15:14 = asl(r11:10,r9) + \\ } + \\ { + \\ r2 = and(r2,##0x007fffff) + \\ } + \\ { + \\ r2 = add(r2,##0x00800000 - 3) + \\ r9 = mux(p1,#7,#8) + \\ } + \\ { + \\ r8 = asl(r2,r9) + \\ r9 = mux(p1,#15-(1+1),#15-(1+0)) + \\ } + \\ { + \\ r13:12 = mpyu(r8,r15) + \\ } + \\ { + \\ r1:0 = asl(r11:10,#15) + \\ r15:14 = mpyu(r13,r13) + \\ p1 = cmp.eq(r0,r0) + \\ } + \\ { + \\ r1:0 -= asl(r15:14,#15) + \\ r15:14 = mpyu(r13,r12) + \\ p2 = cmp.eq(r0,r0) + \\ } + \\ { + \\ r1:0 -= lsr(r15:14,#16) + \\ p3 = cmp.eq(r0,r0) + \\ } + \\ { + \\ r1:0 = mpyu(r1,r8) + \\ } + \\ { + \\ r13:12 += lsr(r1:0,r9) + \\ r9 = add(r9,#16) + \\ r1:0 = asl(r11:10,#31) + \\ } + \\ + \\ { + \\ r15:14 = mpyu(r13,r13) + \\ r1:0 -= mpyu(r13,r12) + \\ } + \\ { + \\ r1:0 -= asl(r15:14,#31) + \\ r15:14 = mpyu(r12,r12) + \\ } + \\ { + \\ r1:0 -= lsr(r15:14,#33) + \\ } + \\ { + \\ r1:0 = mpyu(r1,r8) + \\ } + \\ { + \\ r13:12 += lsr(r1:0,r9) + \\ r9 = add(r9,#16) + \\ r1:0 = asl(r11:10,#47) + \\ } + \\ + \\ { + \\ r15:14 = mpyu(r13,r13) + \\ } + \\ { + \\ r1:0 -= asl(r15:14,#47) + \\ r15:14 = mpyu(r13,r12) + \\ } + \\ { + \\ r1:0 -= asl(r15:14,#16) + \\ r15:14 = mpyu(r12,r12) + \\ } + \\ { + \\ r1:0 -= lsr(r15:14,#17) + \\ } + \\ { + \\ r1:0 = mpyu(r1,r8) + \\ } + \\ { + \\ r13:12 += lsr(r1:0,r9) + \\ } + \\ { + \\ r3:2 = mpyu(r13,r12) + \\ r5:4 = mpyu(r12,r12) + \\ r15:14 = #0 + \\ r1:0 = #0 + \\ } + \\ { + \\ r3:2 += lsr(r5:4,#33) + \\ r5:4 += asl(r3:2,#33) + \\ p1 = cmp.eq(r0,r0) + \\ } + \\ { + \\ r7:6 = mpyu(r13,r13) + \\ r1:0 = sub(r1:0,r5:4,p1):carry + \\ r9:8 = #1 + \\ } + \\ { + \\ r7:6 += lsr(r3:2,#31) + \\ r9:8 += asl(r13:12,#1) + \\ } + \\ + \\ + \\ + \\ + \\ + \\ { + \\ r15:14 = sub(r11:10,r7:6,p1):carry + \\ r5:4 = sub(r1:0,r9:8,p2):carry + \\ + \\ + \\ + \\ + \\ r7:6 = #1 + \\ r11:10 = #0 + \\ } + \\ { + \\ r3:2 = sub(r15:14,r11:10,p2):carry + \\ r7:6 = add(r13:12,r7:6) + \\ r28 = add(r28,#-0x3ff) + \\ } + \\ { + \\ + \\ if (p2) r13:12 = r7:6 + \\ if (p2) r1:0 = r5:4 + \\ if (p2) r15:14 = r3:2 + \\ } + \\ { + \\ r5:4 = sub(r1:0,r9:8,p3):carry + \\ r7:6 = #1 + \\ r28 = asr(r28,#1) + \\ } + \\ { + \\ r3:2 = sub(r15:14,r11:10,p3):carry + \\ r7:6 = add(r13:12,r7:6) + \\ } + \\ { + \\ if (p3) r13:12 = r7:6 + \\ if (p3) r1:0 = r5:4 + \\ + \\ + \\ + \\ + \\ + \\ r2 = #1 + \\ } + \\ { + \\ p0 = cmp.eq(r1:0,r11:10) + \\ if (!p0.new) r12 = or(r12,r2) + \\ r3 = cl0(r13:12) + \\ r28 = add(r28,#-63) + \\ } + \\ + \\ + \\ + \\ { + \\ r1:0 = convert_ud2df(r13:12) + \\ r28 = add(r28,r3) + \\ } + \\ { + \\ r1 += asl(r28,#52 -32) + \\ jumpr r31 + \\ } + \\ .Lsqrt_abnormal: + \\ { + \\ p0 = dfclass(r1:0,#0x01) + \\ if (p0.new) jumpr:t r31 + \\ } + \\ { + \\ p0 = dfclass(r1:0,#0x10) + \\ if (p0.new) jump:nt .Lsqrt_nan + \\ } + \\ { + \\ p0 = cmp.gt(r1,#-1) + \\ if (!p0.new) jump:nt .Lsqrt_invalid_neg + \\ if (!p0.new) r28 = ##0x7F800001 + \\ } + \\ { + \\ p0 = dfclass(r1:0,#0x08) + \\ if (p0.new) jumpr:nt r31 + \\ } + \\ + \\ + \\ { + \\ r1:0 = extractu(r1:0,#52,#0) + \\ } + \\ { + \\ r28 = add(clb(r1:0),#-11) + \\ } + \\ { + \\ r1:0 = asl(r1:0,r28) + \\ r28 = sub(#1,r28) + \\ } + \\ { + \\ r1 = insert(r28,#1,#52 -32) + \\ } + \\ { + \\ r3:2 = extractu(r1:0,#23 +1,#52 -23) + \\ r5 = ##0x3f000004 + \\ } + \\ { + \\ r9 = or(r5,r2) + \\ r5 = and(r5,#-16) + \\ jump .Ldenormal_restart + \\ } + \\ .Lsqrt_nan: + \\ { + \\ r28 = convert_df2sf(r1:0) + \\ r1:0 = #-1 + \\ jumpr r31 + \\ } + \\ .Lsqrt_invalid_neg: + \\ { + \\ r1:0 = convert_sf2df(r28) + \\ jumpr r31 + \\ } + ); +} + +comptime { + if (builtin.cpu.arch == .hexagon) { + @export(&__hexagon_adddf3, .{ .name = "__hexagon_adddf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_adddf3, .{ .name = "__hexagon_fast_adddf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_subdf3, .{ .name = "__hexagon_subdf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_subdf3, .{ .name = "__hexagon_fast_subdf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_divdf3, .{ .name = "__hexagon_divdf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_divdf3, .{ .name = "__hexagon_fast_divdf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_muldf3, .{ .name = "__hexagon_muldf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_muldf3, .{ .name = "__hexagon_fast_muldf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_sqrtdf2, .{ .name = "__hexagon_sqrtdf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_sqrtdf2, .{ .name = "__hexagon_fast2_sqrtdf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_sqrtdf2, .{ .name = "__hexagon_sqrt", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_divsf3, .{ .name = "__hexagon_divsf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_divsf3, .{ .name = "__hexagon_fast_divsf3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_divsi3, .{ .name = "__hexagon_divsi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_umodsi3, .{ .name = "__hexagon_umodsi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_sqrtf, .{ .name = "__hexagon_sqrtf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_sqrtf, .{ .name = "__hexagon_fast2_sqrtf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_moddi3, .{ .name = "__hexagon_moddi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_divdi3, .{ .name = "__hexagon_divdi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_udivdi3, .{ .name = "__hexagon_udivdi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_umoddi3, .{ .name = "__hexagon_umoddi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_modsi3, .{ .name = "__hexagon_modsi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes, .{ .name = "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__hexagon_udivsi3, .{ .name = "__hexagon_udivsi3", .linkage = common.linkage, .visibility = common.visibility }); + } +} diff --git a/build/compiler_rt/int.zig b/build/compiler_rt/int.zig new file mode 100644 index 00000000..16c504ee --- /dev/null +++ b/build/compiler_rt/int.zig @@ -0,0 +1,664 @@ +//! Builtin functions that operate on integer types + +const builtin = @import("builtin"); +const std = @import("std"); +const testing = std.testing; +const maxInt = std.math.maxInt; +const minInt = std.math.minInt; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); +const udivmod = @import("udivmod.zig").udivmod; +const __divti3 = @import("divti3.zig").__divti3; + +pub const panic = common.panic; + +comptime { + @export(&__divmodti4, .{ .name = "__divmodti4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__divmoddi4, .{ .name = "__divmoddi4", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_aeabi) { + @export(&__aeabi_idiv, .{ .name = "__aeabi_idiv", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_uidiv, .{ .name = "__aeabi_uidiv", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__divsi3, .{ .name = "__divsi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__udivsi3, .{ .name = "__udivsi3", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__divdi3, .{ .name = "__divdi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__udivdi3, .{ .name = "__udivdi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__modsi3, .{ .name = "__modsi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__moddi3, .{ .name = "__moddi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__umodsi3, .{ .name = "__umodsi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__umoddi3, .{ .name = "__umoddi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__divmodsi4, .{ .name = "__divmodsi4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 { + const d = __divti3(a, b); + rem.* = a -% (d * b); + return d; +} + +test "test_divmodti4" { + const cases = [_][4]i128{ + [_]i128{ 0, 1, 0, 0 }, + [_]i128{ 0, -1, 0, 0 }, + [_]i128{ 2, 1, 2, 0 }, + [_]i128{ 2, -1, -2, 0 }, + [_]i128{ -2, 1, -2, 0 }, + [_]i128{ -2, -1, 2, 0 }, + [_]i128{ 7, 5, 1, 2 }, + [_]i128{ -7, 5, -1, -2 }, + [_]i128{ 19, 5, 3, 4 }, + [_]i128{ 19, -5, -3, 4 }, + [_]i128{ @bitCast(@as(u128, 0x80000000000000000000000000000000)), 8, @bitCast(@as(u128, 0xf0000000000000000000000000000000)), 0 }, + [_]i128{ @bitCast(@as(u128, 0x80000000000000000000000000000007)), 8, @bitCast(@as(u128, 0xf0000000000000000000000000000001)), -1 }, + }; + + for (cases) |case| { + try test_one_divmodti4(case[0], case[1], case[2], case[3]); + } +} + +fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !void { + var r: i128 = undefined; + const q: i128 = __divmodti4(a, b, &r); + try testing.expect(q == expected_q and r == expected_r); +} + +pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 { + const d = __divdi3(a, b); + rem.* = a -% (d * b); + return d; +} + +fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void { + var r: i64 = undefined; + const q: i64 = __divmoddi4(a, b, &r); + try testing.expect(q == expected_q and r == expected_r); +} + +const cases__divmoddi4 = + [_][4]i64{ + [_]i64{ 0, 1, 0, 0 }, + [_]i64{ 0, -1, 0, 0 }, + [_]i64{ 2, 1, 2, 0 }, + [_]i64{ 2, -1, -2, 0 }, + [_]i64{ -2, 1, -2, 0 }, + [_]i64{ -2, -1, 2, 0 }, + [_]i64{ 7, 5, 1, 2 }, + [_]i64{ -7, 5, -1, -2 }, + [_]i64{ 19, 5, 3, 4 }, + [_]i64{ 19, -5, -3, 4 }, + [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 }, + [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 }, + }; + +test "test_divmoddi4" { + for (cases__divmoddi4) |case| { + try test_one_divmoddi4(case[0], case[1], case[2], case[3]); + } +} + +pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 { + return udivmod(u64, a, b, maybe_rem); +} + +test "test_udivmoddi4" { + _ = @import("udivmoddi4_test.zig"); +} + +pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 { + // Set aside the sign of the quotient. + const sign: u64 = @bitCast((a ^ b) >> 63); + // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63). + const abs_a = (a ^ (a >> 63)) -% (a >> 63); + const abs_b = (b ^ (b >> 63)) -% (b >> 63); + // Unsigned division + const res = __udivmoddi4(@bitCast(abs_a), @bitCast(abs_b), null); + // Apply sign of quotient to result and return. + return @bitCast((res ^ sign) -% sign); +} + +test "test_divdi3" { + const cases = [_][3]i64{ + [_]i64{ 0, 1, 0 }, + [_]i64{ 0, -1, 0 }, + [_]i64{ 2, 1, 2 }, + [_]i64{ 2, -1, -2 }, + [_]i64{ -2, 1, -2 }, + [_]i64{ -2, -1, 2 }, + + [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))) }, + [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))) }, + [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -2, 0x4000000000000000 }, + [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, @as(i64, @bitCast(@as(u64, 0xC000000000000000))) }, + }; + + for (cases) |case| { + try test_one_divdi3(case[0], case[1], case[2]); + } +} + +fn test_one_divdi3(a: i64, b: i64, expected_q: i64) !void { + const q: i64 = __divdi3(a, b); + try testing.expect(q == expected_q); +} + +pub fn __moddi3(a: i64, b: i64) callconv(.c) i64 { + // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63). + const abs_a = (a ^ (a >> 63)) -% (a >> 63); + const abs_b = (b ^ (b >> 63)) -% (b >> 63); + // Unsigned division + var r: u64 = undefined; + _ = __udivmoddi4(@bitCast(abs_a), @bitCast(abs_b), &r); + // Apply the sign of the dividend and return. + return (@as(i64, @bitCast(r)) ^ (a >> 63)) -% (a >> 63); +} + +test "test_moddi3" { + const cases = [_][3]i64{ + [_]i64{ 0, 1, 0 }, + [_]i64{ 0, -1, 0 }, + [_]i64{ 5, 3, 2 }, + [_]i64{ 5, -3, 2 }, + [_]i64{ -5, 3, -2 }, + [_]i64{ -5, -3, -2 }, + + [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 1, 0 }, + [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -1, 0 }, + [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 2, 0 }, + [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -2, 0 }, + [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 3, -2 }, + [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -3, -2 }, + }; + + for (cases) |case| { + try test_one_moddi3(case[0], case[1], case[2]); + } +} + +fn test_one_moddi3(a: i64, b: i64, expected_r: i64) !void { + const r: i64 = __moddi3(a, b); + try testing.expect(r == expected_r); +} + +pub fn __udivdi3(a: u64, b: u64) callconv(.c) u64 { + return __udivmoddi4(a, b, null); +} + +pub fn __umoddi3(a: u64, b: u64) callconv(.c) u64 { + var r: u64 = undefined; + _ = __udivmoddi4(a, b, &r); + return r; +} + +test "test_umoddi3" { + try test_one_umoddi3(0, 1, 0); + try test_one_umoddi3(2, 1, 0); + try test_one_umoddi3(0x8000000000000000, 1, 0x0); + try test_one_umoddi3(0x8000000000000000, 2, 0x0); + try test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1); +} + +fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void { + const r = __umoddi3(a, b); + try testing.expect(r == expected_r); +} + +pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 { + const d = __divsi3(a, b); + rem.* = a -% (d * b); + return d; +} + +const cases__divmodsi4 = + [_][4]i32{ + [_]i32{ 0, 1, 0, 0 }, + [_]i32{ 0, -1, 0, 0 }, + [_]i32{ 2, 1, 2, 0 }, + [_]i32{ 2, -1, -2, 0 }, + [_]i32{ -2, 1, -2, 0 }, + [_]i32{ -2, -1, 2, 0 }, + [_]i32{ 7, 5, 1, 2 }, + [_]i32{ -7, 5, -1, -2 }, + [_]i32{ 19, 5, 3, 4 }, + [_]i32{ 19, -5, -3, 4 }, + [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 }, + [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 }, + }; + +fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void { + var r: i32 = undefined; + const q: i32 = __divmodsi4(a, b, &r); + try testing.expect(q == expected_q and r == expected_r); +} + +test "test_divmodsi4" { + for (cases__divmodsi4) |case| { + try test_one_divmodsi4(case[0], case[1], case[2], case[3]); + } +} + +pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 { + const d = __udivsi3(a, b); + rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))); + return d; +} + +pub fn __divsi3(n: i32, d: i32) callconv(.c) i32 { + return div_i32(n, d); +} + +fn __aeabi_idiv(n: i32, d: i32) callconv(.{ .arm_aapcs = .{} }) i32 { + return div_i32(n, d); +} + +inline fn div_i32(n: i32, d: i32) i32 { + // Set aside the sign of the quotient. + const sign: u32 = @bitCast((n ^ d) >> 31); + // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). + const abs_n = (n ^ (n >> 31)) -% (n >> 31); + const abs_d = (d ^ (d >> 31)) -% (d >> 31); + // abs(a) / abs(b) + const res = @as(u32, @bitCast(abs_n)) / @as(u32, @bitCast(abs_d)); + // Apply sign of quotient to result and return. + return @bitCast((res ^ sign) -% sign); +} + +test "test_divsi3" { + const cases = [_][3]i32{ + [_]i32{ 0, 1, 0 }, + [_]i32{ 0, -1, 0 }, + [_]i32{ 2, 1, 2 }, + [_]i32{ 2, -1, -2 }, + [_]i32{ -2, 1, -2 }, + [_]i32{ -2, -1, 2 }, + + [_]i32{ @bitCast(@as(u32, 0x80000000)), 1, @bitCast(@as(u32, 0x80000000)) }, + [_]i32{ @bitCast(@as(u32, 0x80000000)), -1, @bitCast(@as(u32, 0x80000000)) }, + [_]i32{ @bitCast(@as(u32, 0x80000000)), -2, 0x40000000 }, + [_]i32{ @bitCast(@as(u32, 0x80000000)), 2, @bitCast(@as(u32, 0xC0000000)) }, + }; + + for (cases) |case| { + try test_one_divsi3(case[0], case[1], case[2]); + } +} + +fn test_one_divsi3(a: i32, b: i32, expected_q: i32) !void { + const q: i32 = __divsi3(a, b); + try testing.expect(q == expected_q); +} + +pub fn __udivsi3(n: u32, d: u32) callconv(.c) u32 { + return div_u32(n, d); +} + +fn __aeabi_uidiv(n: u32, d: u32) callconv(.{ .arm_aapcs = .{} }) u32 { + return div_u32(n, d); +} + +inline fn div_u32(n: u32, d: u32) u32 { + const n_uword_bits: c_uint = 32; + // special cases + if (d == 0) return 0; // ?! + if (n == 0) return 0; + var sr = @as(c_uint, @bitCast(@as(c_int, @clz(d)) - @as(c_int, @clz(n)))); + // 0 <= sr <= n_uword_bits - 1 or sr large + if (sr > n_uword_bits - 1) { + // d > r + return 0; + } + if (sr == n_uword_bits - 1) { + // d == 1 + return n; + } + sr += 1; + // 1 <= sr <= n_uword_bits - 1 + // Not a special case + var q: u32 = n << @intCast(n_uword_bits - sr); + var r: u32 = n >> @intCast(sr); + var carry: u32 = 0; + while (sr > 0) : (sr -= 1) { + // r:q = ((r:q) << 1) | carry + r = (r << 1) | (q >> @intCast(n_uword_bits - 1)); + q = (q << 1) | carry; + // carry = 0; + // if (r.all >= d.all) + // { + // r.all -= d.all; + // carry = 1; + // } + const s = @as(i32, @bitCast(d -% r -% 1)) >> @intCast(n_uword_bits - 1); + carry = @intCast(s & 1); + r -= d & @as(u32, @bitCast(s)); + } + q = (q << 1) | carry; + return q; +} + +test "test_udivsi3" { + const cases = [_][3]u32{ + [_]u32{ 0x00000000, 0x00000001, 0x00000000 }, + [_]u32{ 0x00000000, 0x00000002, 0x00000000 }, + [_]u32{ 0x00000000, 0x00000003, 0x00000000 }, + [_]u32{ 0x00000000, 0x00000010, 0x00000000 }, + [_]u32{ 0x00000000, 0x078644FA, 0x00000000 }, + [_]u32{ 0x00000000, 0x0747AE14, 0x00000000 }, + [_]u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x00000000, 0x80000000, 0x00000000 }, + [_]u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x00000001, 0x00000001, 0x00000001 }, + [_]u32{ 0x00000001, 0x00000002, 0x00000000 }, + [_]u32{ 0x00000001, 0x00000003, 0x00000000 }, + [_]u32{ 0x00000001, 0x00000010, 0x00000000 }, + [_]u32{ 0x00000001, 0x078644FA, 0x00000000 }, + [_]u32{ 0x00000001, 0x0747AE14, 0x00000000 }, + [_]u32{ 0x00000001, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x00000001, 0x80000000, 0x00000000 }, + [_]u32{ 0x00000001, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x00000001, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x00000001, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x00000002, 0x00000001, 0x00000002 }, + [_]u32{ 0x00000002, 0x00000002, 0x00000001 }, + [_]u32{ 0x00000002, 0x00000003, 0x00000000 }, + [_]u32{ 0x00000002, 0x00000010, 0x00000000 }, + [_]u32{ 0x00000002, 0x078644FA, 0x00000000 }, + [_]u32{ 0x00000002, 0x0747AE14, 0x00000000 }, + [_]u32{ 0x00000002, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x00000002, 0x80000000, 0x00000000 }, + [_]u32{ 0x00000002, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x00000002, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x00000002, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x00000003, 0x00000001, 0x00000003 }, + [_]u32{ 0x00000003, 0x00000002, 0x00000001 }, + [_]u32{ 0x00000003, 0x00000003, 0x00000001 }, + [_]u32{ 0x00000003, 0x00000010, 0x00000000 }, + [_]u32{ 0x00000003, 0x078644FA, 0x00000000 }, + [_]u32{ 0x00000003, 0x0747AE14, 0x00000000 }, + [_]u32{ 0x00000003, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x00000003, 0x80000000, 0x00000000 }, + [_]u32{ 0x00000003, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x00000003, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x00000003, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x00000010, 0x00000001, 0x00000010 }, + [_]u32{ 0x00000010, 0x00000002, 0x00000008 }, + [_]u32{ 0x00000010, 0x00000003, 0x00000005 }, + [_]u32{ 0x00000010, 0x00000010, 0x00000001 }, + [_]u32{ 0x00000010, 0x078644FA, 0x00000000 }, + [_]u32{ 0x00000010, 0x0747AE14, 0x00000000 }, + [_]u32{ 0x00000010, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x00000010, 0x80000000, 0x00000000 }, + [_]u32{ 0x00000010, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x00000010, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x00000010, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x078644FA, 0x00000001, 0x078644FA }, + [_]u32{ 0x078644FA, 0x00000002, 0x03C3227D }, + [_]u32{ 0x078644FA, 0x00000003, 0x028216FE }, + [_]u32{ 0x078644FA, 0x00000010, 0x0078644F }, + [_]u32{ 0x078644FA, 0x078644FA, 0x00000001 }, + [_]u32{ 0x078644FA, 0x0747AE14, 0x00000001 }, + [_]u32{ 0x078644FA, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x078644FA, 0x80000000, 0x00000000 }, + [_]u32{ 0x078644FA, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x078644FA, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x078644FA, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x0747AE14, 0x00000001, 0x0747AE14 }, + [_]u32{ 0x0747AE14, 0x00000002, 0x03A3D70A }, + [_]u32{ 0x0747AE14, 0x00000003, 0x026D3A06 }, + [_]u32{ 0x0747AE14, 0x00000010, 0x00747AE1 }, + [_]u32{ 0x0747AE14, 0x078644FA, 0x00000000 }, + [_]u32{ 0x0747AE14, 0x0747AE14, 0x00000001 }, + [_]u32{ 0x0747AE14, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x0747AE14, 0x80000000, 0x00000000 }, + [_]u32{ 0x0747AE14, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x0747AE14, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x0747AE14, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x7FFFFFFF, 0x00000001, 0x7FFFFFFF }, + [_]u32{ 0x7FFFFFFF, 0x00000002, 0x3FFFFFFF }, + [_]u32{ 0x7FFFFFFF, 0x00000003, 0x2AAAAAAA }, + [_]u32{ 0x7FFFFFFF, 0x00000010, 0x07FFFFFF }, + [_]u32{ 0x7FFFFFFF, 0x078644FA, 0x00000011 }, + [_]u32{ 0x7FFFFFFF, 0x0747AE14, 0x00000011 }, + [_]u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000001 }, + [_]u32{ 0x7FFFFFFF, 0x80000000, 0x00000000 }, + [_]u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x80000000, 0x00000001, 0x80000000 }, + [_]u32{ 0x80000000, 0x00000002, 0x40000000 }, + [_]u32{ 0x80000000, 0x00000003, 0x2AAAAAAA }, + [_]u32{ 0x80000000, 0x00000010, 0x08000000 }, + [_]u32{ 0x80000000, 0x078644FA, 0x00000011 }, + [_]u32{ 0x80000000, 0x0747AE14, 0x00000011 }, + [_]u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 }, + [_]u32{ 0x80000000, 0x80000000, 0x00000001 }, + [_]u32{ 0x80000000, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x80000000, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x80000000, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0xFFFFFFFD, 0x00000001, 0xFFFFFFFD }, + [_]u32{ 0xFFFFFFFD, 0x00000002, 0x7FFFFFFE }, + [_]u32{ 0xFFFFFFFD, 0x00000003, 0x55555554 }, + [_]u32{ 0xFFFFFFFD, 0x00000010, 0x0FFFFFFF }, + [_]u32{ 0xFFFFFFFD, 0x078644FA, 0x00000022 }, + [_]u32{ 0xFFFFFFFD, 0x0747AE14, 0x00000023 }, + [_]u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x00000001 }, + [_]u32{ 0xFFFFFFFD, 0x80000000, 0x00000001 }, + [_]u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000001 }, + [_]u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE }, + [_]u32{ 0xFFFFFFFE, 0x00000002, 0x7FFFFFFF }, + [_]u32{ 0xFFFFFFFE, 0x00000003, 0x55555554 }, + [_]u32{ 0xFFFFFFFE, 0x00000010, 0x0FFFFFFF }, + [_]u32{ 0xFFFFFFFE, 0x078644FA, 0x00000022 }, + [_]u32{ 0xFFFFFFFE, 0x0747AE14, 0x00000023 }, + [_]u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000002 }, + [_]u32{ 0xFFFFFFFE, 0x80000000, 0x00000001 }, + [_]u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 }, + [_]u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000001 }, + [_]u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF }, + [_]u32{ 0xFFFFFFFF, 0x00000002, 0x7FFFFFFF }, + [_]u32{ 0xFFFFFFFF, 0x00000003, 0x55555555 }, + [_]u32{ 0xFFFFFFFF, 0x00000010, 0x0FFFFFFF }, + [_]u32{ 0xFFFFFFFF, 0x078644FA, 0x00000022 }, + [_]u32{ 0xFFFFFFFF, 0x0747AE14, 0x00000023 }, + [_]u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000002 }, + [_]u32{ 0xFFFFFFFF, 0x80000000, 0x00000001 }, + [_]u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000001 }, + [_]u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 }, + [_]u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 }, + }; + + for (cases) |case| { + try test_one_udivsi3(case[0], case[1], case[2]); + } +} + +fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void { + const q: u32 = __udivsi3(a, b); + try testing.expect(q == expected_q); +} + +pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 { + return n -% __divsi3(n, d) * d; +} + +test "test_modsi3" { + const cases = [_][3]i32{ + [_]i32{ 0, 1, 0 }, + [_]i32{ 0, -1, 0 }, + [_]i32{ 5, 3, 2 }, + [_]i32{ 5, -3, 2 }, + [_]i32{ -5, 3, -2 }, + [_]i32{ -5, -3, -2 }, + [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 1, 0x0 }, + [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 2, 0x0 }, + [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), -2, 0x0 }, + [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 3, -2 }, + [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), -3, -2 }, + }; + + for (cases) |case| { + try test_one_modsi3(case[0], case[1], case[2]); + } +} + +fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void { + const r: i32 = __modsi3(a, b); + try testing.expect(r == expected_r); +} + +pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 { + return n -% __udivsi3(n, d) * d; +} + +test "test_umodsi3" { + const cases = [_][3]u32{ + [_]u32{ 0x00000000, 0x00000001, 0x00000000 }, + [_]u32{ 0x00000000, 0x00000002, 0x00000000 }, + [_]u32{ 0x00000000, 0x00000003, 0x00000000 }, + [_]u32{ 0x00000000, 0x00000010, 0x00000000 }, + [_]u32{ 0x00000000, 0x078644FA, 0x00000000 }, + [_]u32{ 0x00000000, 0x0747AE14, 0x00000000 }, + [_]u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x00000000, 0x80000000, 0x00000000 }, + [_]u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 }, + [_]u32{ 0x00000001, 0x00000001, 0x00000000 }, + [_]u32{ 0x00000001, 0x00000002, 0x00000001 }, + [_]u32{ 0x00000001, 0x00000003, 0x00000001 }, + [_]u32{ 0x00000001, 0x00000010, 0x00000001 }, + [_]u32{ 0x00000001, 0x078644FA, 0x00000001 }, + [_]u32{ 0x00000001, 0x0747AE14, 0x00000001 }, + [_]u32{ 0x00000001, 0x7FFFFFFF, 0x00000001 }, + [_]u32{ 0x00000001, 0x80000000, 0x00000001 }, + [_]u32{ 0x00000001, 0xFFFFFFFD, 0x00000001 }, + [_]u32{ 0x00000001, 0xFFFFFFFE, 0x00000001 }, + [_]u32{ 0x00000001, 0xFFFFFFFF, 0x00000001 }, + [_]u32{ 0x00000002, 0x00000001, 0x00000000 }, + [_]u32{ 0x00000002, 0x00000002, 0x00000000 }, + [_]u32{ 0x00000002, 0x00000003, 0x00000002 }, + [_]u32{ 0x00000002, 0x00000010, 0x00000002 }, + [_]u32{ 0x00000002, 0x078644FA, 0x00000002 }, + [_]u32{ 0x00000002, 0x0747AE14, 0x00000002 }, + [_]u32{ 0x00000002, 0x7FFFFFFF, 0x00000002 }, + [_]u32{ 0x00000002, 0x80000000, 0x00000002 }, + [_]u32{ 0x00000002, 0xFFFFFFFD, 0x00000002 }, + [_]u32{ 0x00000002, 0xFFFFFFFE, 0x00000002 }, + [_]u32{ 0x00000002, 0xFFFFFFFF, 0x00000002 }, + [_]u32{ 0x00000003, 0x00000001, 0x00000000 }, + [_]u32{ 0x00000003, 0x00000002, 0x00000001 }, + [_]u32{ 0x00000003, 0x00000003, 0x00000000 }, + [_]u32{ 0x00000003, 0x00000010, 0x00000003 }, + [_]u32{ 0x00000003, 0x078644FA, 0x00000003 }, + [_]u32{ 0x00000003, 0x0747AE14, 0x00000003 }, + [_]u32{ 0x00000003, 0x7FFFFFFF, 0x00000003 }, + [_]u32{ 0x00000003, 0x80000000, 0x00000003 }, + [_]u32{ 0x00000003, 0xFFFFFFFD, 0x00000003 }, + [_]u32{ 0x00000003, 0xFFFFFFFE, 0x00000003 }, + [_]u32{ 0x00000003, 0xFFFFFFFF, 0x00000003 }, + [_]u32{ 0x00000010, 0x00000001, 0x00000000 }, + [_]u32{ 0x00000010, 0x00000002, 0x00000000 }, + [_]u32{ 0x00000010, 0x00000003, 0x00000001 }, + [_]u32{ 0x00000010, 0x00000010, 0x00000000 }, + [_]u32{ 0x00000010, 0x078644FA, 0x00000010 }, + [_]u32{ 0x00000010, 0x0747AE14, 0x00000010 }, + [_]u32{ 0x00000010, 0x7FFFFFFF, 0x00000010 }, + [_]u32{ 0x00000010, 0x80000000, 0x00000010 }, + [_]u32{ 0x00000010, 0xFFFFFFFD, 0x00000010 }, + [_]u32{ 0x00000010, 0xFFFFFFFE, 0x00000010 }, + [_]u32{ 0x00000010, 0xFFFFFFFF, 0x00000010 }, + [_]u32{ 0x078644FA, 0x00000001, 0x00000000 }, + [_]u32{ 0x078644FA, 0x00000002, 0x00000000 }, + [_]u32{ 0x078644FA, 0x00000003, 0x00000000 }, + [_]u32{ 0x078644FA, 0x00000010, 0x0000000A }, + [_]u32{ 0x078644FA, 0x078644FA, 0x00000000 }, + [_]u32{ 0x078644FA, 0x0747AE14, 0x003E96E6 }, + [_]u32{ 0x078644FA, 0x7FFFFFFF, 0x078644FA }, + [_]u32{ 0x078644FA, 0x80000000, 0x078644FA }, + [_]u32{ 0x078644FA, 0xFFFFFFFD, 0x078644FA }, + [_]u32{ 0x078644FA, 0xFFFFFFFE, 0x078644FA }, + [_]u32{ 0x078644FA, 0xFFFFFFFF, 0x078644FA }, + [_]u32{ 0x0747AE14, 0x00000001, 0x00000000 }, + [_]u32{ 0x0747AE14, 0x00000002, 0x00000000 }, + [_]u32{ 0x0747AE14, 0x00000003, 0x00000002 }, + [_]u32{ 0x0747AE14, 0x00000010, 0x00000004 }, + [_]u32{ 0x0747AE14, 0x078644FA, 0x0747AE14 }, + [_]u32{ 0x0747AE14, 0x0747AE14, 0x00000000 }, + [_]u32{ 0x0747AE14, 0x7FFFFFFF, 0x0747AE14 }, + [_]u32{ 0x0747AE14, 0x80000000, 0x0747AE14 }, + [_]u32{ 0x0747AE14, 0xFFFFFFFD, 0x0747AE14 }, + [_]u32{ 0x0747AE14, 0xFFFFFFFE, 0x0747AE14 }, + [_]u32{ 0x0747AE14, 0xFFFFFFFF, 0x0747AE14 }, + [_]u32{ 0x7FFFFFFF, 0x00000001, 0x00000000 }, + [_]u32{ 0x7FFFFFFF, 0x00000002, 0x00000001 }, + [_]u32{ 0x7FFFFFFF, 0x00000003, 0x00000001 }, + [_]u32{ 0x7FFFFFFF, 0x00000010, 0x0000000F }, + [_]u32{ 0x7FFFFFFF, 0x078644FA, 0x00156B65 }, + [_]u32{ 0x7FFFFFFF, 0x0747AE14, 0x043D70AB }, + [_]u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF }, + [_]u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF }, + [_]u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF }, + [_]u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }, + [_]u32{ 0x80000000, 0x00000001, 0x00000000 }, + [_]u32{ 0x80000000, 0x00000002, 0x00000000 }, + [_]u32{ 0x80000000, 0x00000003, 0x00000002 }, + [_]u32{ 0x80000000, 0x00000010, 0x00000000 }, + [_]u32{ 0x80000000, 0x078644FA, 0x00156B66 }, + [_]u32{ 0x80000000, 0x0747AE14, 0x043D70AC }, + [_]u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 }, + [_]u32{ 0x80000000, 0x80000000, 0x00000000 }, + [_]u32{ 0x80000000, 0xFFFFFFFD, 0x80000000 }, + [_]u32{ 0x80000000, 0xFFFFFFFE, 0x80000000 }, + [_]u32{ 0x80000000, 0xFFFFFFFF, 0x80000000 }, + [_]u32{ 0xFFFFFFFD, 0x00000001, 0x00000000 }, + [_]u32{ 0xFFFFFFFD, 0x00000002, 0x00000001 }, + [_]u32{ 0xFFFFFFFD, 0x00000003, 0x00000001 }, + [_]u32{ 0xFFFFFFFD, 0x00000010, 0x0000000D }, + [_]u32{ 0xFFFFFFFD, 0x078644FA, 0x002AD6C9 }, + [_]u32{ 0xFFFFFFFD, 0x0747AE14, 0x01333341 }, + [_]u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE }, + [_]u32{ 0xFFFFFFFD, 0x80000000, 0x7FFFFFFD }, + [_]u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000000 }, + [_]u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD }, + [_]u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD }, + [_]u32{ 0xFFFFFFFE, 0x00000001, 0x00000000 }, + [_]u32{ 0xFFFFFFFE, 0x00000002, 0x00000000 }, + [_]u32{ 0xFFFFFFFE, 0x00000003, 0x00000002 }, + [_]u32{ 0xFFFFFFFE, 0x00000010, 0x0000000E }, + [_]u32{ 0xFFFFFFFE, 0x078644FA, 0x002AD6CA }, + [_]u32{ 0xFFFFFFFE, 0x0747AE14, 0x01333342 }, + [_]u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000000 }, + [_]u32{ 0xFFFFFFFE, 0x80000000, 0x7FFFFFFE }, + [_]u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 }, + [_]u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000000 }, + [_]u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE }, + [_]u32{ 0xFFFFFFFF, 0x00000001, 0x00000000 }, + [_]u32{ 0xFFFFFFFF, 0x00000002, 0x00000001 }, + [_]u32{ 0xFFFFFFFF, 0x00000003, 0x00000000 }, + [_]u32{ 0xFFFFFFFF, 0x00000010, 0x0000000F }, + [_]u32{ 0xFFFFFFFF, 0x078644FA, 0x002AD6CB }, + [_]u32{ 0xFFFFFFFF, 0x0747AE14, 0x01333343 }, + [_]u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000001 }, + [_]u32{ 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF }, + [_]u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000002 }, + [_]u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 }, + [_]u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }, + }; + + for (cases) |case| { + try test_one_umodsi3(case[0], case[1], case[2]); + } +} + +fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void { + const r: u32 = __umodsi3(a, b); + try testing.expect(r == expected_r); +} diff --git a/build/compiler_rt/int_from_float.zig b/build/compiler_rt/int_from_float.zig new file mode 100644 index 00000000..0c2c73bb --- /dev/null +++ b/build/compiler_rt/int_from_float.zig @@ -0,0 +1,107 @@ +const std = @import("std"); +const Int = std.meta.Int; +const math = std.math; +const Log2Int = math.Log2Int; + +pub inline fn intFromFloat(comptime I: type, a: anytype) I { + const F = @TypeOf(a); + const float_bits = @typeInfo(F).float.bits; + const int_bits = @typeInfo(I).int.bits; + const rep_t = Int(.unsigned, float_bits); + const sig_bits = math.floatMantissaBits(F); + const exp_bits = math.floatExponentBits(F); + const fractional_bits = math.floatFractionalBits(F); + + const implicit_bit = if (F != f80) (@as(rep_t, 1) << sig_bits) else 0; + const max_exp = (1 << (exp_bits - 1)); + const exp_bias = max_exp - 1; + const sig_mask = (@as(rep_t, 1) << sig_bits) - 1; + + // Break a into sign, exponent, significand + const a_rep: rep_t = @bitCast(a); + const negative = (a_rep >> (float_bits - 1)) != 0; + const exponent = @as(i32, @intCast((a_rep << 1) >> (sig_bits + 1))) - exp_bias; + const significand: rep_t = (a_rep & sig_mask) | implicit_bit; + + // If the exponent is negative, the result rounds to zero. + if (exponent < 0) return 0; + + // If the value is too large for the integer type, saturate. + switch (@typeInfo(I).int.signedness) { + .unsigned => { + if (negative) return 0; + if (@as(c_uint, @intCast(exponent)) >= @min(int_bits, max_exp)) return math.maxInt(I); + }, + .signed => if (@as(c_uint, @intCast(exponent)) >= @min(int_bits - 1, max_exp)) { + return if (negative) math.minInt(I) else math.maxInt(I); + }, + } + + // If 0 <= exponent < sig_bits, right shift to get the result. + // Otherwise, shift left. + var result: I = undefined; + if (exponent < fractional_bits) { + result = @intCast(significand >> @intCast(fractional_bits - exponent)); + } else { + result = @as(I, @intCast(significand)) << @intCast(exponent - fractional_bits); + } + + if ((@typeInfo(I).int.signedness == .signed) and negative) + return ~result +% 1; + return result; +} + +pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void { + switch (result.len) { + 0 => return, + inline 1...4 => |limbs_len| { + result[0..limbs_len].* = @bitCast(@as( + @Type(.{ .int = .{ .signedness = signedness, .bits = 32 * limbs_len } }), + @intFromFloat(a), + )); + return; + }, + else => {}, + } + + // sign implicit fraction + const significand_bits = 1 + math.floatFractionalBits(@TypeOf(a)); + const I = @Type(comptime .{ .int = .{ + .signedness = signedness, + .bits = @as(u16, @intFromBool(signedness == .signed)) + significand_bits, + } }); + + const parts = math.frexp(a); + const significand_bits_adjusted_to_handle_smin = @as(i32, significand_bits) + + @intFromBool(signedness == .signed and parts.exponent == 32 * result.len); + const exponent = @max(parts.exponent - significand_bits_adjusted_to_handle_smin, 0); + const int: I = @intFromFloat(switch (exponent) { + 0 => a, + else => math.ldexp(parts.significand, significand_bits_adjusted_to_handle_smin), + }); + switch (signedness) { + .signed => { + const endian = @import("builtin").cpu.arch.endian(); + const exponent_limb = switch (endian) { + .little => exponent / 32, + .big => result.len - 1 - exponent / 32, + }; + const sign_bits: u32 = if (int < 0) math.maxInt(u32) else 0; + @memset(result[0..exponent_limb], switch (endian) { + .little => 0, + .big => sign_bits, + }); + result[exponent_limb] = sign_bits << @truncate(exponent); + @memset(result[exponent_limb + 1 ..], switch (endian) { + .little => sign_bits, + .big => 0, + }); + }, + .unsigned => @memset(result, 0), + } + std.mem.writePackedIntNative(I, std.mem.sliceAsBytes(result), exponent, int); +} + +test { + _ = @import("int_from_float_test.zig"); +} diff --git a/build/compiler_rt/int_from_float_test.zig b/build/compiler_rt/int_from_float_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/log.zig b/build/compiler_rt/log.zig new file mode 100644 index 00000000..f8bbf430 --- /dev/null +++ b/build/compiler_rt/log.zig @@ -0,0 +1,231 @@ +//! Ported from musl, which is licensed under the MIT license: +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/lnf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/ln.c + +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__logh, .{ .name = "__logh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&logf, .{ .name = "logf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&log, .{ .name = "log", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__logx, .{ .name = "__logx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&logq, .{ .name = "logf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&logq, .{ .name = "logq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&logl, .{ .name = "logl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __logh(a: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(logf(a)); +} + +pub fn logf(x_: f32) callconv(.c) f32 { + const ln2_hi: f32 = 6.9313812256e-01; + const ln2_lo: f32 = 9.0580006145e-06; + const Lg1: f32 = 0xaaaaaa.0p-24; + const Lg2: f32 = 0xccce13.0p-25; + const Lg3: f32 = 0x91e9ee.0p-25; + const Lg4: f32 = 0xf89e26.0p-26; + + var x = x_; + var ix: u32 = @bitCast(x); + var k: i32 = 0; + + // x < 2^(-126) + if (ix < 0x00800000 or ix >> 31 != 0) { + // log(+-0) = -inf + if (ix << 1 == 0) { + return -math.inf(f32); + } + // log(-#) = nan + if (ix >> 31 != 0) { + return math.nan(f32); + } + + // subnormal, scale x + k -= 25; + x *= 0x1.0p25; + ix = @bitCast(x); + } else if (ix >= 0x7F800000) { + return x; + } else if (ix == 0x3F800000) { + return 0; + } + + // x into [sqrt(2) / 2, sqrt(2)] + ix += 0x3F800000 - 0x3F3504F3; + k += @as(i32, @intCast(ix >> 23)) - 0x7F; + ix = (ix & 0x007FFFFF) + 0x3F3504F3; + x = @bitCast(ix); + + const f = x - 1.0; + const s = f / (2.0 + f); + const z = s * s; + const w = z * z; + const t1 = w * (Lg2 + w * Lg4); + const t2 = z * (Lg1 + w * Lg3); + const R = t2 + t1; + const hfsq = 0.5 * f * f; + const dk: f32 = @floatFromInt(k); + + return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; +} + +pub fn log(x_: f64) callconv(.c) f64 { + const ln2_hi: f64 = 6.93147180369123816490e-01; + const ln2_lo: f64 = 1.90821492927058770002e-10; + const Lg1: f64 = 6.666666666666735130e-01; + const Lg2: f64 = 3.999999999940941908e-01; + const Lg3: f64 = 2.857142874366239149e-01; + const Lg4: f64 = 2.222219843214978396e-01; + const Lg5: f64 = 1.818357216161805012e-01; + const Lg6: f64 = 1.531383769920937332e-01; + const Lg7: f64 = 1.479819860511658591e-01; + + var x = x_; + var ix: u64 = @bitCast(x); + var hx: u32 = @intCast(ix >> 32); + var k: i32 = 0; + + if (hx < 0x00100000 or hx >> 31 != 0) { + // log(+-0) = -inf + if (ix << 1 == 0) { + return -math.inf(f64); + } + // log(-#) = nan + if (hx >> 31 != 0) { + return math.nan(f64); + } + + // subnormal, scale x + k -= 54; + x *= 0x1p54; + hx = @intCast(@as(u64, @bitCast(x)) >> 32); + } else if (hx >= 0x7FF00000) { + return x; + } else if (hx == 0x3FF00000 and ix << 32 == 0) { + return 0; + } + + // x into [sqrt(2) / 2, sqrt(2)] + hx += 0x3FF00000 - 0x3FE6A09E; + k += @as(i32, @intCast(hx >> 20)) - 0x3FF; + hx = (hx & 0x000FFFFF) + 0x3FE6A09E; + ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF); + x = @bitCast(ix); + + const f = x - 1.0; + const hfsq = 0.5 * f * f; + const s = f / (2.0 + f); + const z = s * s; + const w = z * z; + const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); + const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); + const R = t2 + t1; + const dk: f64 = @floatFromInt(k); + + return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; +} + +pub fn __logx(a: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(logq(a)); +} + +pub fn logq(a: f128) callconv(.c) f128 { + // TODO: more correct implementation + return log(@floatCast(a)); +} + +pub fn logl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __logh(x), + 32 => return logf(x), + 64 => return log(x), + 80 => return __logx(x), + 128 => return logq(x), + else => @compileError("unreachable"), + } +} + +test "logf() special" { + try expectEqual(logf(0.0), -math.inf(f32)); + try expectEqual(logf(-0.0), -math.inf(f32)); + try expect(math.isPositiveZero(logf(1.0))); + try expectEqual(logf(math.e), 1.0); + try expectEqual(logf(math.inf(f32)), math.inf(f32)); + try expect(math.isNan(logf(-1.0))); + try expect(math.isNan(logf(-math.inf(f32)))); + try expect(math.isNan(logf(math.nan(f32)))); + try expect(math.isNan(logf(math.snan(f32)))); +} + +test "logf() sanity" { + try expect(math.isNan(logf(-0x1.0223a0p+3))); + try expectEqual(logf(0x1.161868p+2), 0x1.7815b0p+0); + try expect(math.isNan(logf(-0x1.0c34b4p+3))); + try expect(math.isNan(logf(-0x1.a206f0p+2))); + try expectEqual(logf(0x1.288bbcp+3), 0x1.1cfcd6p+1); + try expectEqual(logf(0x1.52efd0p-1), -0x1.a6694cp-2); + try expect(math.isNan(logf(-0x1.a05cc8p-2))); + try expectEqual(logf(0x1.1f9efap-1), -0x1.2742bap-1); + try expectEqual(logf(0x1.8c5db0p-1), -0x1.062160p-2); + try expect(math.isNan(logf(-0x1.5b86eap-1))); +} + +test "logf() boundary" { + try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value + try expectEqual(logf(0x1p-149), -0x1.9d1da0p+6); // Min positive input value + try expect(math.isNan(logf(-0x1p-149))); // Min negative input value + try expectEqual(logf(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0 + try expectEqual(logf(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0 + try expectEqual(logf(0x1p-126), -0x1.5d58a0p+6); // First subnormal + try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal +} + +test "log() special" { + try expectEqual(log(0.0), -math.inf(f64)); + try expectEqual(log(-0.0), -math.inf(f64)); + try expect(math.isPositiveZero(log(1.0))); + try expectEqual(log(math.e), 1.0); + try expectEqual(log(math.inf(f64)), math.inf(f64)); + try expect(math.isNan(log(-1.0))); + try expect(math.isNan(log(-math.inf(f64)))); + try expect(math.isNan(log(math.nan(f64)))); + try expect(math.isNan(log(math.snan(f64)))); +} + +test "log() sanity" { + try expect(math.isNan(log(-0x1.02239f3c6a8f1p+3))); + try expectEqual(log(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0); + try expect(math.isNan(log(-0x1.0c34b3e01e6e7p+3))); + try expect(math.isNan(log(-0x1.a206f0a19dcc4p+2))); + try expectEqual(log(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1); + try expectEqual(log(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2); + try expect(math.isNan(log(-0x1.a05cc754481d1p-2))); + try expectEqual(log(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1); + try expectEqual(log(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2); + try expect(math.isNan(log(-0x1.5b86ea8118a0ep-1))); +} + +test "log() boundary" { + try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value + try expectEqual(log(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value + try expect(math.isNan(log(-0x1p-1074))); // Min negative input value + try expectEqual(log(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0 + try expectEqual(log(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0 + try expectEqual(log(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal + try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal +} diff --git a/build/compiler_rt/log10.zig b/build/compiler_rt/log10.zig new file mode 100644 index 00000000..1c2ce4bb --- /dev/null +++ b/build/compiler_rt/log10.zig @@ -0,0 +1,261 @@ +//! Ported from musl, which is licensed under the MIT license: +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/log10f.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/log10.c + +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; +const maxInt = std.math.maxInt; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__log10h, .{ .name = "__log10h", .linkage = common.linkage, .visibility = common.visibility }); + @export(&log10f, .{ .name = "log10f", .linkage = common.linkage, .visibility = common.visibility }); + @export(&log10, .{ .name = "log10", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__log10x, .{ .name = "__log10x", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&log10q, .{ .name = "log10f128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&log10q, .{ .name = "log10q", .linkage = common.linkage, .visibility = common.visibility }); + @export(&log10l, .{ .name = "log10l", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __log10h(a: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(log10f(a)); +} + +pub fn log10f(x_: f32) callconv(.c) f32 { + const ivln10hi: f32 = 4.3432617188e-01; + const ivln10lo: f32 = -3.1689971365e-05; + const log10_2hi: f32 = 3.0102920532e-01; + const log10_2lo: f32 = 7.9034151668e-07; + const Lg1: f32 = 0xaaaaaa.0p-24; + const Lg2: f32 = 0xccce13.0p-25; + const Lg3: f32 = 0x91e9ee.0p-25; + const Lg4: f32 = 0xf89e26.0p-26; + + var x = x_; + var u: u32 = @bitCast(x); + var ix = u; + var k: i32 = 0; + + // x < 2^(-126) + if (ix < 0x00800000 or ix >> 31 != 0) { + // log(+-0) = -inf + if (ix << 1 == 0) { + return -math.inf(f32); + } + // log(-#) = nan + if (ix >> 31 != 0) { + return math.nan(f32); + } + + k -= 25; + x *= 0x1.0p25; + ix = @bitCast(x); + } else if (ix >= 0x7F800000) { + return x; + } else if (ix == 0x3F800000) { + return 0; + } + + // x into [sqrt(2) / 2, sqrt(2)] + ix += 0x3F800000 - 0x3F3504F3; + k += @as(i32, @intCast(ix >> 23)) - 0x7F; + ix = (ix & 0x007FFFFF) + 0x3F3504F3; + x = @bitCast(ix); + + const f = x - 1.0; + const s = f / (2.0 + f); + const z = s * s; + const w = z * z; + const t1 = w * (Lg2 + w * Lg4); + const t2 = z * (Lg1 + w * Lg3); + const R = t2 + t1; + const hfsq = 0.5 * f * f; + + var hi = f - hfsq; + u = @bitCast(hi); + u &= 0xFFFFF000; + hi = @bitCast(u); + const lo = f - hi - hfsq + s * (hfsq + R); + const dk: f32 = @floatFromInt(k); + + return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; +} + +pub fn log10(x_: f64) callconv(.c) f64 { + const ivln10hi: f64 = 4.34294481878168880939e-01; + const ivln10lo: f64 = 2.50829467116452752298e-11; + const log10_2hi: f64 = 3.01029995663611771306e-01; + const log10_2lo: f64 = 3.69423907715893078616e-13; + const Lg1: f64 = 6.666666666666735130e-01; + const Lg2: f64 = 3.999999999940941908e-01; + const Lg3: f64 = 2.857142874366239149e-01; + const Lg4: f64 = 2.222219843214978396e-01; + const Lg5: f64 = 1.818357216161805012e-01; + const Lg6: f64 = 1.531383769920937332e-01; + const Lg7: f64 = 1.479819860511658591e-01; + + var x = x_; + var ix: u64 = @bitCast(x); + var hx: u32 = @intCast(ix >> 32); + var k: i32 = 0; + + if (hx < 0x00100000 or hx >> 31 != 0) { + // log(+-0) = -inf + if (ix << 1 == 0) { + return -math.inf(f64); + } + // log(-#) = nan + if (hx >> 31 != 0) { + return math.nan(f64); + } + + // subnormal, scale x + k -= 54; + x *= 0x1.0p54; + hx = @intCast(@as(u64, @bitCast(x)) >> 32); + } else if (hx >= 0x7FF00000) { + return x; + } else if (hx == 0x3FF00000 and ix << 32 == 0) { + return 0; + } + + // x into [sqrt(2) / 2, sqrt(2)] + hx += 0x3FF00000 - 0x3FE6A09E; + k += @as(i32, @intCast(hx >> 20)) - 0x3FF; + hx = (hx & 0x000FFFFF) + 0x3FE6A09E; + ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF); + x = @bitCast(ix); + + const f = x - 1.0; + const hfsq = 0.5 * f * f; + const s = f / (2.0 + f); + const z = s * s; + const w = z * z; + const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); + const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); + const R = t2 + t1; + + // hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f) + var hi = f - hfsq; + var hii: u64 = @bitCast(hi); + hii &= @as(u64, maxInt(u64)) << 32; + hi = @bitCast(hii); + const lo = f - hi - hfsq + s * (hfsq + R); + + // val_hi + val_lo ~ log10(1 + f) + k * log10(2) + var val_hi = hi * ivln10hi; + const dk: f64 = @floatFromInt(k); + const y = dk * log10_2hi; + var val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi; + + // Extra precision multiplication + const ww = y + val_hi; + val_lo += (y - ww) + val_hi; + val_hi = ww; + + return val_lo + val_hi; +} + +pub fn __log10x(a: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(log10q(a)); +} + +pub fn log10q(a: f128) callconv(.c) f128 { + // TODO: more correct implementation + return log10(@floatCast(a)); +} + +pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __log10h(x), + 32 => return log10f(x), + 64 => return log10(x), + 80 => return __log10x(x), + 128 => return log10q(x), + else => @compileError("unreachable"), + } +} + +test "log10f() special" { + try expectEqual(log10f(0.0), -math.inf(f32)); + try expectEqual(log10f(-0.0), -math.inf(f32)); + try expect(math.isPositiveZero(log10f(1.0))); + try expectEqual(log10f(10.0), 1.0); + try expectEqual(log10f(0.1), -1.0); + try expectEqual(log10f(math.inf(f32)), math.inf(f32)); + try expect(math.isNan(log10f(-1.0))); + try expect(math.isNan(log10f(-math.inf(f32)))); + try expect(math.isNan(log10f(math.nan(f32)))); + try expect(math.isNan(log10f(math.snan(f32)))); +} + +test "log10f() sanity" { + try expect(math.isNan(log10f(-0x1.0223a0p+3))); + try expectEqual(log10f(0x1.161868p+2), 0x1.46a9bcp-1); + try expect(math.isNan(log10f(-0x1.0c34b4p+3))); + try expect(math.isNan(log10f(-0x1.a206f0p+2))); + try expectEqual(log10f(0x1.288bbcp+3), 0x1.ef1300p-1); + try expectEqual(log10f(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit + try expect(math.isNan(log10f(-0x1.a05cc8p-2))); + try expectEqual(log10f(0x1.1f9efap-1), -0x1.0075ccp-2); + try expectEqual(log10f(0x1.8c5db0p-1), -0x1.c75df8p-4); + try expect(math.isNan(log10f(-0x1.5b86eap-1))); +} + +test "log10f() boundary" { + try expectEqual(log10f(0x1.fffffep+127), 0x1.344136p+5); // Max input value + try expectEqual(log10f(0x1p-149), -0x1.66d3e8p+5); // Min positive input value + try expect(math.isNan(log10f(-0x1p-149))); // Min negative input value + try expectEqual(log10f(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0 + try expectEqual(log10f(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0 + try expectEqual(log10f(0x1p-126), -0x1.2f7030p+5); // First subnormal + try expect(math.isNan(log10f(-0x1p-126))); // First negative subnormal +} + +test "log10() special" { + try expectEqual(log10(0.0), -math.inf(f64)); + try expectEqual(log10(-0.0), -math.inf(f64)); + try expect(math.isPositiveZero(log10(1.0))); + try expectEqual(log10(10.0), 1.0); + try expectEqual(log10(0.1), -1.0); + try expectEqual(log10(math.inf(f64)), math.inf(f64)); + try expect(math.isNan(log10(-1.0))); + try expect(math.isNan(log10(-math.inf(f64)))); + try expect(math.isNan(log10(math.nan(f64)))); + try expect(math.isNan(log10(math.snan(f64)))); +} + +test "log10() sanity" { + try expect(math.isNan(log10(-0x1.02239f3c6a8f1p+3))); + try expectEqual(log10(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1); + try expect(math.isNan(log10(-0x1.0c34b3e01e6e7p+3))); + try expect(math.isNan(log10(-0x1.a206f0a19dcc4p+2))); + try expectEqual(log10(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1); + try expectEqual(log10(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3); + try expect(math.isNan(log10(-0x1.a05cc754481d1p-2))); + try expectEqual(log10(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2); + try expectEqual(log10(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4); + try expect(math.isNan(log10(-0x1.5b86ea8118a0ep-1))); +} + +test "log10() boundary" { + try expectEqual(log10(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value + try expectEqual(log10(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value + try expect(math.isNan(log10(-0x1p-1074))); // Min negative input value + try expectEqual(log10(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0 + try expectEqual(log10(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0 + try expectEqual(log10(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal + try expect(math.isNan(log10(-0x1p-1022))); // First negative subnormal +} diff --git a/build/compiler_rt/log2.zig b/build/compiler_rt/log2.zig new file mode 100644 index 00000000..4cedcfe0 --- /dev/null +++ b/build/compiler_rt/log2.zig @@ -0,0 +1,252 @@ +//! Ported from musl, which is licensed under the MIT license: +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/log2f.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/log2.c + +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; +const maxInt = std.math.maxInt; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__log2h, .{ .name = "__log2h", .linkage = common.linkage, .visibility = common.visibility }); + @export(&log2f, .{ .name = "log2f", .linkage = common.linkage, .visibility = common.visibility }); + @export(&log2, .{ .name = "log2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__log2x, .{ .name = "__log2x", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&log2q, .{ .name = "log2f128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&log2q, .{ .name = "log2q", .linkage = common.linkage, .visibility = common.visibility }); + @export(&log2l, .{ .name = "log2l", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __log2h(a: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(log2f(a)); +} + +pub fn log2f(x_: f32) callconv(.c) f32 { + const ivln2hi: f32 = 1.4428710938e+00; + const ivln2lo: f32 = -1.7605285393e-04; + const Lg1: f32 = 0xaaaaaa.0p-24; + const Lg2: f32 = 0xccce13.0p-25; + const Lg3: f32 = 0x91e9ee.0p-25; + const Lg4: f32 = 0xf89e26.0p-26; + + var x = x_; + var u: u32 = @bitCast(x); + var ix = u; + var k: i32 = 0; + + // x < 2^(-126) + if (ix < 0x00800000 or ix >> 31 != 0) { + // log(+-0) = -inf + if (ix << 1 == 0) { + return -math.inf(f32); + } + // log(-#) = nan + if (ix >> 31 != 0) { + return math.nan(f32); + } + + k -= 25; + x *= 0x1.0p25; + ix = @bitCast(x); + } else if (ix >= 0x7F800000) { + return x; + } else if (ix == 0x3F800000) { + return 0; + } + + // x into [sqrt(2) / 2, sqrt(2)] + ix += 0x3F800000 - 0x3F3504F3; + k += @as(i32, @intCast(ix >> 23)) - 0x7F; + ix = (ix & 0x007FFFFF) + 0x3F3504F3; + x = @bitCast(ix); + + const f = x - 1.0; + const s = f / (2.0 + f); + const z = s * s; + const w = z * z; + const t1 = w * (Lg2 + w * Lg4); + const t2 = z * (Lg1 + w * Lg3); + const R = t2 + t1; + const hfsq = 0.5 * f * f; + + var hi = f - hfsq; + u = @bitCast(hi); + u &= 0xFFFFF000; + hi = @bitCast(u); + const lo = f - hi - hfsq + s * (hfsq + R); + return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k)); +} + +pub fn log2(x_: f64) callconv(.c) f64 { + const ivln2hi: f64 = 1.44269504072144627571e+00; + const ivln2lo: f64 = 1.67517131648865118353e-10; + const Lg1: f64 = 6.666666666666735130e-01; + const Lg2: f64 = 3.999999999940941908e-01; + const Lg3: f64 = 2.857142874366239149e-01; + const Lg4: f64 = 2.222219843214978396e-01; + const Lg5: f64 = 1.818357216161805012e-01; + const Lg6: f64 = 1.531383769920937332e-01; + const Lg7: f64 = 1.479819860511658591e-01; + + var x = x_; + var ix: u64 = @bitCast(x); + var hx: u32 = @intCast(ix >> 32); + var k: i32 = 0; + + if (hx < 0x00100000 or hx >> 31 != 0) { + // log(+-0) = -inf + if (ix << 1 == 0) { + return -math.inf(f64); + } + // log(-#) = nan + if (hx >> 31 != 0) { + return math.nan(f64); + } + + // subnormal, scale x + k -= 54; + x *= 0x1.0p54; + hx = @intCast(@as(u64, @bitCast(x)) >> 32); + } else if (hx >= 0x7FF00000) { + return x; + } else if (hx == 0x3FF00000 and ix << 32 == 0) { + return 0; + } + + // x into [sqrt(2) / 2, sqrt(2)] + hx += 0x3FF00000 - 0x3FE6A09E; + k += @as(i32, @intCast(hx >> 20)) - 0x3FF; + hx = (hx & 0x000FFFFF) + 0x3FE6A09E; + ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF); + x = @bitCast(ix); + + const f = x - 1.0; + const hfsq = 0.5 * f * f; + const s = f / (2.0 + f); + const z = s * s; + const w = z * z; + const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); + const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); + const R = t2 + t1; + + // hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f) + var hi = f - hfsq; + var hii = @as(u64, @bitCast(hi)); + hii &= @as(u64, maxInt(u64)) << 32; + hi = @bitCast(hii); + const lo = f - hi - hfsq + s * (hfsq + R); + + var val_hi = hi * ivln2hi; + var val_lo = (lo + hi) * ivln2lo + lo * ivln2hi; + + // spadd(val_hi, val_lo, y) + const y: f64 = @floatFromInt(k); + const ww = y + val_hi; + val_lo += (y - ww) + val_hi; + val_hi = ww; + + return val_lo + val_hi; +} + +pub fn __log2x(a: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(log2q(a)); +} + +pub fn log2q(a: f128) callconv(.c) f128 { + // TODO: more correct implementation + return log2(@floatCast(a)); +} + +pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __log2h(x), + 32 => return log2f(x), + 64 => return log2(x), + 80 => return __log2x(x), + 128 => return log2q(x), + else => @compileError("unreachable"), + } +} + +test "log2f() special" { + try expectEqual(log2f(0.0), -math.inf(f32)); + try expectEqual(log2f(-0.0), -math.inf(f32)); + try expect(math.isPositiveZero(log2f(1.0))); + try expectEqual(log2f(2.0), 1.0); + try expectEqual(log2f(math.inf(f32)), math.inf(f32)); + try expect(math.isNan(log2f(-1.0))); + try expect(math.isNan(log2f(-math.inf(f32)))); + try expect(math.isNan(log2f(math.nan(f32)))); + try expect(math.isNan(log2f(math.snan(f32)))); +} + +test "log2f() sanity" { + try expect(math.isNan(log2f(-0x1.0223a0p+3))); + try expectEqual(log2f(0x1.161868p+2), 0x1.0f49acp+1); + try expect(math.isNan(log2f(-0x1.0c34b4p+3))); + try expect(math.isNan(log2f(-0x1.a206f0p+2))); + try expectEqual(log2f(0x1.288bbcp+3), 0x1.9b2676p+1); + try expectEqual(log2f(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit + try expect(math.isNan(log2f(-0x1.a05cc8p-2))); + try expectEqual(log2f(0x1.1f9efap-1), -0x1.a9f89ap-1); + try expectEqual(log2f(0x1.8c5db0p-1), -0x1.7a2c96p-2); + try expect(math.isNan(log2f(-0x1.5b86eap-1))); +} + +test "log2f() boundary" { + try expectEqual(log2f(0x1.fffffep+127), 0x1p+7); // Max input value + try expectEqual(log2f(0x1p-149), -0x1.2ap+7); // Min positive input value + try expect(math.isNan(log2f(-0x1p-149))); // Min negative input value + try expectEqual(log2f(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0 + try expectEqual(log2f(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0 + try expectEqual(log2f(0x1p-126), -0x1.f8p+6); // First subnormal + try expect(math.isNan(log2f(-0x1p-126))); // First negative subnormal + +} + +test "log2() special" { + try expectEqual(log2(0.0), -math.inf(f64)); + try expectEqual(log2(-0.0), -math.inf(f64)); + try expect(math.isPositiveZero(log2(1.0))); + try expectEqual(log2(2.0), 1.0); + try expectEqual(log2(math.inf(f64)), math.inf(f64)); + try expect(math.isNan(log2(-1.0))); + try expect(math.isNan(log2(-math.inf(f64)))); + try expect(math.isNan(log2(math.nan(f64)))); + try expect(math.isNan(log2(math.snan(f64)))); +} + +test "log2() sanity" { + try expect(math.isNan(log2(-0x1.02239f3c6a8f1p+3))); + try expectEqual(log2(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1); + try expect(math.isNan(log2(-0x1.0c34b3e01e6e7p+3))); + try expect(math.isNan(log2(-0x1.a206f0a19dcc4p+2))); + try expectEqual(log2(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1); + try expectEqual(log2(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1); + try expect(math.isNan(log2(-0x1.a05cc754481d1p-2))); + try expectEqual(log2(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1); + try expectEqual(log2(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2); + try expect(math.isNan(log2(-0x1.5b86ea8118a0ep-1))); +} + +test "log2() boundary" { + try expectEqual(log2(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value + try expectEqual(log2(0x1p-1074), -0x1.0c8p+10); // Min positive input value + try expect(math.isNan(log2(-0x1p-1074))); // Min negative input value + try expectEqual(log2(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0 + try expectEqual(log2(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0 + try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal + try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal +} diff --git a/build/compiler_rt/memcmp.zig b/build/compiler_rt/memcmp.zig new file mode 100644 index 00000000..f332d82e --- /dev/null +++ b/build/compiler_rt/memcmp.zig @@ -0,0 +1,30 @@ +const std = @import("std"); +const common = @import("./common.zig"); + +comptime { + @export(&memcmp, .{ .name = "memcmp", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn memcmp(vl: [*]const u8, vr: [*]const u8, n: usize) callconv(.c) c_int { + var i: usize = 0; + while (i < n) : (i += 1) { + const compared = @as(c_int, vl[i]) -% @as(c_int, vr[i]); + if (compared != 0) return compared; + } + return 0; +} + +test "memcmp" { + const arr0 = &[_]u8{ 1, 1, 1 }; + const arr1 = &[_]u8{ 1, 1, 1 }; + const arr2 = &[_]u8{ 1, 0, 1 }; + const arr3 = &[_]u8{ 1, 2, 1 }; + const arr4 = &[_]u8{ 1, 0xff, 1 }; + + try std.testing.expect(memcmp(arr0, arr1, 3) == 0); + try std.testing.expect(memcmp(arr0, arr2, 3) > 0); + try std.testing.expect(memcmp(arr0, arr3, 3) < 0); + + try std.testing.expect(memcmp(arr0, arr4, 3) < 0); + try std.testing.expect(memcmp(arr4, arr0, 3) > 0); +} diff --git a/build/compiler_rt/memcpy.zig b/build/compiler_rt/memcpy.zig new file mode 100644 index 00000000..a31bbe62 --- /dev/null +++ b/build/compiler_rt/memcpy.zig @@ -0,0 +1,230 @@ +const std = @import("std"); +const assert = std.debug.assert; +const common = @import("./common.zig"); +const builtin = @import("builtin"); + +comptime { + if (builtin.object_format != .c) { + const export_options: std.builtin.ExportOptions = .{ + .name = "memcpy", + .linkage = common.linkage, + .visibility = common.visibility, + }; + + if (builtin.mode == .ReleaseSmall or builtin.zig_backend == .stage2_aarch64) + @export(&memcpySmall, export_options) + else + @export(&memcpyFast, export_options); + } +} + +const Element = common.PreferredLoadStoreElement; + +comptime { + assert(std.math.isPowerOfTwo(@sizeOf(Element))); +} + +fn memcpySmall(noalias dest: ?[*]u8, noalias src: ?[*]const u8, len: usize) callconv(.c) ?[*]u8 { + @setRuntimeSafety(false); + + for (0..len) |i| { + dest.?[i] = src.?[i]; + } + + return dest; +} + +fn memcpyFast(noalias dest: ?[*]u8, noalias src: ?[*]const u8, len: usize) callconv(.c) ?[*]u8 { + @setRuntimeSafety(false); + + const small_limit = 2 * @sizeOf(Element); + + if (copySmallLength(small_limit, dest.?, src.?, len)) return dest; + + copyForwards(dest.?, src.?, len); + + return dest; +} + +inline fn copySmallLength( + comptime small_limit: comptime_int, + dest: [*]u8, + src: [*]const u8, + len: usize, +) bool { + if (len < 16) { + copyLessThan16(dest, src, len); + return true; + } + + if (comptime 2 < (std.math.log2(small_limit) + 1) / 2) { + if (copy16ToSmallLimit(small_limit, dest, src, len)) return true; + } + + return false; +} + +inline fn copyLessThan16( + dest: [*]u8, + src: [*]const u8, + len: usize, +) void { + @setRuntimeSafety(false); + if (len < 4) { + if (len == 0) return; + dest[0] = src[0]; + dest[len / 2] = src[len / 2]; + dest[len - 1] = src[len - 1]; + return; + } + copyRange4(4, dest, src, len); +} + +inline fn copy16ToSmallLimit( + comptime small_limit: comptime_int, + dest: [*]u8, + src: [*]const u8, + len: usize, +) bool { + @setRuntimeSafety(false); + inline for (2..(std.math.log2(small_limit) + 1) / 2 + 1) |p| { + const limit = 1 << (2 * p); + if (len < limit) { + copyRange4(limit / 4, dest, src, len); + return true; + } + } + return false; +} + +inline fn copyForwards( + noalias dest: [*]u8, + noalias src: [*]const u8, + len: usize, +) void { + @setRuntimeSafety(false); + + copyFixedLength(dest, src, @sizeOf(Element)); + const alignment_offset = @alignOf(Element) - @intFromPtr(src) % @alignOf(Element); + const n = len - alignment_offset; + const d = dest + alignment_offset; + const s = src + alignment_offset; + + copyBlocksAlignedSource(@ptrCast(d), @ptrCast(@alignCast(s)), n); + + // copy last `@sizeOf(Element)` bytes unconditionally, since block copy + // methods only copy a multiple of `@sizeOf(Element)` bytes. + const offset = len - @sizeOf(Element); + copyFixedLength(dest + offset, src + offset, @sizeOf(Element)); +} + +inline fn copyBlocksAlignedSource( + noalias dest: [*]align(1) Element, + noalias src: [*]const Element, + max_bytes: usize, +) void { + copyBlocks(dest, src, max_bytes); +} + +/// Copies the largest multiple of `@sizeOf(T)` bytes from `src` to `dest`, +/// that is less than `max_bytes` where `T` is the child type of `src` and +/// `dest`. +inline fn copyBlocks( + noalias dest: anytype, + noalias src: anytype, + max_bytes: usize, +) void { + @setRuntimeSafety(false); + + const T = @typeInfo(@TypeOf(dest)).pointer.child; + comptime assert(T == @typeInfo(@TypeOf(src)).pointer.child); + + const loop_count = max_bytes / @sizeOf(T); + + for (dest[0..loop_count], src[0..loop_count]) |*d, s| { + d.* = s; + } +} + +inline fn copyFixedLength( + noalias dest: [*]u8, + noalias src: [*]const u8, + comptime len: comptime_int, +) void { + @setRuntimeSafety(false); + comptime assert(std.math.isPowerOfTwo(len)); + + const T = if (len >= @sizeOf(Element)) + Element + else if (len > @sizeOf(usize)) + @Vector(len, u8) + else + @Type(.{ .int = .{ .signedness = .unsigned, .bits = len * 8 } }); + + const loop_count = @divExact(len, @sizeOf(T)); + + const d: [*]align(1) T = @ptrCast(dest); + const s: [*]align(1) const T = @ptrCast(src); + + inline for (0..loop_count) |i| { + d[i] = s[i]; + } +} + +/// copy `len` bytes from `src` to `dest`; `len` must be in the range +/// `[copy_len, 4 * copy_len)`. +inline fn copyRange4( + comptime copy_len: comptime_int, + noalias dest: [*]u8, + noalias src: [*]const u8, + len: usize, +) void { + @setRuntimeSafety(false); + comptime assert(std.math.isPowerOfTwo(copy_len)); + + const a = len & (copy_len * 2); + const b = a / 2; + + const last = len - copy_len; + const pen = last - b; + + copyFixedLength(dest, src, copy_len); + copyFixedLength(dest + b, src + b, copy_len); + copyFixedLength(dest + pen, src + pen, copy_len); + copyFixedLength(dest + last, src + last, copy_len); +} + +test "memcpy" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + + const S = struct { + fn testFunc(comptime copy_func: anytype) !void { + const max_len = 1024; + var buffer: [max_len + @alignOf(Element) - 1]u8 align(@alignOf(Element)) = undefined; + for (&buffer, 0..) |*b, i| { + b.* = @intCast(i % 97); + } + var dest: [max_len + @alignOf(Element) - 1]u8 align(@alignOf(Element)) = undefined; + + for (0..max_len) |copy_len| { + for (0..@alignOf(Element)) |s_offset| { + for (0..@alignOf(Element)) |d_offset| { + @memset(&dest, 0xff); + const s = buffer[s_offset..][0..copy_len]; + const d = dest[d_offset..][0..copy_len]; + _ = copy_func(@ptrCast(d.ptr), @ptrCast(s.ptr), s.len); + std.testing.expectEqualSlices(u8, s, d) catch |e| { + std.debug.print("error encountered for length={d}, s_offset={d}, d_offset={d}\n", .{ + copy_len, s_offset, d_offset, + }); + return e; + }; + } + } + } + } + }; + + try S.testFunc(memcpySmall); + try S.testFunc(memcpyFast); +} diff --git a/build/compiler_rt/memmove.zig b/build/compiler_rt/memmove.zig new file mode 100644 index 00000000..c57ba9c3 --- /dev/null +++ b/build/compiler_rt/memmove.zig @@ -0,0 +1,252 @@ +const std = @import("std"); +const common = @import("./common.zig"); +const builtin = @import("builtin"); +const assert = std.debug.assert; +const memcpy = @import("memcpy.zig"); + +const Element = common.PreferredLoadStoreElement; + +comptime { + if (builtin.object_format != .c) { + const export_options: std.builtin.ExportOptions = .{ + .name = "memmove", + .linkage = common.linkage, + .visibility = common.visibility, + }; + + if (builtin.mode == .ReleaseSmall or builtin.zig_backend == .stage2_aarch64) + @export(&memmoveSmall, export_options) + else + @export(&memmoveFast, export_options); + } +} + +fn memmoveSmall(opt_dest: ?[*]u8, opt_src: ?[*]const u8, len: usize) callconv(.c) ?[*]u8 { + const dest = opt_dest.?; + const src = opt_src.?; + + if (@intFromPtr(dest) < @intFromPtr(src)) { + for (0..len) |i| { + dest[i] = src[i]; + } + } else { + for (0..len) |i| { + dest[len - 1 - i] = src[len - 1 - i]; + } + } + + return dest; +} + +fn memmoveFast(dest: ?[*]u8, src: ?[*]u8, len: usize) callconv(.c) ?[*]u8 { + @setRuntimeSafety(common.test_safety); + const small_limit = @max(2 * @sizeOf(Element), @sizeOf(Element)); + + if (copySmallLength(small_limit, dest.?, src.?, len)) return dest; + + const dest_address = @intFromPtr(dest); + const src_address = @intFromPtr(src); + + if (src_address < dest_address) { + copyBackwards(dest.?, src.?, len); + } else { + copyForwards(dest.?, src.?, len); + } + + return dest; +} + +inline fn copySmallLength( + comptime small_limit: comptime_int, + dest: [*]u8, + src: [*]const u8, + len: usize, +) bool { + if (len < 16) { + copyLessThan16(dest, src, len); + return true; + } + + if (comptime 2 < (std.math.log2(small_limit) + 1) / 2) { + if (copy16ToSmallLimit(small_limit, dest, src, len)) return true; + } + + return false; +} + +inline fn copyLessThan16( + dest: [*]u8, + src: [*]const u8, + len: usize, +) void { + @setRuntimeSafety(common.test_safety); + if (len < 4) { + if (len == 0) return; + const b = len / 2; + const d0 = src[0]; + const db = src[b]; + const de = src[len - 1]; + dest[0] = d0; + dest[b] = db; + dest[len - 1] = de; + return; + } + copyRange4(4, dest, src, len); +} + +inline fn copy16ToSmallLimit( + comptime small_limit: comptime_int, + dest: [*]u8, + src: [*]const u8, + len: usize, +) bool { + @setRuntimeSafety(common.test_safety); + inline for (2..(std.math.log2(small_limit) + 1) / 2 + 1) |p| { + const limit = 1 << (2 * p); + if (len < limit) { + copyRange4(limit / 4, dest, src, len); + return true; + } + } + return false; +} + +/// copy `len` bytes from `src` to `dest`; `len` must be in the range +/// `[copy_len, 4 * copy_len)`. +inline fn copyRange4( + comptime copy_len: comptime_int, + dest: [*]u8, + src: [*]const u8, + len: usize, +) void { + @setRuntimeSafety(common.test_safety); + comptime assert(std.math.isPowerOfTwo(copy_len)); + assert(len >= copy_len); + assert(len < 4 * copy_len); + + const a = len & (copy_len * 2); + const b = a / 2; + + const last = len - copy_len; + const pen = last - b; + + const d0 = src[0..copy_len].*; + const d1 = src[b..][0..copy_len].*; + const d2 = src[pen..][0..copy_len].*; + const d3 = src[last..][0..copy_len].*; + + // the slice dest[0..len] is needed to workaround -ODebug miscompilation + dest[0..len][0..copy_len].* = d0; + dest[b..][0..copy_len].* = d1; + dest[pen..][0..copy_len].* = d2; + dest[last..][0..copy_len].* = d3; +} + +inline fn copyForwards( + dest: [*]u8, + src: [*]const u8, + len: usize, +) void { + @setRuntimeSafety(common.test_safety); + assert(len >= 2 * @sizeOf(Element)); + + const head = src[0..@sizeOf(Element)].*; + const tail = src[len - @sizeOf(Element) ..][0..@sizeOf(Element)].*; + const alignment_offset = @alignOf(Element) - @intFromPtr(src) % @alignOf(Element); + const n = len - alignment_offset; + const d = dest + alignment_offset; + const s = src + alignment_offset; + + copyBlocksAlignedSource(@ptrCast(d), @ptrCast(@alignCast(s)), n); + + // copy last `copy_size` bytes unconditionally, since block copy + // methods only copy a multiple of `copy_size` bytes. + dest[len - @sizeOf(Element) ..][0..@sizeOf(Element)].* = tail; + dest[0..@sizeOf(Element)].* = head; +} + +inline fn copyBlocksAlignedSource( + dest: [*]align(1) Element, + src: [*]const Element, + max_bytes: usize, +) void { + copyBlocks(dest, src, max_bytes); +} + +/// Copies the largest multiple of `@sizeOf(T)` bytes from `src` to `dest`, +/// that is less than `max_bytes` where `T` is the child type of `src` and +/// `dest`; `max_bytes` must be at least `@sizeOf(T)`. +inline fn copyBlocks( + dest: anytype, + src: anytype, + max_bytes: usize, +) void { + @setRuntimeSafety(common.test_safety); + + const T = @typeInfo(@TypeOf(dest)).pointer.child; + comptime assert(T == @typeInfo(@TypeOf(src)).pointer.child); + + const loop_count = max_bytes / @sizeOf(T); + + for (dest[0..loop_count], src[0..loop_count]) |*d, s| { + d.* = s; + } +} + +inline fn copyBackwards( + dest: [*]u8, + src: [*]const u8, + len: usize, +) void { + const end_bytes = src[len - @sizeOf(Element) ..][0..@sizeOf(Element)].*; + const start_bytes = src[0..@sizeOf(Element)].*; + + const d_addr: usize = std.mem.alignBackward(usize, @intFromPtr(dest) + len, @alignOf(Element)); + const d: [*]Element = @ptrFromInt(d_addr); + const n = d_addr - @intFromPtr(dest); + const s: [*]align(1) const Element = @ptrCast(src + n); + + const loop_count = n / @sizeOf(Element); + var i: usize = 1; + while (i < loop_count + 1) : (i += 1) { + (d - i)[0] = (s - i)[0]; + } + + dest[0..@sizeOf(Element)].* = start_bytes; + dest[len - @sizeOf(Element) ..][0..@sizeOf(Element)].* = end_bytes; +} + +test memmoveFast { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + + const max_len = 1024; + var buffer: [max_len + @alignOf(Element) - 1]u8 = undefined; + for (&buffer, 0..) |*b, i| { + b.* = @intCast(i % 97); + } + + var move_buffer: [max_len + @alignOf(Element) - 1]u8 align(@alignOf(Element)) = undefined; + + for (0..max_len) |copy_len| { + for (0..@alignOf(Element)) |s_offset| { + for (0..@alignOf(Element)) |d_offset| { + for (&move_buffer, buffer) |*d, s| { + d.* = s; + } + const dest = move_buffer[d_offset..][0..copy_len]; + const src = move_buffer[s_offset..][0..copy_len]; + _ = memmoveFast(dest.ptr, src.ptr, copy_len); + std.testing.expectEqualSlices(u8, buffer[s_offset..][0..copy_len], dest) catch |e| { + std.debug.print( + "error occured with source offset {d} and destination offset {d}\n", + .{ + s_offset, + d_offset, + }, + ); + return e; + }; + } + } + } +} diff --git a/build/compiler_rt/memset.zig b/build/compiler_rt/memset.zig new file mode 100644 index 00000000..6b51037b --- /dev/null +++ b/build/compiler_rt/memset.zig @@ -0,0 +1,33 @@ +const std = @import("std"); +const common = @import("./common.zig"); +const builtin = @import("builtin"); + +comptime { + if (builtin.object_format != .c) { + @export(&memset, .{ .name = "memset", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__memset, .{ .name = "__memset", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.c) ?[*]u8 { + @setRuntimeSafety(false); + + if (len != 0) { + var d = dest.?; + var n = len; + while (true) { + d[0] = c; + n -= 1; + if (n == 0) break; + d += 1; + } + } + + return dest; +} + +pub fn __memset(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.c) ?[*]u8 { + if (dest_n < n) + @panic("buffer overflow"); + return memset(dest, c, n); +} diff --git a/build/compiler_rt/modti3.zig b/build/compiler_rt/modti3.zig new file mode 100644 index 00000000..b73f3d05 --- /dev/null +++ b/build/compiler_rt/modti3.zig @@ -0,0 +1,44 @@ +//! Ported from: +//! +//! https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/modti3.c + +const std = @import("std"); +const builtin = @import("builtin"); +const udivmod = @import("udivmod.zig").udivmod; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__modti3, .{ .name = "__modti3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __modti3(a: i128, b: i128) callconv(.c) i128 { + return mod(a, b); +} + +const v2u64 = @Vector(2, u64); + +fn __modti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.c) v2u64 { + return @bitCast(mod(@as(i128, @bitCast(a)), @as(i128, @bitCast(b)))); +} + +inline fn mod(a: i128, b: i128) i128 { + const s_a = a >> (128 - 1); // s = a < 0 ? -1 : 0 + const s_b = b >> (128 - 1); // s = b < 0 ? -1 : 0 + + const an = (a ^ s_a) -% s_a; // negate if s == -1 + const bn = (b ^ s_b) -% s_b; // negate if s == -1 + + var r: u128 = undefined; + _ = udivmod(u128, @as(u128, @bitCast(an)), @as(u128, @bitCast(bn)), &r); + return (@as(i128, @bitCast(r)) ^ s_a) -% s_a; // negate if s == -1 +} + +test { + _ = @import("modti3_test.zig"); +} diff --git a/build/compiler_rt/modti3_test.zig b/build/compiler_rt/modti3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/mulXi3.zig b/build/compiler_rt/mulXi3.zig new file mode 100644 index 00000000..a96ef135 --- /dev/null +++ b/build/compiler_rt/mulXi3.zig @@ -0,0 +1,101 @@ +const builtin = @import("builtin"); +const std = @import("std"); +const testing = std.testing; +const common = @import("common.zig"); +const native_endian = builtin.cpu.arch.endian(); + +pub const panic = common.panic; + +comptime { + @export(&__mulsi3, .{ .name = "__mulsi3", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_aeabi) { + @export(&__aeabi_lmul, .{ .name = "__aeabi_lmul", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__muldi3, .{ .name = "__muldi3", .linkage = common.linkage, .visibility = common.visibility }); + } + if (common.want_windows_v2u64_abi) { + @export(&__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__multi3, .{ .name = "__multi3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __mulsi3(a: i32, b: i32) callconv(.c) i32 { + var ua: u32 = @bitCast(a); + var ub: u32 = @bitCast(b); + var r: u32 = 0; + + while (ua > 0) { + if ((ua & 1) != 0) r +%= ub; + ua >>= 1; + ub <<= 1; + } + + return @bitCast(r); +} + +pub fn __muldi3(a: i64, b: i64) callconv(.c) i64 { + return mulX(i64, a, b); +} + +fn __aeabi_lmul(a: i64, b: i64) callconv(.{ .arm_aapcs = .{} }) i64 { + return mulX(i64, a, b); +} + +inline fn mulX(comptime T: type, a: T, b: T) T { + const word_t = common.HalveInt(T, false); + const x = word_t{ .all = a }; + const y = word_t{ .all = b }; + var r = switch (T) { + i64, i128 => word_t{ .all = muldXi(word_t.HalfT, x.s.low, y.s.low) }, + else => unreachable, + }; + r.s.high +%= x.s.high *% y.s.low +% x.s.low *% y.s.high; + return r.all; +} + +fn DoubleInt(comptime T: type) type { + return switch (T) { + u32 => i64, + u64 => i128, + i32 => i64, + i64 => i128, + else => unreachable, + }; +} + +fn muldXi(comptime T: type, a: T, b: T) DoubleInt(T) { + const DT = DoubleInt(T); + const word_t = common.HalveInt(DT, false); + const bits_in_word_2 = @sizeOf(T) * 8 / 2; + const lower_mask = (~@as(T, 0)) >> bits_in_word_2; + + var r: word_t = undefined; + r.s.low = (a & lower_mask) *% (b & lower_mask); + var t: T = r.s.low >> bits_in_word_2; + r.s.low &= lower_mask; + t += (a >> bits_in_word_2) *% (b & lower_mask); + r.s.low +%= (t & lower_mask) << bits_in_word_2; + r.s.high = t >> bits_in_word_2; + t = r.s.low >> bits_in_word_2; + r.s.low &= lower_mask; + t +%= (b >> bits_in_word_2) *% (a & lower_mask); + r.s.low +%= (t & lower_mask) << bits_in_word_2; + r.s.high +%= t >> bits_in_word_2; + r.s.high +%= (a >> bits_in_word_2) *% (b >> bits_in_word_2); + return r.all; +} + +pub fn __multi3(a: i128, b: i128) callconv(.c) i128 { + return mulX(i128, a, b); +} + +const v2u64 = @Vector(2, u64); + +fn __multi3_windows_x86_64(a: v2u64, b: v2u64) callconv(.c) v2u64 { + return @bitCast(mulX(i128, @as(i128, @bitCast(a)), @as(i128, @bitCast(b)))); +} + +test { + _ = @import("mulXi3_test.zig"); +} diff --git a/build/compiler_rt/mulXi3_test.zig b/build/compiler_rt/mulXi3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/mulc3.zig b/build/compiler_rt/mulc3.zig new file mode 100644 index 00000000..eea75324 --- /dev/null +++ b/build/compiler_rt/mulc3.zig @@ -0,0 +1,79 @@ +const std = @import("std"); +const isNan = std.math.isNan; +const isInf = std.math.isInf; +const copysign = std.math.copysign; + +pub fn Complex(comptime T: type) type { + return extern struct { + real: T, + imag: T, + }; +} + +/// Implementation based on Annex G of C17 Standard (N2176) +pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Complex(T) { + var a = a_in; + var b = b_in; + var c = c_in; + var d = d_in; + + const ac = a * c; + const bd = b * d; + const ad = a * d; + const bc = b * c; + + const zero: T = 0.0; + const one: T = 1.0; + + const z: Complex(T) = .{ + .real = ac - bd, + .imag = ad + bc, + }; + if (isNan(z.real) and isNan(z.imag)) { + var recalc: bool = false; + + if (isInf(a) or isInf(b)) { // (a + ib) is infinite + + // "Box" the infinity (+/-inf goes to +/-1, all finite values go to 0) + a = copysign(if (isInf(a)) one else zero, a); + b = copysign(if (isInf(b)) one else zero, b); + + // Replace NaNs in the other factor with (signed) 0 + if (isNan(c)) c = copysign(zero, c); + if (isNan(d)) d = copysign(zero, d); + + recalc = true; + } + + if (isInf(c) or isInf(d)) { // (c + id) is infinite + + // "Box" the infinity (+/-inf goes to +/-1, all finite values go to 0) + c = copysign(if (isInf(c)) one else zero, c); + d = copysign(if (isInf(d)) one else zero, d); + + // Replace NaNs in the other factor with (signed) 0 + if (isNan(a)) a = copysign(zero, a); + if (isNan(b)) b = copysign(zero, b); + + recalc = true; + } + + if (!recalc and (isInf(ac) or isInf(bd) or isInf(ad) or isInf(bc))) { + + // Recover infinities from overflow by changing NaNs to 0 + if (isNan(a)) a = copysign(zero, a); + if (isNan(b)) b = copysign(zero, b); + if (isNan(c)) c = copysign(zero, c); + if (isNan(d)) d = copysign(zero, d); + + recalc = true; + } + if (recalc) { + return .{ + .real = std.math.inf(T) * (a * c - b * d), + .imag = std.math.inf(T) * (a * d + b * c), + }; + } + } + return z; +} diff --git a/build/compiler_rt/mulc3_test.zig b/build/compiler_rt/mulc3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/muldc3.zig b/build/compiler_rt/muldc3.zig new file mode 100644 index 00000000..1c53b4d0 --- /dev/null +++ b/build/compiler_rt/muldc3.zig @@ -0,0 +1,14 @@ +const common = @import("./common.zig"); +const mulc3 = @import("./mulc3.zig"); + +pub const panic = common.panic; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + @export(&__muldc3, .{ .name = "__muldc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __muldc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) mulc3.Complex(f64) { + return mulc3.mulc3(f64, a, b, c, d); +} diff --git a/build/compiler_rt/muldf3.zig b/build/compiler_rt/muldf3.zig new file mode 100644 index 00000000..1fa4c9de --- /dev/null +++ b/build/compiler_rt/muldf3.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const mulf3 = @import("./mulf3.zig").mulf3; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_dmul, .{ .name = "__aeabi_dmul", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__muldf3, .{ .name = "__muldf3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __muldf3(a: f64, b: f64) callconv(.c) f64 { + return mulf3(f64, a, b); +} + +fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return mulf3(f64, a, b); +} diff --git a/build/compiler_rt/mulf3.zig b/build/compiler_rt/mulf3.zig new file mode 100644 index 00000000..34d39fb9 --- /dev/null +++ b/build/compiler_rt/mulf3.zig @@ -0,0 +1,203 @@ +const std = @import("std"); +const math = std.math; +const builtin = @import("builtin"); +const common = @import("./common.zig"); + +/// Ported from: +/// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc +pub inline fn mulf3(comptime T: type, a: T, b: T) T { + @setRuntimeSafety(common.test_safety); + const typeWidth = @typeInfo(T).float.bits; + const significandBits = math.floatMantissaBits(T); + const fractionalBits = math.floatFractionalBits(T); + const exponentBits = math.floatExponentBits(T); + + const Z = std.meta.Int(.unsigned, typeWidth); + + // ZSignificand is large enough to contain the significand, including an explicit integer bit + const ZSignificand = PowerOfTwoSignificandZ(T); + const ZSignificandBits = @typeInfo(ZSignificand).int.bits; + + const roundBit = (1 << (ZSignificandBits - 1)); + const signBit = (@as(Z, 1) << (significandBits + exponentBits)); + const maxExponent = ((1 << exponentBits) - 1); + const exponentBias = (maxExponent >> 1); + + const integerBit = (@as(ZSignificand, 1) << fractionalBits); + const quietBit = integerBit >> 1; + const significandMask = (@as(Z, 1) << significandBits) - 1; + + const absMask = signBit - 1; + const qnanRep = @as(Z, @bitCast(math.nan(T))) | quietBit; + const infRep: Z = @bitCast(math.inf(T)); + const minNormalRep: Z = @bitCast(math.floatMin(T)); + + const ZExp = if (typeWidth >= 32) u32 else Z; + const aExponent: ZExp = @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent); + const bExponent: ZExp = @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent); + const productSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit; + + var aSignificand: ZSignificand = @intCast(@as(Z, @bitCast(a)) & significandMask); + var bSignificand: ZSignificand = @intCast(@as(Z, @bitCast(b)) & significandMask); + var scale: i32 = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { + const aAbs: Z = @as(Z, @bitCast(a)) & absMask; + const bAbs: Z = @as(Z, @bitCast(b)) & absMask; + + // NaN * anything = qNaN + if (aAbs > infRep) return @bitCast(@as(Z, @bitCast(a)) | quietBit); + // anything * NaN = qNaN + if (bAbs > infRep) return @bitCast(@as(Z, @bitCast(b)) | quietBit); + + if (aAbs == infRep) { + // infinity * non-zero = +/- infinity + if (bAbs != 0) { + return @bitCast(aAbs | productSign); + } else { + // infinity * zero = NaN + return @bitCast(qnanRep); + } + } + + if (bAbs == infRep) { + //? non-zero * infinity = +/- infinity + if (aAbs != 0) { + return @bitCast(bAbs | productSign); + } else { + // zero * infinity = NaN + return @bitCast(qnanRep); + } + } + + // zero * anything = +/- zero + if (aAbs == 0) return @bitCast(productSign); + // anything * zero = +/- zero + if (bAbs == 0) return @bitCast(productSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < minNormalRep) scale += normalize(T, &aSignificand); + if (bAbs < minNormalRep) scale += normalize(T, &bSignificand); + } + + // Or in the implicit significand bit. (If we fell through from the + // denormal path it was already set by normalize( ), but setting it twice + // won't hurt anything.) + aSignificand |= integerBit; + bSignificand |= integerBit; + + // Get the significand of a*b. Before multiplying the significands, shift + // one of them left to left-align it in the field. Thus, the product will + // have (exponentBits + 2) integral digits, all but two of which must be + // zero. Normalizing this result is just a conditional left-shift by one + // and bumping the exponent accordingly. + var productHi: ZSignificand = undefined; + var productLo: ZSignificand = undefined; + const left_align_shift = ZSignificandBits - fractionalBits - 1; + common.wideMultiply(ZSignificand, aSignificand, bSignificand << left_align_shift, &productHi, &productLo); + + var productExponent: i32 = @as(i32, @intCast(aExponent + bExponent)) - exponentBias + scale; + + // Normalize the significand, adjust exponent if needed. + if ((productHi & integerBit) != 0) { + productExponent +%= 1; + } else { + productHi = (productHi << 1) | (productLo >> (ZSignificandBits - 1)); + productLo = productLo << 1; + } + + // If we have overflowed the type, return +/- infinity. + if (productExponent >= maxExponent) return @bitCast(infRep | productSign); + + var result: Z = undefined; + if (productExponent <= 0) { + // Result is denormal before rounding + // + // If the result is so small that it just underflows to zero, return + // a zero of the appropriate sign. Mathematically there is no need to + // handle this case separately, but we make it a special case to + // simplify the shift logic. + const shift: u32 = @truncate(@as(Z, 1) -% @as(u32, @bitCast(productExponent))); + if (shift >= ZSignificandBits) return @bitCast(productSign); + + // Otherwise, shift the significand of the result so that the round + // bit is the high bit of productLo. + const sticky = wideShrWithTruncation(ZSignificand, &productHi, &productLo, shift); + productLo |= @intFromBool(sticky); + result = productHi; + + // We include the integer bit so that rounding will carry to the exponent, + // but it will be removed later if the result is still denormal + if (significandBits != fractionalBits) result |= integerBit; + } else { + // Result is normal before rounding; insert the exponent. + result = productHi & significandMask; + result |= @as(Z, @intCast(productExponent)) << significandBits; + } + + // Final rounding. The final result may overflow to infinity, or underflow + // to zero, but those are the correct results in those cases. We use the + // default IEEE-754 round-to-nearest, ties-to-even rounding mode. + if (productLo > roundBit) result +%= 1; + if (productLo == roundBit) result +%= result & 1; + + // Restore any explicit integer bit, if it was rounded off + if (significandBits != fractionalBits) { + if ((result >> significandBits) != 0) { + result |= integerBit; + } else { + result &= ~integerBit; + } + } + + // Insert the sign of the result: + result |= productSign; + + return @bitCast(result); +} + +/// Returns `true` if the right shift is inexact (i.e. any bit shifted out is non-zero) +/// +/// This is analogous to an shr version of `@shlWithOverflow` +fn wideShrWithTruncation(comptime Z: type, hi: *Z, lo: *Z, count: u32) bool { + @setRuntimeSafety(common.test_safety); + const typeWidth = @typeInfo(Z).int.bits; + var inexact = false; + if (count < typeWidth) { + inexact = (lo.* << @intCast(typeWidth -% count)) != 0; + lo.* = (hi.* << @intCast(typeWidth -% count)) | (lo.* >> @intCast(count)); + hi.* = hi.* >> @intCast(count); + } else if (count < 2 * typeWidth) { + inexact = (hi.* << @intCast(2 * typeWidth -% count) | lo.*) != 0; + lo.* = hi.* >> @intCast(count -% typeWidth); + hi.* = 0; + } else { + inexact = (hi.* | lo.*) != 0; + lo.* = 0; + hi.* = 0; + } + return inexact; +} + +fn normalize(comptime T: type, significand: *PowerOfTwoSignificandZ(T)) i32 { + const Z = PowerOfTwoSignificandZ(T); + const integerBit = @as(Z, 1) << math.floatFractionalBits(T); + + const shift = @clz(significand.*) - @clz(integerBit); + significand.* <<= @intCast(shift); + return @as(i32, 1) - shift; +} + +/// Returns a power-of-two integer type that is large enough to contain +/// the significand of T, including an explicit integer bit +fn PowerOfTwoSignificandZ(comptime T: type) type { + const bits = math.ceilPowerOfTwoAssert(u16, math.floatFractionalBits(T) + 1); + return std.meta.Int(.unsigned, bits); +} + +test { + _ = @import("mulf3_test.zig"); +} diff --git a/build/compiler_rt/mulf3_test.zig b/build/compiler_rt/mulf3_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/mulhc3.zig b/build/compiler_rt/mulhc3.zig new file mode 100644 index 00000000..4d97a097 --- /dev/null +++ b/build/compiler_rt/mulhc3.zig @@ -0,0 +1,14 @@ +const common = @import("./common.zig"); +const mulc3 = @import("./mulc3.zig"); + +pub const panic = common.panic; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + @export(&__mulhc3, .{ .name = "__mulhc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __mulhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) mulc3.Complex(f16) { + return mulc3.mulc3(f16, a, b, c, d); +} diff --git a/build/compiler_rt/mulhf3.zig b/build/compiler_rt/mulhf3.zig new file mode 100644 index 00000000..2731625a --- /dev/null +++ b/build/compiler_rt/mulhf3.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const mulf3 = @import("./mulf3.zig").mulf3; + +pub const panic = common.panic; + +comptime { + @export(&__mulhf3, .{ .name = "__mulhf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __mulhf3(a: f16, b: f16) callconv(.c) f16 { + return mulf3(f16, a, b); +} diff --git a/build/compiler_rt/mulo.zig b/build/compiler_rt/mulo.zig new file mode 100644 index 00000000..20fbff3b --- /dev/null +++ b/build/compiler_rt/mulo.zig @@ -0,0 +1,79 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__mulosi4, .{ .name = "__mulosi4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__mulodi4, .{ .name = "__mulodi4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__muloti4, .{ .name = "__muloti4", .linkage = common.linkage, .visibility = common.visibility }); +} + +// mulo - multiplication overflow +// * return a*%b. +// * return if a*b overflows => 1 else => 0 +// - muloXi4_genericSmall as default +// - muloXi4_genericFast for 2*bitsize <= usize + +inline fn muloXi4_genericSmall(comptime ST: type, a: ST, b: ST, overflow: *c_int) ST { + overflow.* = 0; + const min = math.minInt(ST); + const res: ST = a *% b; + // Hacker's Delight section Overflow subsection Multiplication + // case a=-2^{31}, b=-1 problem, because + // on some machines a*b = -2^{31} with overflow + // Then -2^{31}/-1 overflows and any result is possible. + // => check with a<0 and b=-2^{31} + if ((a < 0 and b == min) or (a != 0 and @divTrunc(res, a) != b)) + overflow.* = 1; + return res; +} + +inline fn muloXi4_genericFast(comptime ST: type, a: ST, b: ST, overflow: *c_int) ST { + overflow.* = 0; + const EST = switch (ST) { + i32 => i64, + i64 => i128, + i128 => i256, + else => unreachable, + }; + const min = math.minInt(ST); + const max = math.maxInt(ST); + const res: EST = @as(EST, a) * @as(EST, b); + //invariant: -2^{bitwidth(EST)} < res < 2^{bitwidth(EST)-1} + if (res < min or max < res) + overflow.* = 1; + return @as(ST, @truncate(res)); +} + +pub fn __mulosi4(a: i32, b: i32, overflow: *c_int) callconv(.c) i32 { + if (2 * @bitSizeOf(i32) <= @bitSizeOf(usize)) { + return muloXi4_genericFast(i32, a, b, overflow); + } else { + return muloXi4_genericSmall(i32, a, b, overflow); + } +} + +pub fn __mulodi4(a: i64, b: i64, overflow: *c_int) callconv(.c) i64 { + if (2 * @bitSizeOf(i64) <= @bitSizeOf(usize)) { + return muloXi4_genericFast(i64, a, b, overflow); + } else { + return muloXi4_genericSmall(i64, a, b, overflow); + } +} + +pub fn __muloti4(a: i128, b: i128, overflow: *c_int) callconv(.c) i128 { + if (2 * @bitSizeOf(i128) <= @bitSizeOf(usize)) { + return muloXi4_genericFast(i128, a, b, overflow); + } else { + return muloXi4_genericSmall(i128, a, b, overflow); + } +} + +test { + _ = @import("mulosi4_test.zig"); + _ = @import("mulodi4_test.zig"); + _ = @import("muloti4_test.zig"); +} diff --git a/build/compiler_rt/mulodi4_test.zig b/build/compiler_rt/mulodi4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/mulosi4_test.zig b/build/compiler_rt/mulosi4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/muloti4_test.zig b/build/compiler_rt/muloti4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/mulsc3.zig b/build/compiler_rt/mulsc3.zig new file mode 100644 index 00000000..f011d2fe --- /dev/null +++ b/build/compiler_rt/mulsc3.zig @@ -0,0 +1,14 @@ +const common = @import("./common.zig"); +const mulc3 = @import("./mulc3.zig"); + +pub const panic = common.panic; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + @export(&__mulsc3, .{ .name = "__mulsc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __mulsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) mulc3.Complex(f32) { + return mulc3.mulc3(f32, a, b, c, d); +} diff --git a/build/compiler_rt/mulsf3.zig b/build/compiler_rt/mulsf3.zig new file mode 100644 index 00000000..8929b5de --- /dev/null +++ b/build/compiler_rt/mulsf3.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const mulf3 = @import("./mulf3.zig").mulf3; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_fmul, .{ .name = "__aeabi_fmul", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__mulsf3, .{ .name = "__mulsf3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __mulsf3(a: f32, b: f32) callconv(.c) f32 { + return mulf3(f32, a, b); +} + +fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + return mulf3(f32, a, b); +} diff --git a/build/compiler_rt/multc3.zig b/build/compiler_rt/multc3.zig new file mode 100644 index 00000000..cf362191 --- /dev/null +++ b/build/compiler_rt/multc3.zig @@ -0,0 +1,16 @@ +const common = @import("./common.zig"); +const mulc3 = @import("./mulc3.zig"); + +pub const panic = common.panic; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + if (common.want_ppc_abi) + @export(&__multc3, .{ .name = "__mulkc3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__multc3, .{ .name = "__multc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __multc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) mulc3.Complex(f128) { + return mulc3.mulc3(f128, a, b, c, d); +} diff --git a/build/compiler_rt/multf3.zig b/build/compiler_rt/multf3.zig new file mode 100644 index 00000000..0da8c506 --- /dev/null +++ b/build/compiler_rt/multf3.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const mulf3 = @import("./mulf3.zig").mulf3; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__multf3, .{ .name = "__mulkf3", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_mul, .{ .name = "_Qp_mul", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__multf3, .{ .name = "__multf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __multf3(a: f128, b: f128) callconv(.c) f128 { + return mulf3(f128, a, b); +} + +fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { + c.* = mulf3(f128, a.*, b.*); +} diff --git a/build/compiler_rt/mulvsi3.zig b/build/compiler_rt/mulvsi3.zig new file mode 100644 index 00000000..d225552a --- /dev/null +++ b/build/compiler_rt/mulvsi3.zig @@ -0,0 +1,26 @@ +const mulv = @import("mulo.zig"); +const common = @import("./common.zig"); +const testing = @import("std").testing; + +pub const panic = common.panic; + +comptime { + @export(&__mulvsi3, .{ .name = "__mulvsi3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 { + var overflow: c_int = 0; + const sum = mulv.__mulosi4(a, b, &overflow); + if (overflow != 0) @panic("compiler-rt: integer overflow"); + return sum; +} + +test "mulvsi3" { + // min i32 = -2147483648 + // max i32 = 2147483647 + // TODO write panic handler for testing panics + // try test__mulvsi3(-2147483648, -1, -1); // panic + // try test__mulvsi3(2147483647, 1, 1); // panic + try testing.expectEqual(-2147483648, __mulvsi3(-1073741824, 2)); + try testing.expectEqual(2147483646, __mulvsi3(1073741823, 2)); // one too less for corner case 2147483647 +} diff --git a/build/compiler_rt/mulxc3.zig b/build/compiler_rt/mulxc3.zig new file mode 100644 index 00000000..ef6927ce --- /dev/null +++ b/build/compiler_rt/mulxc3.zig @@ -0,0 +1,14 @@ +const common = @import("./common.zig"); +const mulc3 = @import("./mulc3.zig"); + +pub const panic = common.panic; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + @export(&__mulxc3, .{ .name = "__mulxc3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __mulxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) mulc3.Complex(f80) { + return mulc3.mulc3(f80, a, b, c, d); +} diff --git a/build/compiler_rt/mulxf3.zig b/build/compiler_rt/mulxf3.zig new file mode 100644 index 00000000..2db80b81 --- /dev/null +++ b/build/compiler_rt/mulxf3.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const mulf3 = @import("./mulf3.zig").mulf3; + +pub const panic = common.panic; + +comptime { + @export(&__mulxf3, .{ .name = "__mulxf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __mulxf3(a: f80, b: f80) callconv(.c) f80 { + return mulf3(f80, a, b); +} diff --git a/build/compiler_rt/negXi2.zig b/build/compiler_rt/negXi2.zig new file mode 100644 index 00000000..eee5202e --- /dev/null +++ b/build/compiler_rt/negXi2.zig @@ -0,0 +1,41 @@ +//! neg - negate (the number) +//! - negXi2 for unoptimized little and big endian +//! sfffffff = 2^31-1 +//! two's complement inverting bits and add 1 would result in -INT_MIN == 0 +//! => -INT_MIN = -2^31 forbidden +//! * size optimized builds +//! * machines that dont support carry operations + +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__negsi2, .{ .name = "__negsi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__negdi2, .{ .name = "__negdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__negti2, .{ .name = "__negti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __negsi2(a: i32) callconv(.c) i32 { + return negXi2(i32, a); +} + +pub fn __negdi2(a: i64) callconv(.c) i64 { + return negXi2(i64, a); +} + +pub fn __negti2(a: i128) callconv(.c) i128 { + return negXi2(i128, a); +} + +inline fn negXi2(comptime T: type, a: T) T { + return -a; +} + +test { + _ = @import("negsi2_test.zig"); + _ = @import("negdi2_test.zig"); + _ = @import("negti2_test.zig"); +} diff --git a/build/compiler_rt/negdf2.zig b/build/compiler_rt/negdf2.zig new file mode 100644 index 00000000..85e7f2bd --- /dev/null +++ b/build/compiler_rt/negdf2.zig @@ -0,0 +1,19 @@ +const common = @import("./common.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_dneg, .{ .name = "__aeabi_dneg", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__negdf2, .{ .name = "__negdf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +fn __negdf2(a: f64) callconv(.c) f64 { + return common.fneg(a); +} + +fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return common.fneg(a); +} diff --git a/build/compiler_rt/negdi2_test.zig b/build/compiler_rt/negdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/neghf2.zig b/build/compiler_rt/neghf2.zig new file mode 100644 index 00000000..86b28d48 --- /dev/null +++ b/build/compiler_rt/neghf2.zig @@ -0,0 +1,11 @@ +const common = @import("./common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__neghf2, .{ .name = "__neghf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __neghf2(a: f16) callconv(.c) f16 { + return common.fneg(a); +} diff --git a/build/compiler_rt/negsf2.zig b/build/compiler_rt/negsf2.zig new file mode 100644 index 00000000..08276e7f --- /dev/null +++ b/build/compiler_rt/negsf2.zig @@ -0,0 +1,19 @@ +const common = @import("./common.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_fneg, .{ .name = "__aeabi_fneg", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__negsf2, .{ .name = "__negsf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +fn __negsf2(a: f32) callconv(.c) f32 { + return common.fneg(a); +} + +fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + return common.fneg(a); +} diff --git a/build/compiler_rt/negsi2_test.zig b/build/compiler_rt/negsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/negtf2.zig b/build/compiler_rt/negtf2.zig new file mode 100644 index 00000000..9fb93844 --- /dev/null +++ b/build/compiler_rt/negtf2.zig @@ -0,0 +1,13 @@ +const common = @import("./common.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) + @export(&__negtf2, .{ .name = "__negkf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__negtf2, .{ .name = "__negtf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __negtf2(a: f128) callconv(.c) f128 { + return common.fneg(a); +} diff --git a/build/compiler_rt/negti2_test.zig b/build/compiler_rt/negti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/negv.zig b/build/compiler_rt/negv.zig new file mode 100644 index 00000000..6a2e717d --- /dev/null +++ b/build/compiler_rt/negv.zig @@ -0,0 +1,46 @@ +//! negv - negate oVerflow +//! * @panic, if result can not be represented +//! - negvXi4_generic for unoptimized version +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__negvsi2, .{ .name = "__negvsi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__negvdi2, .{ .name = "__negvdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__negvti2, .{ .name = "__negvti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __negvsi2(a: i32) callconv(.c) i32 { + return negvXi(i32, a); +} + +pub fn __negvdi2(a: i64) callconv(.c) i64 { + return negvXi(i64, a); +} + +pub fn __negvti2(a: i128) callconv(.c) i128 { + return negvXi(i128, a); +} + +inline fn negvXi(comptime ST: type, a: ST) ST { + const UT = switch (ST) { + i32 => u32, + i64 => u64, + i128 => u128, + else => unreachable, + }; + const N: UT = @bitSizeOf(ST); + const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1)))); + if (a == min) + @panic("compiler_rt negv: overflow"); + return -a; +} + +test { + _ = @import("negvsi2_test.zig"); + _ = @import("negvdi2_test.zig"); + _ = @import("negvti2_test.zig"); +} diff --git a/build/compiler_rt/negvdi2_test.zig b/build/compiler_rt/negvdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/negvsi2_test.zig b/build/compiler_rt/negvsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/negvti2_test.zig b/build/compiler_rt/negvti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/negxf2.zig b/build/compiler_rt/negxf2.zig new file mode 100644 index 00000000..9a9c1786 --- /dev/null +++ b/build/compiler_rt/negxf2.zig @@ -0,0 +1,11 @@ +const common = @import("./common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__negxf2, .{ .name = "__negxf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __negxf2(a: f80) callconv(.c) f80 { + return common.fneg(a); +} diff --git a/build/compiler_rt/os_version_check.zig b/build/compiler_rt/os_version_check.zig new file mode 100644 index 00000000..a2dc7f22 --- /dev/null +++ b/build/compiler_rt/os_version_check.zig @@ -0,0 +1,63 @@ +const std = @import("std"); +const testing = std.testing; +const builtin = @import("builtin"); +const common = @import("common.zig"); +const panic = @import("common.zig").panic; + +const have_availability_version_check = builtin.os.tag.isDarwin() and + builtin.os.version_range.semver.min.order(.{ .major = 10, .minor = 15, .patch = 0 }).compare(.gte); + +comptime { + if (have_availability_version_check) { + @export(&__isPlatformVersionAtLeast, .{ .name = "__isPlatformVersionAtLeast", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +// Ported from llvm-project 13.0.0 d7b669b3a30345cfcdb2fde2af6f48aa4b94845d +// +// https://github.com/llvm/llvm-project/blob/llvmorg-13.0.0/compiler-rt/lib/builtins/os_version_check.c + +// The compiler generates calls to __isPlatformVersionAtLeast() when Objective-C's @available +// function is invoked. +// +// Old versions of clang would instead emit calls to __isOSVersionAtLeast(), which is still +// supported in clang's compiler-rt implementation today in case anyone tries to link an object file +// produced with an old clang version. This requires dynamically loading frameworks, parsing a +// system plist file, and generally adds a fair amount of complexity to the implementation and so +// our implementation differs by simply removing that backwards compatability support. We only use +// the newer codepath, which merely calls out to the Darwin _availability_version_check API which is +// available on macOS 10.15+, iOS 13+, tvOS 13+ and watchOS 6+. + +const __isPlatformVersionAtLeast = if (have_availability_version_check) struct { + inline fn constructVersion(major: u32, minor: u32, subminor: u32) u32 { + return ((major & 0xffff) << 16) | ((minor & 0xff) << 8) | (subminor & 0xff); + } + + // Darwin-only + fn __isPlatformVersionAtLeast(platform: u32, major: u32, minor: u32, subminor: u32) callconv(.c) i32 { + const build_version = dyld_build_version_t{ + .platform = platform, + .version = constructVersion(major, minor, subminor), + }; + return @intFromBool(_availability_version_check(1, &[_]dyld_build_version_t{build_version})); + } + + // _availability_version_check darwin API support. + const dyld_platform_t = u32; + const dyld_build_version_t = extern struct { + platform: dyld_platform_t, + version: u32, + }; + // Darwin-only + extern "c" fn _availability_version_check(count: u32, versions: [*c]const dyld_build_version_t) bool; +}.__isPlatformVersionAtLeast else struct {}; + +test "isPlatformVersionAtLeast" { + if (!have_availability_version_check) return error.SkipZigTest; + + // Note: this test depends on the actual host OS version since it is merely calling into the + // native Darwin API. + const macos_platform_constant = 1; + try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1); + try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0); +} diff --git a/build/compiler_rt/parity.zig b/build/compiler_rt/parity.zig new file mode 100644 index 00000000..5a3e5a88 --- /dev/null +++ b/build/compiler_rt/parity.zig @@ -0,0 +1,44 @@ +//! parity - if number of bits set is even => 0, else => 1 +//! - pariytXi2_generic for big and little endian + +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__paritysi2, .{ .name = "__paritysi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__paritydi2, .{ .name = "__paritydi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__parityti2, .{ .name = "__parityti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __paritysi2(a: i32) callconv(.c) i32 { + return parityXi2(i32, a); +} + +pub fn __paritydi2(a: i64) callconv(.c) i32 { + return parityXi2(i64, a); +} + +pub fn __parityti2(a: i128) callconv(.c) i32 { + return parityXi2(i128, a); +} + +inline fn parityXi2(comptime T: type, a: T) i32 { + var x: std.meta.Int(.unsigned, @typeInfo(T).int.bits) = @bitCast(a); + // Bit Twiddling Hacks: Compute parity in parallel + comptime var shift: u8 = @bitSizeOf(T) / 2; + inline while (shift > 2) { + x ^= x >> shift; + shift = shift >> 1; + } + x &= 0xf; + return (@as(u16, 0x6996) >> @intCast(x)) & 1; // optimization for >>2 and >>1 +} + +test { + _ = @import("paritysi2_test.zig"); + _ = @import("paritydi2_test.zig"); + _ = @import("parityti2_test.zig"); +} diff --git a/build/compiler_rt/paritydi2_test.zig b/build/compiler_rt/paritydi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/paritysi2_test.zig b/build/compiler_rt/paritysi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/parityti2_test.zig b/build/compiler_rt/parityti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/popcount.zig b/build/compiler_rt/popcount.zig new file mode 100644 index 00000000..f937bd0c --- /dev/null +++ b/build/compiler_rt/popcount.zig @@ -0,0 +1,56 @@ +//! popcount - population count +//! counts the number of 1 bits +//! SWAR-Popcount: count bits of duos, aggregate to nibbles, and bytes inside +//! x-bit register in parallel to sum up all bytes +//! SWAR-Masks and factors can be defined as 2-adic fractions +//! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques, +//! subsubsection "Working with the rightmost bits" and "Sideways addition". + +const builtin = @import("builtin"); +const std = @import("std"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__popcountsi2, .{ .name = "__popcountsi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__popcountdi2, .{ .name = "__popcountdi2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__popcountti2, .{ .name = "__popcountti2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __popcountsi2(a: i32) callconv(.c) i32 { + return popcountXi2(i32, a); +} + +pub fn __popcountdi2(a: i64) callconv(.c) i32 { + return popcountXi2(i64, a); +} + +pub fn __popcountti2(a: i128) callconv(.c) i32 { + return popcountXi2(i128, a); +} + +inline fn popcountXi2(comptime ST: type, a: ST) i32 { + const UT = switch (ST) { + i32 => u32, + i64 => u64, + i128 => u128, + else => unreachable, + }; + var x: UT = @bitCast(a); + x -= (x >> 1) & (~@as(UT, 0) / 3); // 0x55...55, aggregate duos + x = ((x >> 2) & (~@as(UT, 0) / 5)) // 0x33...33, aggregate nibbles + + (x & (~@as(UT, 0) / 5)); + x += x >> 4; + x &= ~@as(UT, 0) / 17; // 0x0F...0F, aggregate bytes + // 8 most significant bits of x + (x<<8) + (x<<16) + .. + x *%= ~@as(UT, 0) / 255; // 0x01...01 + x >>= (@bitSizeOf(ST) - 8); + return @intCast(x); +} + +test { + _ = @import("popcountsi2_test.zig"); + _ = @import("popcountdi2_test.zig"); + _ = @import("popcountti2_test.zig"); +} diff --git a/build/compiler_rt/popcountdi2_test.zig b/build/compiler_rt/popcountdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/popcountsi2_test.zig b/build/compiler_rt/popcountsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/popcountti2_test.zig b/build/compiler_rt/popcountti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/powiXf2.zig b/build/compiler_rt/powiXf2.zig new file mode 100644 index 00000000..21e7042a --- /dev/null +++ b/build/compiler_rt/powiXf2.zig @@ -0,0 +1,60 @@ +//! a raised to integer power of b +//! ported from https://github.com/llvm-mirror/compiler-rt/blob/release_80/lib/builtins/powisf2.c +//! Multiplication order (left-to-right or right-to-left) does not matter for +//! error propagation and this method is optimized for performance, not accuracy. + +const builtin = @import("builtin"); +const common = @import("common.zig"); +const std = @import("std"); + +pub const panic = common.panic; + +comptime { + @export(&__powihf2, .{ .name = "__powihf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__powisf2, .{ .name = "__powisf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__powidf2, .{ .name = "__powidf2", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) + @export(&__powitf2, .{ .name = "__powikf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__powitf2, .{ .name = "__powitf2", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__powixf2, .{ .name = "__powixf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { + var x_a: FT = a; + var x_b: i32 = b; + const is_recip: bool = b < 0; + var r: FT = 1.0; + while (true) { + if (@as(u32, @bitCast(x_b)) & @as(u32, 1) != 0) { + r *= x_a; + } + x_b = @divTrunc(x_b, @as(i32, 2)); + if (x_b == 0) break; + x_a *= x_a; // Multiplication of x_a propagates the error + } + return if (is_recip) 1 / r else r; +} + +pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 { + return powiXf2(f16, a, b); +} + +pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 { + return powiXf2(f32, a, b); +} + +pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 { + return powiXf2(f64, a, b); +} + +pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 { + return powiXf2(f128, a, b); +} + +pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 { + return powiXf2(f80, a, b); +} + +test { + _ = @import("powiXf2_test.zig"); +} diff --git a/build/compiler_rt/powiXf2_test.zig b/build/compiler_rt/powiXf2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/rem_pio2.zig b/build/compiler_rt/rem_pio2.zig new file mode 100644 index 00000000..33575b7f --- /dev/null +++ b/build/compiler_rt/rem_pio2.zig @@ -0,0 +1,194 @@ +// Ported from musl, which is licensed under the MIT license: +// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +// +// https://git.musl-libc.org/cgit/musl/tree/src/math/__rem_pio2.c + +const std = @import("std"); +const rem_pio2_large = @import("rem_pio2_large.zig").rem_pio2_large; +const math = std.math; + +const toint = 1.5 / math.floatEps(f64); +// pi/4 +const pio4 = 0x1.921fb54442d18p-1; +// invpio2: 53 bits of 2/pi +const invpio2 = 6.36619772367581382433e-01; // 0x3FE45F30, 0x6DC9C883 +// pio2_1: first 33 bit of pi/2 +const pio2_1 = 1.57079632673412561417e+00; // 0x3FF921FB, 0x54400000 +// pio2_1t: pi/2 - pio2_1 +const pio2_1t = 6.07710050650619224932e-11; // 0x3DD0B461, 0x1A626331 +// pio2_2: second 33 bit of pi/2 +const pio2_2 = 6.07710050630396597660e-11; // 0x3DD0B461, 0x1A600000 +// pio2_2t: pi/2 - (pio2_1+pio2_2) +const pio2_2t = 2.02226624879595063154e-21; // 0x3BA3198A, 0x2E037073 +// pio2_3: third 33 bit of pi/2 +const pio2_3 = 2.02226624871116645580e-21; // 0x3BA3198A, 0x2E000000 +// pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) +const pio2_3t = 8.47842766036889956997e-32; // 0x397B839A, 0x252049C1 + +fn medium(ix: u32, x: f64, y: *[2]f64) i32 { + var w: f64 = undefined; + var t: f64 = undefined; + var r: f64 = undefined; + var @"fn": f64 = undefined; + var n: i32 = undefined; + var ex: i32 = undefined; + var ey: i32 = undefined; + var ui: u64 = undefined; + + // rint(x/(pi/2)) + @"fn" = x * invpio2 + toint - toint; + n = @intFromFloat(@"fn"); + r = x - @"fn" * pio2_1; + w = @"fn" * pio2_1t; // 1st round, good to 85 bits + // Matters with directed rounding. + if (r - w < -pio4) { + n -= 1; + @"fn" -= 1; + r = x - @"fn" * pio2_1; + w = @"fn" * pio2_1t; + } else if (r - w > pio4) { + n += 1; + @"fn" += 1; + r = x - @"fn" * pio2_1; + w = @"fn" * pio2_1t; + } + y[0] = r - w; + ui = @bitCast(y[0]); + ey = @intCast((ui >> 52) & 0x7ff); + ex = @intCast(ix >> 20); + if (ex - ey > 16) { // 2nd round, good to 118 bits + t = r; + w = @"fn" * pio2_2; + r = t - w; + w = @"fn" * pio2_2t - ((t - r) - w); + y[0] = r - w; + ui = @bitCast(y[0]); + ey = @intCast((ui >> 52) & 0x7ff); + if (ex - ey > 49) { // 3rd round, good to 151 bits, covers all cases + t = r; + w = @"fn" * pio2_3; + r = t - w; + w = @"fn" * pio2_3t - ((t - r) - w); + y[0] = r - w; + } + } + y[1] = (r - y[0]) - w; + return n; +} + +// Returns the remainder of x rem pi/2 in y[0]+y[1] +// +// use rem_pio2_large() for large x +// +// caller must handle the case when reduction is not needed: |x| ~<= pi/4 */ +pub fn rem_pio2(x: f64, y: *[2]f64) i32 { + var z: f64 = undefined; + var tx: [3]f64 = undefined; + var ty: [2]f64 = undefined; + var n: i32 = undefined; + var ix: u32 = undefined; + var sign: bool = undefined; + var i: i32 = undefined; + var ui: u64 = undefined; + + ui = @bitCast(x); + sign = ui >> 63 != 0; + ix = @truncate((ui >> 32) & 0x7fffffff); + if (ix <= 0x400f6a7a) { // |x| ~<= 5pi/4 + if ((ix & 0xfffff) == 0x921fb) { // |x| ~= pi/2 or 2pi/2 + return medium(ix, x, y); + } + if (ix <= 0x4002d97c) { // |x| ~<= 3pi/4 + if (!sign) { + z = x - pio2_1; // one round good to 85 bits + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + return 1; + } else { + z = x + pio2_1; + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + return -1; + } + } else { + if (!sign) { + z = x - 2 * pio2_1; + y[0] = z - 2 * pio2_1t; + y[1] = (z - y[0]) - 2 * pio2_1t; + return 2; + } else { + z = x + 2 * pio2_1; + y[0] = z + 2 * pio2_1t; + y[1] = (z - y[0]) + 2 * pio2_1t; + return -2; + } + } + } + if (ix <= 0x401c463b) { // |x| ~<= 9pi/4 + if (ix <= 0x4015fdbc) { // |x| ~<= 7pi/4 + if (ix == 0x4012d97c) { // |x| ~= 3pi/2 + return medium(ix, x, y); + } + if (!sign) { + z = x - 3 * pio2_1; + y[0] = z - 3 * pio2_1t; + y[1] = (z - y[0]) - 3 * pio2_1t; + return 3; + } else { + z = x + 3 * pio2_1; + y[0] = z + 3 * pio2_1t; + y[1] = (z - y[0]) + 3 * pio2_1t; + return -3; + } + } else { + if (ix == 0x401921fb) { // |x| ~= 4pi/2 */ + return medium(ix, x, y); + } + if (!sign) { + z = x - 4 * pio2_1; + y[0] = z - 4 * pio2_1t; + y[1] = (z - y[0]) - 4 * pio2_1t; + return 4; + } else { + z = x + 4 * pio2_1; + y[0] = z + 4 * pio2_1t; + y[1] = (z - y[0]) + 4 * pio2_1t; + return -4; + } + } + } + if (ix < 0x413921fb) { // |x| ~< 2^20*(pi/2), medium size + return medium(ix, x, y); + } + // all other (large) arguments + if (ix >= 0x7ff00000) { // x is inf or NaN + y[0] = x - x; + y[1] = y[0]; + return 0; + } + // set z = scalbn(|x|,-ilogb(x)+23) + ui = @bitCast(x); + ui &= std.math.maxInt(u64) >> 12; + ui |= @as(u64, 0x3ff + 23) << 52; + z = @bitCast(ui); + + i = 0; + while (i < 2) : (i += 1) { + tx[@intCast(i)] = @floatFromInt(@as(i32, @intFromFloat(z))); + z = (z - tx[@intCast(i)]) * 0x1p24; + } + tx[@intCast(i)] = z; + // skip zero terms, first term is non-zero + while (tx[@intCast(i)] == 0.0) { + i -= 1; + } + n = rem_pio2_large(tx[0..], ty[0..], @as(i32, @intCast((ix >> 20))) - (0x3ff + 23), i + 1, 1); + if (sign) { + y[0] = -ty[0]; + y[1] = -ty[1]; + return -n; + } + y[0] = ty[0]; + y[1] = ty[1]; + return n; +} diff --git a/build/compiler_rt/rem_pio2_large.zig b/build/compiler_rt/rem_pio2_large.zig new file mode 100644 index 00000000..f15e0d71 --- /dev/null +++ b/build/compiler_rt/rem_pio2_large.zig @@ -0,0 +1,503 @@ +// Ported from musl, which is licensed under the MIT license: +// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +// +// https://git.musl-libc.org/cgit/musl/tree/src/math/__rem_pio2_large.c + +const std = @import("std"); +const math = std.math; + +const init_jk = [_]i32{ 3, 4, 4, 6 }; // initial value for jk + +/// +/// Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi +/// +/// integer array, contains the (24*i)-th to (24*i+23)-th +/// bit of 2/pi after binary point. The corresponding +/// floating value is +/// +/// ipio2[i] * 2^(-24(i+1)). +/// +/// NB: This table must have at least (e0-3)/24 + jk terms. +/// For quad precision (e0 <= 16360, jk = 6), this is 686. +const ipio2 = [_]i32{ + 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, + 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, + 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, + 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, + 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, + 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, + 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, + 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, + 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, + 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, + 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, + + 0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6, + 0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2, + 0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35, + 0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30, + 0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C, + 0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4, + 0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770, + 0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7, + 0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19, + 0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522, + 0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16, + 0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6, + 0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E, + 0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48, + 0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3, + 0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF, + 0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55, + 0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612, + 0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929, + 0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC, + 0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B, + 0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C, + 0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4, + 0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB, + 0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC, + 0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C, + 0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F, + 0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5, + 0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437, + 0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B, + 0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA, + 0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD, + 0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3, + 0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3, + 0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717, + 0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F, + 0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61, + 0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB, + 0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51, + 0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0, + 0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C, + 0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6, + 0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC, + 0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED, + 0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328, + 0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D, + 0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0, + 0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B, + 0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4, + 0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3, + 0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F, + 0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD, + 0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B, + 0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4, + 0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761, + 0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31, + 0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30, + 0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262, + 0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E, + 0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1, + 0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C, + 0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4, + 0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08, + 0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196, + 0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9, + 0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4, + 0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC, + 0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C, + 0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0, + 0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C, + 0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0, + 0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC, + 0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22, + 0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893, + 0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7, + 0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5, + 0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F, + 0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4, + 0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF, + 0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B, + 0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2, + 0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138, + 0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E, + 0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569, + 0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34, + 0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9, + 0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D, + 0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F, + 0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855, + 0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569, + 0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B, + 0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE, + 0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41, + 0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49, + 0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F, + 0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110, + 0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8, + 0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365, + 0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A, + 0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270, + 0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5, + 0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616, + 0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B, + 0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0, +}; + +const PIo2 = [_]f64{ + 1.57079625129699707031e+00, // 0x3FF921FB, 0x40000000 + 7.54978941586159635335e-08, // 0x3E74442D, 0x00000000 + 5.39030252995776476554e-15, // 0x3CF84698, 0x80000000 + 3.28200341580791294123e-22, // 0x3B78CC51, 0x60000000 + 1.27065575308067607349e-29, // 0x39F01B83, 0x80000000 + 1.22933308981111328932e-36, // 0x387A2520, 0x40000000 + 2.73370053816464559624e-44, // 0x36E38222, 0x80000000 + 2.16741683877804819444e-51, // 0x3569F31D, 0x00000000 +}; + +/// Returns the last three digits of N with y = x - N*pi/2 so that |y| < pi/2. +/// +/// The method is to compute the integer (mod 8) and fraction parts of +/// (2/pi)*x without doing the full multiplication. In general we +/// skip the part of the product that are known to be a huge integer ( +/// more accurately, = 0 mod 8 ). Thus the number of operations are +/// independent of the exponent of the input. +/// +/// (2/pi) is represented by an array of 24-bit integers in ipio2[]. +/// +/// Input parameters: +/// x[] The input value (must be positive) is broken into nx +/// pieces of 24-bit integers in double precision format. +/// x[i] will be the i-th 24 bit of x. The scaled exponent +/// of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 +/// match x's up to 24 bits. +/// +/// Example of breaking a double positive z into x[0]+x[1]+x[2]: +/// e0 = ilogb(z)-23 +/// z = scalbn(z,-e0) +/// for i = 0,1,2 +/// x[i] = floor(z) +/// z = (z-x[i])*2**24 +/// +/// +/// y[] output result in an array of double precision numbers. +/// The dimension of y[] is: +/// 24-bit precision 1 +/// 53-bit precision 2 +/// 64-bit precision 2 +/// 113-bit precision 3 +/// The actual value is the sum of them. Thus for 113-bit +/// precision, one may have to do something like: +/// +/// long double t,w,r_head, r_tail; +/// t = (long double)y[2] + (long double)y[1]; +/// w = (long double)y[0]; +/// r_head = t+w; +/// r_tail = w - (r_head - t); +/// +/// e0 The exponent of x[0]. Must be <= 16360 or you need to +/// expand the ipio2 table. +/// +/// nx dimension of x[] +/// +/// prec an integer indicating the precision: +/// 0 24 bits (single) +/// 1 53 bits (double) +/// 2 64 bits (extended) +/// 3 113 bits (quad) +/// +/// Here is the description of some local variables: +/// +/// jk jk+1 is the initial number of terms of ipio2[] needed +/// in the computation. The minimum and recommended value +/// for jk is 3,4,4,6 for single, double, extended, and quad. +/// jk+1 must be 2 larger than you might expect so that our +/// recomputation test works. (Up to 24 bits in the integer +/// part (the 24 bits of it that we compute) and 23 bits in +/// the fraction part may be lost to cancelation before we +/// recompute.) +/// +/// jz local integer variable indicating the number of +/// terms of ipio2[] used. +/// +/// jx nx - 1 +/// +/// jv index for pointing to the suitable ipio2[] for the +/// computation. In general, we want +/// ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 +/// is an integer. Thus +/// e0-3-24*jv >= 0 or (e0-3)/24 >= jv +/// Hence jv = max(0,(e0-3)/24). +/// +/// jp jp+1 is the number of terms in PIo2[] needed, jp = jk. +/// +/// q[] double array with integral value, representing the +/// 24-bits chunk of the product of x and 2/pi. +/// +/// q0 the corresponding exponent of q[0]. Note that the +/// exponent for q[i] would be q0-24*i. +/// +/// PIo2[] double precision array, obtained by cutting pi/2 +/// into 24 bits chunks. +/// +/// f[] ipio2[] in floating point +/// +/// iq[] integer array by breaking up q[] in 24-bits chunk. +/// +/// fq[] final product of x*(2/pi) in fq[0],..,fq[jk] +/// +/// ih integer. If >0 it indicates q[] is >= 0.5, hence +/// it also indicates the *sign* of the result. +/// +/// +/// +/// Constants: +/// The hexadecimal values are the intended ones for the following +/// constants. The decimal values may be used, provided that the +/// compiler will convert from decimal to binary accurately enough +/// to produce the hexadecimal values shown. +/// +pub fn rem_pio2_large(x: []const f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 { + var jz: i32 = undefined; + var jx: i32 = undefined; + var jv: i32 = undefined; + var jp: i32 = undefined; + var jk: i32 = undefined; + var carry: i32 = undefined; + var n: i32 = undefined; + var iq: [20]i32 = undefined; + var i: i32 = undefined; + var j: i32 = undefined; + var k: i32 = undefined; + var m: i32 = undefined; + var q0: i32 = undefined; + var ih: i32 = undefined; + + var z: f64 = undefined; + var fw: f64 = undefined; + var f: [20]f64 = undefined; + var fq: [20]f64 = undefined; + var q: [20]f64 = undefined; + + // initialize jk + jk = init_jk[prec]; + jp = jk; + + // determine jx,jv,q0, note that 3>q0 + jx = nx - 1; + jv = @divFloor(e0 - 3, 24); + if (jv < 0) jv = 0; + q0 = e0 - 24 * (jv + 1); + + // set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] + j = jv - jx; + m = jx + jk; + i = 0; + while (i <= m) : ({ + i += 1; + j += 1; + }) { + f[@intCast(i)] = if (j < 0) 0.0 else @floatFromInt(ipio2[@intCast(j)]); + } + + // compute q[0],q[1],...q[jk] + i = 0; + while (i <= jk) : (i += 1) { + j = 0; + fw = 0; + while (j <= jx) : (j += 1) { + fw += x[@intCast(j)] * f[@intCast(jx + i - j)]; + } + q[@intCast(i)] = fw; + } + + jz = jk; + + // This is to handle a non-trivial goto translation from C. + // An unconditional return statement is found at the end of this loop. + recompute: while (true) { + // distill q[] into iq[] reversingly + i = 0; + j = jz; + z = q[@intCast(jz)]; + while (j > 0) : ({ + i += 1; + j -= 1; + }) { + fw = @floatFromInt(@as(i32, @intFromFloat(0x1p-24 * z))); + iq[@intCast(i)] = @intFromFloat(z - 0x1p24 * fw); + z = q[@intCast(j - 1)] + fw; + } + + // compute n + z = math.scalbn(z, q0); // actual value of z + z -= 8.0 * @floor(z * 0.125); // trim off integer >= 8 + n = @intFromFloat(z); + z -= @floatFromInt(n); + ih = 0; + if (q0 > 0) { // need iq[jz-1] to determine n + i = iq[@intCast(jz - 1)] >> @intCast(24 - q0); + n += i; + iq[@intCast(jz - 1)] -= i << @intCast(24 - q0); + ih = iq[@intCast(jz - 1)] >> @intCast(23 - q0); + } else if (q0 == 0) { + ih = iq[@intCast(jz - 1)] >> 23; + } else if (z >= 0.5) { + ih = 2; + } + + if (ih > 0) { // q > 0.5 + n += 1; + carry = 0; + i = 0; + while (i < jz) : (i += 1) { // compute 1-q + j = iq[@intCast(i)]; + if (carry == 0) { + if (j != 0) { + carry = 1; + iq[@intCast(i)] = 0x1000000 - j; + } + } else { + iq[@intCast(i)] = 0xffffff - j; + } + } + if (q0 > 0) { // rare case: chance is 1 in 12 + @branchHint(.unlikely); + switch (q0) { + 1 => iq[@intCast(jz - 1)] &= 0x7fffff, + 2 => iq[@intCast(jz - 1)] &= 0x3fffff, + else => unreachable, + } + } + if (ih == 2) { + z = 1.0 - z; + if (carry != 0) { + z -= math.scalbn(@as(f64, 1.0), q0); + } + } + } + + // check if recomputation is needed + if (z == 0.0) { + j = 0; + i = jz - 1; + while (i >= jk) : (i -= 1) { + j |= iq[@intCast(i)]; + } + + if (j == 0) { // need recomputation + k = 1; + while (iq[@intCast(jk - k)] == 0) : (k += 1) { + // k = no. of terms needed + } + + i = jz + 1; + while (i <= jz + k) : (i += 1) { // add q[jz+1] to q[jz+k] + f[@intCast(jx + i)] = @floatFromInt(ipio2[@intCast(jv + i)]); + j = 0; + fw = 0; + while (j <= jx) : (j += 1) { + fw += x[@intCast(j)] * f[@intCast(jx + i - j)]; + } + q[@intCast(i)] = fw; + } + jz += k; + continue :recompute; // mimic goto recompute + } + } + + // chop off zero terms + if (z == 0.0) { + jz -= 1; + q0 -= 24; + while (iq[@intCast(jz)] == 0) { + jz -= 1; + q0 -= 24; + } + } else { // break z into 24-bit if necessary + z = math.scalbn(z, -q0); + if (z >= 0x1p24) { + fw = @floatFromInt(@as(i32, @intFromFloat(0x1p-24 * z))); + iq[@intCast(jz)] = @intFromFloat(z - 0x1p24 * fw); + jz += 1; + q0 += 24; + iq[@intCast(jz)] = @intFromFloat(fw); + } else { + iq[@intCast(jz)] = @intFromFloat(z); + } + } + + // convert integer "bit" chunk to floating-point value + fw = math.scalbn(@as(f64, 1.0), q0); + i = jz; + while (i >= 0) : (i -= 1) { + q[@intCast(i)] = fw * @as(f64, @floatFromInt(iq[@intCast(i)])); + fw *= 0x1p-24; + } + + // compute PIo2[0,...,jp]*q[jz,...,0] + i = jz; + while (i >= 0) : (i -= 1) { + fw = 0; + k = 0; + while (k <= jp and k <= jz - i) : (k += 1) { + fw += PIo2[@intCast(k)] * q[@intCast(i + k)]; + } + fq[@intCast(jz - i)] = fw; + } + + // compress fq[] into y[] + switch (prec) { + 0 => { + fw = 0.0; + i = jz; + while (i >= 0) : (i -= 1) { + fw += fq[@intCast(i)]; + } + y[0] = if (ih == 0) fw else -fw; + }, + + 1, 2 => { + fw = 0.0; + i = jz; + while (i >= 0) : (i -= 1) { + fw += fq[@intCast(i)]; + } + // TODO: drop excess precision here once double_t is used + fw = fw; + y[0] = if (ih == 0) fw else -fw; + fw = fq[0] - fw; + i = 1; + while (i <= jz) : (i += 1) { + fw += fq[@intCast(i)]; + } + y[1] = if (ih == 0) fw else -fw; + }, + 3 => { // painful + i = jz; + while (i > 0) : (i -= 1) { + fw = fq[@intCast(i - 1)] + fq[@intCast(i)]; + fq[@intCast(i)] += fq[@intCast(i - 1)] - fw; + fq[@intCast(i - 1)] = fw; + } + i = jz; + while (i > 1) : (i -= 1) { + fw = fq[@intCast(i - 1)] + fq[@intCast(i)]; + fq[@intCast(i)] += fq[@intCast(i - 1)] - fw; + fq[@intCast(i - 1)] = fw; + } + fw = 0; + i = jz; + while (i >= 2) : (i -= 1) { + fw += fq[@intCast(i)]; + } + if (ih == 0) { + y[0] = fq[0]; + y[1] = fq[1]; + y[2] = fw; + } else { + y[0] = -fq[0]; + y[1] = -fq[1]; + y[2] = -fw; + } + }, + else => unreachable, + } + + return n & 7; + } +} diff --git a/build/compiler_rt/rem_pio2f.zig b/build/compiler_rt/rem_pio2f.zig new file mode 100644 index 00000000..c17ebbd3 --- /dev/null +++ b/build/compiler_rt/rem_pio2f.zig @@ -0,0 +1,70 @@ +// Ported from musl, which is licensed under the MIT license: +// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +// +// https://git.musl-libc.org/cgit/musl/tree/src/math/__rem_pio2f.c + +const std = @import("std"); +const rem_pio2_large = @import("rem_pio2_large.zig").rem_pio2_large; +const math = std.math; + +const toint = 1.5 / math.floatEps(f64); +// pi/4 +const pio4 = 0x1.921fb6p-1; +// invpio2: 53 bits of 2/pi +const invpio2 = 6.36619772367581382433e-01; // 0x3FE45F30, 0x6DC9C883 +// pio2_1: first 25 bits of pi/2 +const pio2_1 = 1.57079631090164184570e+00; // 0x3FF921FB, 0x50000000 +// pio2_1t: pi/2 - pio2_1 +const pio2_1t = 1.58932547735281966916e-08; // 0x3E5110b4, 0x611A6263 + +// Returns the remainder of x rem pi/2 in *y +// use double precision for everything except passing x +// use rem_pio2_large() for large x +pub fn rem_pio2f(x: f32, y: *f64) i32 { + var tx: [1]f64 = undefined; + var ty: [1]f64 = undefined; + var @"fn": f64 = undefined; + var ix: u32 = undefined; + var n: i32 = undefined; + var sign: bool = undefined; + var e0: u32 = undefined; + var ui: u32 = undefined; + + ui = @bitCast(x); + ix = ui & 0x7fffffff; + + // 25+53 bit pi is good enough for medium size + if (ix < 0x4dc90fdb) { // |x| ~< 2^28*(pi/2), medium size + // Use a specialized rint() to get fn. + @"fn" = @as(f64, @floatCast(x)) * invpio2 + toint - toint; + n = @intFromFloat(@"fn"); + y.* = x - @"fn" * pio2_1 - @"fn" * pio2_1t; + // Matters with directed rounding. + if (y.* < -pio4) { + n -= 1; + @"fn" -= 1; + y.* = x - @"fn" * pio2_1 - @"fn" * pio2_1t; + } else if (y.* > pio4) { + n += 1; + @"fn" += 1; + y.* = x - @"fn" * pio2_1 - @"fn" * pio2_1t; + } + return n; + } + if (ix >= 0x7f800000) { // x is inf or NaN + y.* = x - x; + return 0; + } + // scale x into [2^23, 2^24-1] + sign = ui >> 31 != 0; + e0 = (ix >> 23) - (0x7f + 23); // e0 = ilogb(|x|)-23, positive + ui = ix - (e0 << 23); + tx[0] = @as(f32, @bitCast(ui)); + n = rem_pio2_large(&tx, &ty, @as(i32, @intCast(e0)), 1, 0); + if (sign) { + y.* = -ty[0]; + return -n; + } + y.* = ty[0]; + return n; +} diff --git a/build/compiler_rt/round.zig b/build/compiler_rt/round.zig new file mode 100644 index 00000000..9e8ea42d --- /dev/null +++ b/build/compiler_rt/round.zig @@ -0,0 +1,198 @@ +//! Ported from musl, which is licensed under the MIT license: +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/roundf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/round.c + +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__roundh, .{ .name = "__roundh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&roundf, .{ .name = "roundf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&round, .{ .name = "round", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__roundx, .{ .name = "__roundx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&roundq, .{ .name = "roundf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&roundq, .{ .name = "roundq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&roundl, .{ .name = "roundl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __roundh(x: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(roundf(x)); +} + +pub fn roundf(x_: f32) callconv(.c) f32 { + const f32_toint = 1.0 / math.floatEps(f32); + + var x = x_; + const u: u32 = @bitCast(x); + const e = (u >> 23) & 0xFF; + var y: f32 = undefined; + + if (e >= 0x7F + 23) { + return x; + } + if (u >> 31 != 0) { + x = -x; + } + if (e < 0x7F - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + f32_toint); + return 0 * @as(f32, @bitCast(u)); + } + + y = x + f32_toint - f32_toint - x; + if (y > 0.5) { + y = y + x - 1; + } else if (y <= -0.5) { + y = y + x + 1; + } else { + y = y + x; + } + + if (u >> 31 != 0) { + return -y; + } else { + return y; + } +} + +pub fn round(x_: f64) callconv(.c) f64 { + const f64_toint = 1.0 / math.floatEps(f64); + + var x = x_; + const u: u64 = @bitCast(x); + const e = (u >> 52) & 0x7FF; + var y: f64 = undefined; + + if (e >= 0x3FF + 52) { + return x; + } + if (u >> 63 != 0) { + x = -x; + } + if (e < 0x3ff - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + f64_toint); + return 0 * @as(f64, @bitCast(u)); + } + + y = x + f64_toint - f64_toint - x; + if (y > 0.5) { + y = y + x - 1; + } else if (y <= -0.5) { + y = y + x + 1; + } else { + y = y + x; + } + + if (u >> 63 != 0) { + return -y; + } else { + return y; + } +} + +pub fn __roundx(x: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(roundq(x)); +} + +pub fn roundq(x_: f128) callconv(.c) f128 { + const f128_toint = 1.0 / math.floatEps(f128); + + var x = x_; + const u: u128 = @bitCast(x); + const e = (u >> 112) & 0x7FFF; + var y: f128 = undefined; + + if (e >= 0x3FFF + 112) { + return x; + } + if (u >> 127 != 0) { + x = -x; + } + if (e < 0x3FFF - 1) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + f128_toint); + return 0 * @as(f128, @bitCast(u)); + } + + y = x + f128_toint - f128_toint - x; + if (y > 0.5) { + y = y + x - 1; + } else if (y <= -0.5) { + y = y + x + 1; + } else { + y = y + x; + } + + if (u >> 127 != 0) { + return -y; + } else { + return y; + } +} + +pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __roundh(x), + 32 => return roundf(x), + 64 => return round(x), + 80 => return __roundx(x), + 128 => return roundq(x), + else => @compileError("unreachable"), + } +} + +test "round32" { + try expect(roundf(1.3) == 1.0); + try expect(roundf(-1.3) == -1.0); + try expect(roundf(0.2) == 0.0); + try expect(roundf(1.8) == 2.0); +} + +test "round64" { + try expect(round(1.3) == 1.0); + try expect(round(-1.3) == -1.0); + try expect(round(0.2) == 0.0); + try expect(round(1.8) == 2.0); +} + +test "round128" { + try expect(roundq(1.3) == 1.0); + try expect(roundq(-1.3) == -1.0); + try expect(roundq(0.2) == 0.0); + try expect(roundq(1.8) == 2.0); +} + +test "round32.special" { + try expect(roundf(0.0) == 0.0); + try expect(roundf(-0.0) == -0.0); + try expect(math.isPositiveInf(roundf(math.inf(f32)))); + try expect(math.isNegativeInf(roundf(-math.inf(f32)))); + try expect(math.isNan(roundf(math.nan(f32)))); +} + +test "round64.special" { + try expect(round(0.0) == 0.0); + try expect(round(-0.0) == -0.0); + try expect(math.isPositiveInf(round(math.inf(f64)))); + try expect(math.isNegativeInf(round(-math.inf(f64)))); + try expect(math.isNan(round(math.nan(f64)))); +} + +test "round128.special" { + try expect(roundq(0.0) == 0.0); + try expect(roundq(-0.0) == -0.0); + try expect(math.isPositiveInf(roundq(math.inf(f128)))); + try expect(math.isNegativeInf(roundq(-math.inf(f128)))); + try expect(math.isNan(roundq(math.nan(f128)))); +} diff --git a/build/compiler_rt/shift.zig b/build/compiler_rt/shift.zig new file mode 100644 index 00000000..17860da9 --- /dev/null +++ b/build/compiler_rt/shift.zig @@ -0,0 +1,143 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const Log2Int = std.math.Log2Int; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + // symbol compatibility with libgcc + @export(&__ashlsi3, .{ .name = "__ashlsi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ashrsi3, .{ .name = "__ashrsi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lshrsi3, .{ .name = "__lshrsi3", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&__ashlti3, .{ .name = "__ashlti3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ashrti3, .{ .name = "__ashrti3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lshrti3, .{ .name = "__lshrti3", .linkage = common.linkage, .visibility = common.visibility }); + + if (common.want_aeabi) { + @export(&__aeabi_llsl, .{ .name = "__aeabi_llsl", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_lasr, .{ .name = "__aeabi_lasr", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__aeabi_llsr, .{ .name = "__aeabi_llsr", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__ashldi3, .{ .name = "__ashldi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__ashrdi3, .{ .name = "__ashrdi3", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__lshrdi3, .{ .name = "__lshrdi3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +// Arithmetic shift left: shift in 0 from right to left +// Precondition: 0 <= b < bits_in_dword +inline fn ashlXi3(comptime T: type, a: T, b: i32) T { + const word_t = common.HalveInt(T, false); + + const input = word_t{ .all = a }; + var output: word_t = undefined; + + if (b >= word_t.bits) { + output.s.low = 0; + output.s.high = input.s.low << @intCast(b - word_t.bits); + } else if (b == 0) { + return a; + } else { + output.s.low = input.s.low << @intCast(b); + output.s.high = input.s.high << @intCast(b); + output.s.high |= input.s.low >> @intCast(word_t.bits - b); + } + + return output.all; +} + +// Arithmetic shift right: shift in 1 from left to right +// Precondition: 0 <= b < T.bit_count +inline fn ashrXi3(comptime T: type, a: T, b: i32) T { + const word_t = common.HalveInt(T, true); + + const input = word_t{ .all = a }; + var output: word_t = undefined; + + if (b >= word_t.bits) { + output.s.high = input.s.high >> (word_t.bits - 1); + output.s.low = input.s.high >> @intCast(b - word_t.bits); + } else if (b == 0) { + return a; + } else { + output.s.high = input.s.high >> @intCast(b); + output.s.low = input.s.high << @intCast(word_t.bits - b); + // Avoid sign-extension here + output.s.low |= @bitCast(@as(word_t.HalfTU, @bitCast(input.s.low)) >> @intCast(b)); + } + + return output.all; +} + +// Logical shift right: shift in 0 from left to right +// Precondition: 0 <= b < T.bit_count +inline fn lshrXi3(comptime T: type, a: T, b: i32) T { + const word_t = common.HalveInt(T, false); + + const input = word_t{ .all = a }; + var output: word_t = undefined; + + if (b >= word_t.bits) { + output.s.high = 0; + output.s.low = input.s.high >> @intCast(b - word_t.bits); + } else if (b == 0) { + return a; + } else { + output.s.high = input.s.high >> @intCast(b); + output.s.low = input.s.high << @intCast(word_t.bits - b); + output.s.low |= input.s.low >> @intCast(b); + } + + return output.all; +} + +pub fn __ashlsi3(a: i32, b: i32) callconv(.c) i32 { + return ashlXi3(i32, a, b); +} + +pub fn __ashrsi3(a: i32, b: i32) callconv(.c) i32 { + return ashrXi3(i32, a, b); +} + +pub fn __lshrsi3(a: i32, b: i32) callconv(.c) i32 { + return lshrXi3(i32, a, b); +} + +pub fn __ashldi3(a: i64, b: i32) callconv(.c) i64 { + return ashlXi3(i64, a, b); +} +fn __aeabi_llsl(a: i64, b: i32) callconv(.{ .arm_aapcs = .{} }) i64 { + return ashlXi3(i64, a, b); +} + +pub fn __ashlti3(a: i128, b: i32) callconv(.c) i128 { + return ashlXi3(i128, a, b); +} + +pub fn __ashrdi3(a: i64, b: i32) callconv(.c) i64 { + return ashrXi3(i64, a, b); +} +fn __aeabi_lasr(a: i64, b: i32) callconv(.{ .arm_aapcs = .{} }) i64 { + return ashrXi3(i64, a, b); +} + +pub fn __ashrti3(a: i128, b: i32) callconv(.c) i128 { + return ashrXi3(i128, a, b); +} + +pub fn __lshrdi3(a: i64, b: i32) callconv(.c) i64 { + return lshrXi3(i64, a, b); +} +fn __aeabi_llsr(a: i64, b: i32) callconv(.{ .arm_aapcs = .{} }) i64 { + return lshrXi3(i64, a, b); +} + +pub fn __lshrti3(a: i128, b: i32) callconv(.c) i128 { + return lshrXi3(i128, a, b); +} + +test { + _ = @import("shift_test.zig"); +} diff --git a/build/compiler_rt/shift_test.zig b/build/compiler_rt/shift_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/sin.zig b/build/compiler_rt/sin.zig new file mode 100644 index 00000000..e14779d2 --- /dev/null +++ b/build/compiler_rt/sin.zig @@ -0,0 +1,203 @@ +//! Ported from musl, which is licensed under the MIT license: +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/sinf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/sin.c + +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; +const common = @import("common.zig"); + +const trig = @import("trig.zig"); +const rem_pio2 = @import("rem_pio2.zig").rem_pio2; +const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; + +pub const panic = common.panic; + +comptime { + @export(&__sinh, .{ .name = "__sinh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sinf, .{ .name = "sinf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sin, .{ .name = "sin", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__sinx, .{ .name = "__sinx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&sinq, .{ .name = "sinf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&sinq, .{ .name = "sinq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sinl, .{ .name = "sinl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __sinh(x: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(sinf(x)); +} + +pub fn sinf(x: f32) callconv(.c) f32 { + // Small multiples of pi/2 rounded to double precision. + const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 + const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 + const s3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 + const s4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18 + + var ix: u32 = @bitCast(x); + const sign = ix >> 31 != 0; + ix &= 0x7fffffff; + + if (ix <= 0x3f490fda) { // |x| ~<= pi/4 + if (ix < 0x39800000) { // |x| < 2**-12 + // raise inexact if x!=0 and underflow if subnormal + if (common.want_float_exceptions) { + if (ix < 0x00800000) { + mem.doNotOptimizeAway(x / 0x1p120); + } else { + mem.doNotOptimizeAway(x + 0x1p120); + } + } + return x; + } + return trig.__sindf(x); + } + if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 + if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4 + if (sign) { + return -trig.__cosdf(x + s1pio2); + } else { + return trig.__cosdf(x - s1pio2); + } + } + return trig.__sindf(if (sign) -(x + s2pio2) else -(x - s2pio2)); + } + if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 + if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4 + if (sign) { + return trig.__cosdf(x + s3pio2); + } else { + return -trig.__cosdf(x - s3pio2); + } + } + return trig.__sindf(if (sign) x + s4pio2 else x - s4pio2); + } + + // sin(Inf or NaN) is NaN + if (ix >= 0x7f800000) { + return x - x; + } + + var y: f64 = undefined; + const n = rem_pio2f(x, &y); + return switch (n & 3) { + 0 => trig.__sindf(y), + 1 => trig.__cosdf(y), + 2 => trig.__sindf(-y), + else => -trig.__cosdf(y), + }; +} + +pub fn sin(x: f64) callconv(.c) f64 { + var ix = @as(u64, @bitCast(x)) >> 32; + ix &= 0x7fffffff; + + // |x| ~< pi/4 + if (ix <= 0x3fe921fb) { + if (ix < 0x3e500000) { // |x| < 2**-26 + // raise inexact if x != 0 and underflow if subnormal + if (common.want_float_exceptions) { + if (ix < 0x00100000) { + mem.doNotOptimizeAway(x / 0x1p120); + } else { + mem.doNotOptimizeAway(x + 0x1p120); + } + } + return x; + } + return trig.__sin(x, 0.0, 0); + } + + // sin(Inf or NaN) is NaN + if (ix >= 0x7ff00000) { + return x - x; + } + + var y: [2]f64 = undefined; + const n = rem_pio2(x, &y); + return switch (n & 3) { + 0 => trig.__sin(y[0], y[1], 1), + 1 => trig.__cos(y[0], y[1]), + 2 => -trig.__sin(y[0], y[1], 1), + else => -trig.__cos(y[0], y[1]), + }; +} + +pub fn __sinx(x: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(sinq(x)); +} + +pub fn sinq(x: f128) callconv(.c) f128 { + // TODO: more correct implementation + return sin(@floatCast(x)); +} + +pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __sinh(x), + 32 => return sinf(x), + 64 => return sin(x), + 80 => return __sinx(x), + 128 => return sinq(x), + else => @compileError("unreachable"), + } +} + +test "sin32" { + const epsilon = 0.00001; + + try expect(math.approxEqAbs(f32, sinf(0.0), 0.0, epsilon)); + try expect(math.approxEqAbs(f32, sinf(0.2), 0.198669, epsilon)); + try expect(math.approxEqAbs(f32, sinf(0.8923), 0.778517, epsilon)); + try expect(math.approxEqAbs(f32, sinf(1.5), 0.997495, epsilon)); + try expect(math.approxEqAbs(f32, sinf(-1.5), -0.997495, epsilon)); + try expect(math.approxEqAbs(f32, sinf(37.45), -0.246544, epsilon)); + try expect(math.approxEqAbs(f32, sinf(89.123), 0.916166, epsilon)); +} + +test "sin64" { + const epsilon = 0.000001; + + try expect(math.approxEqAbs(f64, sin(0.0), 0.0, epsilon)); + try expect(math.approxEqAbs(f64, sin(0.2), 0.198669, epsilon)); + try expect(math.approxEqAbs(f64, sin(0.8923), 0.778517, epsilon)); + try expect(math.approxEqAbs(f64, sin(1.5), 0.997495, epsilon)); + try expect(math.approxEqAbs(f64, sin(-1.5), -0.997495, epsilon)); + try expect(math.approxEqAbs(f64, sin(37.45), -0.246543, epsilon)); + try expect(math.approxEqAbs(f64, sin(89.123), 0.916166, epsilon)); +} + +test "sin32.special" { + try expect(sinf(0.0) == 0.0); + try expect(sinf(-0.0) == -0.0); + try expect(math.isNan(sinf(math.inf(f32)))); + try expect(math.isNan(sinf(-math.inf(f32)))); + try expect(math.isNan(sinf(math.nan(f32)))); +} + +test "sin64.special" { + try expect(sin(0.0) == 0.0); + try expect(sin(-0.0) == -0.0); + try expect(math.isNan(sin(math.inf(f64)))); + try expect(math.isNan(sin(-math.inf(f64)))); + try expect(math.isNan(sin(math.nan(f64)))); +} + +test "sin32 #9901" { + const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000)); + _ = sinf(float); +} + +test "sin64 #9901" { + const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001)); + _ = sin(float); +} diff --git a/build/compiler_rt/sincos.zig b/build/compiler_rt/sincos.zig new file mode 100644 index 00000000..72b90a51 --- /dev/null +++ b/build/compiler_rt/sincos.zig @@ -0,0 +1,281 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const math = std.math; +const mem = std.mem; +const trig = @import("trig.zig"); +const rem_pio2 = @import("rem_pio2.zig").rem_pio2; +const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__sincosh, .{ .name = "__sincosh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sincosf, .{ .name = "sincosf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sincos, .{ .name = "sincos", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__sincosx, .{ .name = "__sincosx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&sincosq, .{ .name = "sincosf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&sincosq, .{ .name = "sincosq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sincosl, .{ .name = "sincosl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void { + // TODO: more efficient implementation + var big_sin: f32 = undefined; + var big_cos: f32 = undefined; + sincosf(x, &big_sin, &big_cos); + r_sin.* = @as(f16, @floatCast(big_sin)); + r_cos.* = @as(f16, @floatCast(big_cos)); +} + +pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { + const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 + const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 + const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 + const sc4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18 + + const pre_ix = @as(u32, @bitCast(x)); + const sign = pre_ix >> 31 != 0; + const ix = pre_ix & 0x7fffffff; + + // |x| ~<= pi/4 + if (ix <= 0x3f490fda) { + // |x| < 2**-12 + if (ix < 0x39800000) { + // raise inexact if x!=0 and underflow if subnormal + if (common.want_float_exceptions) { + if (ix < 0x00100000) { + mem.doNotOptimizeAway(x / 0x1p120); + } else { + mem.doNotOptimizeAway(x + 0x1p120); + } + } + r_sin.* = x; + r_cos.* = 1.0; + return; + } + r_sin.* = trig.__sindf(x); + r_cos.* = trig.__cosdf(x); + return; + } + + // |x| ~<= 5*pi/4 + if (ix <= 0x407b53d1) { + // |x| ~<= 3pi/4 + if (ix <= 0x4016cbe3) { + if (sign) { + r_sin.* = -trig.__cosdf(x + sc1pio2); + r_cos.* = trig.__sindf(x + sc1pio2); + } else { + r_sin.* = trig.__cosdf(sc1pio2 - x); + r_cos.* = trig.__sindf(sc1pio2 - x); + } + return; + } + // -sin(x+c) is not correct if x+c could be 0: -0 vs +0 + r_sin.* = -trig.__sindf(if (sign) x + sc2pio2 else x - sc2pio2); + r_cos.* = -trig.__cosdf(if (sign) x + sc2pio2 else x - sc2pio2); + return; + } + + // |x| ~<= 9*pi/4 + if (ix <= 0x40e231d5) { + // |x| ~<= 7*pi/4 + if (ix <= 0x40afeddf) { + if (sign) { + r_sin.* = trig.__cosdf(x + sc3pio2); + r_cos.* = -trig.__sindf(x + sc3pio2); + } else { + r_sin.* = -trig.__cosdf(x - sc3pio2); + r_cos.* = trig.__sindf(x - sc3pio2); + } + return; + } + r_sin.* = trig.__sindf(if (sign) x + sc4pio2 else x - sc4pio2); + r_cos.* = trig.__cosdf(if (sign) x + sc4pio2 else x - sc4pio2); + return; + } + + // sin(Inf or NaN) is NaN + if (ix >= 0x7f800000) { + const result = x - x; + r_sin.* = result; + r_cos.* = result; + return; + } + + // general argument reduction needed + var y: f64 = undefined; + const n = rem_pio2f(x, &y); + const s = trig.__sindf(y); + const c = trig.__cosdf(y); + switch (n & 3) { + 0 => { + r_sin.* = s; + r_cos.* = c; + }, + 1 => { + r_sin.* = c; + r_cos.* = -s; + }, + 2 => { + r_sin.* = -s; + r_cos.* = -c; + }, + else => { + r_sin.* = -c; + r_cos.* = s; + }, + } +} + +pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { + const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff; + + // |x| ~< pi/4 + if (ix <= 0x3fe921fb) { + // if |x| < 2**-27 * sqrt(2) + if (ix < 0x3e46a09e) { + // raise inexact if x != 0 and underflow if subnormal + if (common.want_float_exceptions) { + if (ix < 0x00100000) { + mem.doNotOptimizeAway(x / 0x1p120); + } else { + mem.doNotOptimizeAway(x + 0x1p120); + } + } + r_sin.* = x; + r_cos.* = 1.0; + return; + } + r_sin.* = trig.__sin(x, 0.0, 0); + r_cos.* = trig.__cos(x, 0.0); + return; + } + + // sincos(Inf or NaN) is NaN + if (ix >= 0x7ff00000) { + const result = x - x; + r_sin.* = result; + r_cos.* = result; + return; + } + + // argument reduction needed + var y: [2]f64 = undefined; + const n = rem_pio2(x, &y); + const s = trig.__sin(y[0], y[1], 1); + const c = trig.__cos(y[0], y[1]); + switch (n & 3) { + 0 => { + r_sin.* = s; + r_cos.* = c; + }, + 1 => { + r_sin.* = c; + r_cos.* = -s; + }, + 2 => { + r_sin.* = -s; + r_cos.* = -c; + }, + else => { + r_sin.* = -c; + r_cos.* = s; + }, + } +} + +pub fn __sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { + // TODO: more efficient implementation + //return sincos_generic(f80, x, r_sin, r_cos); + var big_sin: f128 = undefined; + var big_cos: f128 = undefined; + sincosq(x, &big_sin, &big_cos); + r_sin.* = @as(f80, @floatCast(big_sin)); + r_cos.* = @as(f80, @floatCast(big_cos)); +} + +pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { + // TODO: more correct implementation + //return sincos_generic(f128, x, r_sin, r_cos); + var small_sin: f64 = undefined; + var small_cos: f64 = undefined; + sincos(@as(f64, @floatCast(x)), &small_sin, &small_cos); + r_sin.* = small_sin; + r_cos.* = small_cos; +} + +pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __sincosh(x, r_sin, r_cos), + 32 => return sincosf(x, r_sin, r_cos), + 64 => return sincos(x, r_sin, r_cos), + 80 => return __sincosx(x, r_sin, r_cos), + 128 => return sincosq(x, r_sin, r_cos), + else => @compileError("unreachable"), + } +} + +pub const rem_pio2_generic = @compileError("TODO"); + +/// Ported from musl sincosl.c. Needs the following dependencies to be complete: +/// * rem_pio2_generic ported from __rem_pio2l.c +/// * trig.sin_generic ported from __sinl.c +/// * trig.cos_generic ported from __cosl.c +inline fn sincos_generic(comptime F: type, x: F, r_sin: *F, r_cos: *F) void { + const sc1pio4: F = 1.0 * math.pi / 4.0; + const bits = @typeInfo(F).float.bits; + const I = std.meta.Int(.unsigned, bits); + const ix = @as(I, @bitCast(x)) & (math.maxInt(I) >> 1); + const se: u16 = @truncate(ix >> (bits - 16)); + + if (se == 0x7fff) { + const result = x - x; + r_sin.* = result; + r_cos.* = result; + return; + } + + if (@as(F, @bitCast(ix)) < sc1pio4) { + if (se < 0x3fff - math.floatFractionalBits(F) - 1) { + // raise underflow if subnormal + if (se == 0) { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x * 0x1p-120); + } + r_sin.* = x; + // raise inexact if x!=0 + r_cos.* = 1.0 + x; + return; + } + r_sin.* = trig.sin_generic(F, x, 0, 0); + r_cos.* = trig.cos_generic(F, x, 0); + return; + } + + var y: [2]F = undefined; + const n = rem_pio2_generic(F, x, &y); + const s = trig.sin_generic(F, y[0], y[1], 1); + const c = trig.cos_generic(F, y[0], y[1]); + switch (n & 3) { + 0 => { + r_sin.* = s; + r_cos.* = c; + }, + 1 => { + r_sin.* = c; + r_cos.* = -s; + }, + 2 => { + r_sin.* = -s; + r_cos.* = -c; + }, + else => { + r_sin.* = -c; + r_cos.* = s; + }, + } +} diff --git a/build/compiler_rt/sqrt.zig b/build/compiler_rt/sqrt.zig new file mode 100644 index 00000000..ed460212 --- /dev/null +++ b/build/compiler_rt/sqrt.zig @@ -0,0 +1,750 @@ +//! Ported from musl, which is MIT licensed. +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/sqrtf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/sqrt.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/sqrtl.c + +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const math = std.math; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__sqrth, .{ .name = "__sqrth", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sqrtf, .{ .name = "sqrtf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sqrt, .{ .name = "sqrt", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__sqrtx, .{ .name = "__sqrtx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&sqrtq, .{ .name = "sqrtf128", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_sqrt, .{ .name = "_Qp_sqrt", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&sqrtq, .{ .name = "sqrtq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&sqrtl, .{ .name = "sqrtl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __sqrth(x: f16) callconv(.c) f16 { + var ix: u16 = @bitCast(x); + var top = ix >> 10; + + // special case handling. + if (top -% 0x01 >= 0x1F - 0x01) { + @branchHint(.unlikely); + // x < 0x1p-14 or inf or nan. + if (ix & 0x7FFF == 0) return x; + if (ix == 0x7C00) return x; + if (ix > 0x7C00) return math.nan(f16); + // x is subnormal, normalize it. + ix = @bitCast(x * 0x1p10); + top = (ix >> 10) -% 10; + } + + // argument reduction: + // x = 4^e m; with integer e, and m in [1, 4) + // m: fixed point representation [2.14] + // 2^e is the exponent part of the result. + const even = (top & 1) != 0; + const m = if (even) (ix << 4) & 0x7FFF else (ix << 5) | 0x8000; + top = (top +% 0x0F) >> 1; + + // approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4) + // the fixed point representations are + // m: 2.14 r: 0.16, s: 2.14, d: 2.14, u: 2.14, three: 2.14 + const three: u16 = 0xC000; + const i: usize = @intCast((ix >> 4) & 0x7F); + const r = __rsqrt_tab[i]; + // |r*sqrt(m) - 1| < 0x1p-8 + var s = mul16(m, r); + // |s/sqrt(m) - 1| < 0x1p-8 + const d = mul16(s, r); + const u = three - d; + s = mul16(s, u); // repr: 3.13 + // -0x1.20p-13 < s/sqrt(m) - 1 < 0x7Dp-16 + s = (s - 1) >> 3; // repr: 6.10 + // s < sqrt(m) < s + 0x1.24p-10 + + // compute nearest rounded result: + // the nearest result to 10 bits is either s or s+0x1p-10, + // we can decide by comparing (2^10 s + 0.5)^2 to 2^20 m. + const d0 = (m << 6) -% s *% s; + const d1 = s -% d0; + const d2 = d1 +% s +% 1; + s += d1 >> 15; + s &= 0x03FF; + s |= top << 10; + const y: f16 = @bitCast(s); + + // handle rounding modes and inexact exception: + // only (s+1)^2 == 2^6 m case is exact otherwise + // add a tiny value to cause the fenv effects. + if (d2 != 0) { + @branchHint(.likely); + var tiny: u16 = 0x0001; + tiny |= (d1 ^ d2) & 0x8000; + const t: f16 = @bitCast(tiny); + return y + t; + } + + return y; +} + +pub fn sqrtf(x: f32) callconv(.c) f32 { + var ix: u32 = @bitCast(x); + var top = ix >> 23; + + // special case handling. + if (top -% 0x01 >= 0xFF - 0x01) { + @branchHint(.unlikely); + // x < 0x1p-126 or inf or nan. + if (ix & 0x7FFF_FFFF == 0) return x; + if (ix == 0x7F80_0000) return x; + if (ix > 0x7F80_0000) return math.nan(f32); + // x is subnormal, normalize it. + ix = @bitCast(x * 0x1p23); + top = (ix >> 23) -% 23; + } + + // argument reduction: + // x = 4^e m; with integer e, and m in [1, 4) + // m: fixed point representation [2.30] + // 2^e is the exponent part of the result. + const even = (top & 1) != 0; + const m = if (even) (ix << 7) & 0x7FFF_FFFF else (ix << 8) | 0x8000_0000; + top = (top +% 0x7F) >> 1; + + // approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4) + // the fixed point representations are + // m: 2.30 r: 0.32, s: 2.30, d: 2.30, u: 2.30, three: 2.30 + const three: u32 = 0xC000_0000; + var i: usize = @intCast((ix >> 17) & 0x3F); + if (even) i += 64; + var r = @as(u32, @intCast(__rsqrt_tab[i])) << 16; + // |r*sqrt(m) - 1| < 0x1p-8 + var s = mul32(m, r); + // |s/sqrt(m) - 1| < 0x1p-8 + var d = mul32(s, r); + var u = three - d; + r = mul32(r, u) << 1; + // |r*sqrt(m) - 1| < 0x1.7bp-16 + s = mul32(s, u) << 1; + // |s/sqrt(m) - 1| < 0x1.7bp-16 + d = mul32(s, r); + u = three - d; + s = mul32(s, u); // repr: 3.29 + // -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 + s = (s - 1) >> 6; // repr: 9.23 + // s < sqrt(m) < s + 0x1.08p-23 + + // compute nearest rounded result: + // the nearest result to 23 bits is either s or s+0x1p-23, + // we can decide by comparing (2^23 s + 0.5)^2 to 2^46 m. + const d0 = (m << 16) -% s *% s; + const d1 = s -% d0; + const d2 = d1 +% s +% 1; + s += d1 >> 31; + s &= 0x007F_FFFF; + s |= top << 23; + const y: f32 = @bitCast(s); + + // handle rounding modes and inexact exception: + // only (s+1)^2 == 2^16 m case is exact otherwise + // add a tiny value to cause the fenv effects. + if (d2 != 0) { + @branchHint(.likely); + var tiny: u32 = 0x0100_0000; + tiny |= (d1 ^ d2) & 0x8000_0000; + const t: f32 = @bitCast(tiny); + return y + t; + } + + return y; +} + +pub fn sqrt(x: f64) callconv(.c) f64 { + var ix: u64 = @bitCast(x); + var top = ix >> 52; + + // special case handling. + if (top -% 0x001 >= 0x7FF - 0x001) { + @branchHint(.unlikely); + // x < 0x1p-1022 or inf or nan. + if (ix & 0x7FFF_FFFF_FFFF_FFFF == 0) return x; + if (ix == 0x7FF0_0000_0000_0000) return x; + if (ix > 0x7FF0_0000_0000_0000) return math.nan(f64); + // x is subnormal, normalize it. + ix = @bitCast(x * 0x1p52); + top = (ix >> 52) -% 52; + } + + // argument reduction: + // x = 4^e m; with integer e, and m in [1, 4) + // m: fixed point representation [2.62] + // 2^e is the exponent part of the result. + const even = (top & 1) != 0; + const m = if (even) (ix << 10) & 0x7FFF_FFFF_FFFF_FFFF else (ix << 11) | 0x8000_0000_0000_0000; + top = (top +% 0x3FF) >> 1; + + // approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4) + // + // initial estimate: + // 7bit table lookup (1bit exponent and 6bit significand). + // + // iterative approximation: + // using 2 goldschmidt iterations with 32bit int arithmetics + // and a final iteration with 64bit int arithmetics. + // + // details: + // + // the relative error (e = r0 sqrt(m)-1) of a linear estimate + // (r0 = a m + b) is |e| < 0.085955 ~ 0x1.6p-4 at best, + // a table lookup is faster and needs one less iteration + // 6 bit lookup table (128b) gives |e| < 0x1.f9p-8 + // 7 bit lookup table (256b) gives |e| < 0x1.fdp-9 + // for single and double prec 6bit is enough but for quad + // prec 7bit is needed (or modified iterations). to avoid + // one more iteration >=13bit table would be needed (16k). + // + // a newton-raphson iteration for r is + // w = r*r + // u = 3 - m*w + // r = r*u/2 + // can use a goldschmidt iteration for s at the end or + // s = m*r + // + // first goldschmidt iteration is + // s = m*r + // u = 3 - s*r + // r = r*u/2 + // s = s*u/2 + // next goldschmidt iteration is + // u = 3 - s*r + // r = r*u/2 + // s = s*u/2 + // and at the end r is not computed only s. + // + // they use the same amount of operations and converge at the + // same quadratic rate, i.e. if + // r1 sqrt(m) - 1 = e, then + // r2 sqrt(m) - 1 = -3/2 e^2 - 1/2 e^3 + // the advantage of goldschmidt is that the mul for s and r + // are independent (computed in parallel), however it is not + // "self synchronizing": it only uses the input m in the + // first iteration so rounding errors accumulate. at the end + // or when switching to larger precision arithmetics rounding + // errors dominate so the first iteration should be used. + // + // the fixed point representations are + // m: 2.30 r: 0.32, s: 2.30, d: 2.30, u: 2.30, three: 2.30 + // and after switching to 64 bit + // m: 2.62 r: 0.64, s: 2.62, d: 2.62, u: 2.62, three: 2.62 + const three: struct { u32, u64 } = .{ + 0xC000_0000, + 0xC000_0000_0000_0000, + }; + var r: struct { u32, u64 } = undefined; + var s: struct { u32, u64 } = undefined; + var d: struct { u32, u64 } = undefined; + var u: struct { u32, u64 } = undefined; + const i: usize = @intCast((ix >> 46) & 0x7F); + r[0] = @intCast(__rsqrt_tab[i]); + r[0] <<= 16; + // |r sqrt(m) - 1| < 0x1.fdp-9 + s[0] = mul32(@intCast(m >> 32), r[0]); + // |s/sqrt(m) - 1| < 0x1.fdp-9 + d[0] = mul32(s[0], r[0]); + u[0] = three[0] - d[0]; + r[0] = mul32(r[0], u[0]) << 1; + // |r sqrt(m) - 1| < 0x1.7bp-16 + s[0] = mul32(s[0], u[0]) << 1; + // |s/sqrt(m) - 1| < 0x1.7bp-16 + d[0] = mul32(s[0], r[0]); + u[0] = three[0] - d[0]; + r[0] = mul32(r[0], u[0]) << 1; + // |r sqrt(m) - 1| < 0x1.3704p-29 (measured worst-case) + r[1] = @intCast(r[0]); + r[1] <<= 32; + s[1] = mul64(m, r[1]); + d[1] = mul64(s[1], r[1]); + u[1] = three[1] - d[1]; + s[1] = mul64(s[1], u[1]); // repr: 3.61 + // -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 + s[1] = (s[1] - 2) >> 9; // repr: 12.52 + // -0x1.09p-52 < s - sqrt(m) < -0x1.fffcp-63 + + // s < sqrt(m) < s + 0x1.09p-52 + // compute nearest rounded result: + // the nearest result to 52 bits is either s or s+0x1p-52, + // we can decide by comparing (2^52 s + 0.5)^2 to 2^104 m. + const d0 = (m << 42) -% s[1] *% s[1]; + const d1 = s[1] -% d0; + const d2 = d1 +% s[1] +% 1; + s[1] += d1 >> 63; + s[1] &= 0x000F_FFFF_FFFF_FFFF; + s[1] |= top << 52; + const y: f64 = @bitCast(s[1]); + + // handle rounding modes and inexact exception: + // only (s+1)^2 == 2^42 m case is exact otherwise + // add a tiny value to cause the fenv effects. + if (d2 != 0) { + @branchHint(.likely); + var tiny: u64 = 0x0010_0000_0000_0000; + tiny |= (d1 ^ d2) & 0x8000_0000_0000_0000; + const t: f64 = @bitCast(tiny); + return y + t; + } + + return y; +} + +pub fn __sqrtx(x: f80) callconv(.c) f80 { + var ix: u80 = @bitCast(x); + var top = ix >> 64; + + // special case handling. + if (top -% 0x0001 >= 0x7FFF - 0x0001) { + @branchHint(.unlikely); + // x < 0x1p-16382 or inf or nan. + if (ix & 0x7FFF_FFFF_FFFF_FFFF_FFFF == 0) return x; + if (ix == 0x7FFF_8000_0000_0000_0000) return x; + if (ix > 0x7FFF_8000_0000_0000_0000) return math.nan(f80); + // x is subnormal, normalize it. + ix = @bitCast(x * 0x1p63); + top = (ix >> 64) -% 63; + } + + // argument reduction: + // x = 4^e m; with integer e, and m in [1, 4) + // m: fixed point representation [2.78] + // 2^e is the exponent part of the result. + const even = (top & 1) != 0; + const m = if (even) (ix << 15) & 0x7FFF_FFFF_FFFF_FFFF_FFFF else ix << 16; + top = (top +% 0x3FFF) >> 1; + + // approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4) + // the fixed point representations are + // m: 2.30 r: 0.32, s: 2.30, d: 2.30, u: 2.30, three: 2.30 + // and after switching to 64 bit + // m: 2.62 r: 0.64, s: 2.62, d: 2.62, u: 2.62, three: 2.62 + // and after switching to 80 bit + // m: 2.78 r: 0.80, s: 2.78, d: 2.78, u: 2.78, three: 2.78 + const three: struct { u32, u64, u80 } = .{ + 0xC000_0000, + 0xC000_0000_0000_0000, + 0xC000_0000_0000_0000_0000, + }; + var r: struct { u32, u64, u80 } = undefined; + var s: struct { u32, u64, u80 } = undefined; + var d: struct { u32, u64, u80 } = undefined; + var u: struct { u32, u64, u80 } = undefined; + var i: usize = @intCast((ix >> 57) & 0x3F); + if (even) i += 64; + r[0] = @intCast(__rsqrt_tab[i]); + r[0] <<= 16; + // |r sqrt(m) - 1| < 0x1p-8 + s[0] = mul32(@intCast(m >> 48), r[0]); + d[0] = mul32(s[0], r[0]); + u[0] = three[0] - d[0]; + r[0] = mul32(u[0], r[0]) << 1; + // |r sqrt(m) - 1| < 0x1.7bp-16, switch to 64bit + r[1] = @intCast(r[0]); + r[1] <<= 32; + s[1] = mul64(@intCast(m >> 16), r[1]); + d[1] = mul64(s[1], r[1]); + u[1] = three[1] - d[1]; + r[1] = mul64(u[1], r[1]) << 1; + // |r sqrt(m) - 1| < 0x1.a5p-31 + s[1] = mul64(u[1], s[1]) << 1; + d[1] = mul64(s[1], r[1]); + u[1] = three[1] - d[1]; + r[1] = mul64(u[1], r[1]) << 1; + // |r sqrt(m) - 1| < 0x1.c001p-59, switch to 80bit + r[2] = @intCast(r[1]); + r[2] <<= 16; + s[2] = mul80(m, r[2]); + d[2] = mul80(s[2], r[2]); + u[2] = three[2] - d[2]; + s[2] = mul80(u[2], s[2]); // repr: 3.77 + s[2] = (s[2] - 4) >> 14; // repr: 17.63 + // s < sqrt(m) < s + 1 ULP + tiny + + // compute nearest rounded result: + // the nearest result to 63 bits is either s or s+0x1p-63, + // we can decide by comparing (2^63 s + 0.5)^2 to 2^126 m + const d0 = (m << 48) -% mul80_tail(s[2], s[2]); + const d1 = s[2] -% d0; + const d2 = d1 +% s[2] +% 1; + s[2] += d1 >> 79; + s[2] &= 0x0000_7FFF_FFFF_FFFF_FFFF; + s[2] |= 0x0000_8000_0000_0000_0000; + s[2] |= top << 64; + const y: f80 = @bitCast(s[2]); + + // handle rounding modes and inexact exception: + // only (s+1)^2 == 2^48 m case is exact otherwise + // add a tiny value to cause the fenv effects. + if (d2 != 0) { + @branchHint(.likely); + var tiny: u80 = 0x0001_8000_0000_0000_0000; + tiny |= (d1 ^ d2) & 0x8000_0000_0000_0000_0000; + const t: f80 = @bitCast(tiny); + return y + t; + } + + return y; +} + +pub fn sqrtq(x: f128) callconv(.c) f128 { + var ix: u128 = @bitCast(x); + var top = ix >> 112; + + // special case handling. + if (top -% 0x0001 >= 0x7FFF - 0x0001) { + @branchHint(.unlikely); + // x < 0x1p-16382 or inf or nan. + if (ix & 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF == 0) return x; + if (ix == 0x7FFF_0000_0000_0000_0000_0000_0000_0000) return x; + if (ix > 0x7FFF_0000_0000_0000_0000_0000_0000_0000) return math.nan(f128); + // x is subnormal, normalize it. + ix = @bitCast(x * 0x1p112); + top = (ix >> 112) -% 112; + } + + // argument reduction: + // x = 4^e m; with integer e, and m in [1, 4) + // m: fixed point representation [2.126] + // 2^e is the exponent part of the result. + const even = (top & 1) != 0; + const m = if (even) (ix << 14) & 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF else (ix << 15) | 0x8000_0000_0000_0000_0000_0000_0000_0000; + top = (top +% 0x3FFF) >> 1; + + // approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4) + // the fixed point representations are + // m: 2.30 r: 0.32, s: 2.30, d: 2.30, u: 2.30, three: 2.30 + // and after switching to 64 bit + // m: 2.62 r: 0.64, s: 2.62, d: 2.62, u: 2.62, three: 2.62 + // and after switching to 128 bit + // m: 2.126 r: 0.128, s: 2.126, d: 2.126, u: 2.126, three: 2.126 + const three: struct { u32, u64, u128 } = .{ + 0xC000_0000, + 0xC000_0000_0000_0000, + 0xC000_0000_0000_0000_0000_0000_0000_0000, + }; + var r: struct { u32, u64, u128 } = undefined; + var s: struct { u32, u64, u128 } = undefined; + var d: struct { u32, u64, u128 } = undefined; + var u: struct { u32, u64, u128 } = undefined; + const i: usize = @intCast((ix >> 106) & 0x7F); + r[0] = @intCast(__rsqrt_tab[i]); + r[0] <<= 16; + // |r sqrt(m) - 1| < 0x1p-8 + s[0] = mul32(@intCast(m >> 96), r[0]); + d[0] = mul32(s[0], r[0]); + u[0] = three[0] - d[0]; + r[0] = mul32(u[0], r[0]) << 1; + // |r sqrt(m) - 1| < 0x1.7bp-16, switch to 64bit + r[1] = @intCast(r[0]); + r[1] <<= 32; + s[1] = mul64(@intCast(m >> 64), r[1]); + d[1] = mul64(s[1], r[1]); + u[1] = three[1] - d[1]; + r[1] = mul64(u[1], r[1]) << 1; + // |r sqrt(m) - 1| < 0x1.a5p-31 + s[1] = mul64(u[1], s[1]) << 1; + d[1] = mul64(s[1], r[1]); + u[1] = three[1] - d[1]; + r[1] = mul64(u[1], r[1]) << 1; + // |r sqrt(m) - 1| < 0x1.c001p-59, switch to 128bit + r[2] = @intCast(r[1]); + r[2] <<= 64; + s[2] = mul128(m, r[2]); + d[2] = mul128(s[2], r[2]); + u[2] = three[2] - d[2]; + s[2] = mul128(u[2], s[2]); // repr: 3.125 + // -0x1p-116 < s - sqrt(m) < 0x3.8001p-125 + s[2] = (s[2] - 4) >> 13; // repr: 16.122 + // s < sqrt(m) < s + 1 ULP + tiny + + // compute nearest rounded result: + // the nearest result to 122 bits is either s or s+0x1p-122, + // we can decide by comparing (2^122 s + 0.5)^2 to 2^244 m + const d0 = (m << 98) -% s[2] *% s[2]; + const d1 = s[2] -% d0; + const d2 = d1 +% s[2] +% 1; + s[2] += d1 >> 127; + s[2] &= 0x0000_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF; + s[2] |= top << 112; + const y: f128 = @bitCast(s[2]); + + // handle rounding modes and inexact exception: + // only (s+1)^2 == 2^98 m case is exact otherwise + // add a tiny value to cause the fenv effects. + if (d2 != 0) { + @branchHint(.likely); + var tiny: u128 = 0x0001_0000_0000_0000_0000_0000_0000_0000; + tiny |= (d1 ^ d2) & 0x8000_0000_0000_0000_0000_0000_0000_0000; + const t: f128 = @bitCast(tiny); + return y + t; + } + + return y; +} + +fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void { + c.* = sqrt(@floatCast(a.*)); +} + +pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __sqrth(x), + 32 => return sqrtf(x), + 64 => return sqrt(x), + 80 => return __sqrtx(x), + 128 => return sqrtq(x), + else => @compileError("unreachable"), + } +} + +const __rsqrt_tab: [128]u16 = .{ + 0xB451, 0xB2F0, 0xB196, 0xB044, 0xAEF9, 0xADB6, 0xAC79, 0xAB43, + 0xAA14, 0xA8EB, 0xA7C8, 0xA6AA, 0xA592, 0xA480, 0xA373, 0xA26B, + 0xA168, 0xA06A, 0x9F70, 0x9E7B, 0x9D8A, 0x9C9D, 0x9BB5, 0x9AD1, + 0x99F0, 0x9913, 0x983A, 0x9765, 0x9693, 0x95C4, 0x94F8, 0x9430, + 0x936B, 0x92A9, 0x91EA, 0x912E, 0x9075, 0x8FBE, 0x8F0A, 0x8E59, + 0x8DAA, 0x8CFE, 0x8C54, 0x8BAC, 0x8B07, 0x8A64, 0x89C4, 0x8925, + 0x8889, 0x87EE, 0x8756, 0x86C0, 0x862B, 0x8599, 0x8508, 0x8479, + 0x83EC, 0x8361, 0x82D8, 0x8250, 0x81C9, 0x8145, 0x80C2, 0x8040, + 0xFF02, 0xFD0E, 0xFB25, 0xF947, 0xF773, 0xF5AA, 0xF3EA, 0xF234, + 0xF087, 0xEEE3, 0xED47, 0xEBB3, 0xEA27, 0xE8A3, 0xE727, 0xE5B2, + 0xE443, 0xE2DC, 0xE17A, 0xE020, 0xDECB, 0xDD7D, 0xDC34, 0xDAF1, + 0xD9B3, 0xD87B, 0xD748, 0xD61A, 0xD4F1, 0xD3CD, 0xD2AD, 0xD192, + 0xD07B, 0xCF69, 0xCE5B, 0xCD51, 0xCC4A, 0xCB48, 0xCA4A, 0xC94F, + 0xC858, 0xC764, 0xC674, 0xC587, 0xC49D, 0xC3B7, 0xC2D4, 0xC1F4, + 0xC116, 0xC03C, 0xBF65, 0xBE90, 0xBDBE, 0xBCEF, 0xBC23, 0xBB59, + 0xBA91, 0xB9CC, 0xB90A, 0xB84A, 0xB78C, 0xB6D0, 0xB617, 0xB560, +}; + +inline fn mul16(a: u16, b: u16) u16 { + return @intCast(@as(u32, @intCast(a)) * @as(u32, @intCast(b)) >> 16); +} + +inline fn mul32(a: u32, b: u32) u32 { + return @intCast(@as(u64, @intCast(a)) * @as(u64, @intCast(b)) >> 32); +} + +inline fn mul64(a: u64, b: u64) u64 { + return @intCast(@as(u128, @intCast(a)) * @as(u128, @intCast(b)) >> 64); +} + +inline fn mul80(a: u80, b: u80) u80 { + const ahi = a >> 40; + const alo = a & 0xFF_FFFF_FFFF; + const bhi = b >> 40; + const blo = b & 0xFF_FFFF_FFFF; + return ahi * bhi + (ahi * blo >> 40) + (alo * bhi >> 40); +} + +inline fn mul128(a: u128, b: u128) u128 { + const ahi = a >> 64; + const alo = a & 0xFFFF_FFFF_FFFF_FFFF; + const bhi = b >> 64; + const blo = b & 0xFFFF_FFFF_FFFF_FFFF; + return ahi * bhi + (ahi * blo >> 64) + (alo * bhi >> 64); +} + +inline fn mul80_tail(a: u80, b: u80) u80 { + const ahi = a >> 40; + const alo = a & 0xFF_FFFF_FFFF; + const bhi = b >> 40; + const blo = b & 0xFF_FFFF_FFFF; + return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40); +} + +test "__sqrth" { + // sqrt(±0) is ±0 + try std.testing.expectEqual(__sqrth(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(__sqrth(-0x0.0p0), -0x0.0p0); + // sqrt(+max) is finite + try std.testing.expectEqual(__sqrth(0x1.FFCp15), 0x1.FFCp7); + // sqrt(4)=2 + try std.testing.expectEqual(__sqrth(0x1p2), 0x1p1); + // sqrt(x) for x=1, 1±ulp + try std.testing.expectEqual(__sqrth(0x1p0), 0x1p0); + try std.testing.expectEqual(__sqrth(0x1.004p0), 0x1p0); + try std.testing.expectEqual(__sqrth(0x1.FF8p-1), 0x1.FFCp-1); + // sqrt(+min) is non-zero + try std.testing.expectEqual(__sqrth(0x1p-14), 0x1p-7); + // sqrt(min subnormal) is non-zero + try std.testing.expectEqual(__sqrth(0x0.004p-14), 0x1p-12); + // sqrt(inf) is inf + try std.testing.expect(math.isInf(__sqrth(math.inf(f16)))); + // sqrt(nan) is nan + try std.testing.expect(math.isNan(__sqrth(math.nan(f16)))); + // sqrt(-ve) is nan + try std.testing.expect(math.isNan(__sqrth(-0x1p-14))); + try std.testing.expect(math.isNan(__sqrth(-0x1p+0))); + try std.testing.expect(math.isNan(__sqrth(-math.inf(f16)))); + // random arguments + try std.testing.expectEqual(__sqrth(0x1.1p14), 0x1.08p7); + try std.testing.expectEqual(__sqrth(0x1.C9p-12), 0x1.56p-6); + try std.testing.expectEqual(__sqrth(0x1.CE8p-7), 0x1.E68p-4); + try std.testing.expectEqual(__sqrth(0x1.134p-7), 0x1.778p-4); + try std.testing.expectEqual(__sqrth(0x1.E9Cp-10), 0x1.62p-5); + try std.testing.expectEqual(__sqrth(0x1.3Dp9), 0x1.92Cp4); + try std.testing.expectEqual(__sqrth(0x1.AA4p8), 0x1.4A4p4); + try std.testing.expectEqual(__sqrth(0x1.8A8p4), 0x1.3DCp2); + try std.testing.expectEqual(__sqrth(0x1.8Fp-7), 0x1.C4p-4); + try std.testing.expectEqual(__sqrth(0x1.584p-11), 0x1.A3Cp-6); +} + +test "sqrtf" { + // sqrt(±0) is ±0 + try std.testing.expectEqual(sqrtf(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(sqrtf(-0x0.0p0), -0x0.0p0); + // sqrt(+max) is finite + try std.testing.expectEqual(sqrtf(0x1.FFFFFEp127), 0x1.FFFFFEp63); + // sqrt(4)=2 + try std.testing.expectEqual(sqrtf(0x1p2), 0x1p1); + // sqrt(x) for x=1, 1±ulp + try std.testing.expectEqual(sqrtf(0x1p0), 0x1p0); + try std.testing.expectEqual(sqrtf(0x1.000002p0), 0x1p0); + try std.testing.expectEqual(sqrtf(0x1.FFFFFEp-1), 0x1.FFFFFEp-1); + // sqrt(+min) is non-zero + try std.testing.expectEqual(sqrtf(0x1p-126), 0x1p-63); + // sqrt(min subnormal) is non-zero + try std.testing.expectEqual(sqrtf(0x0.000002p-126), 0x1.6a09e6p-75); + // sqrt(inf) is inf + try std.testing.expect(math.isInf(sqrtf(math.inf(f32)))); + // sqrt(nan) is nan + try std.testing.expect(math.isNan(sqrtf(math.nan(f32)))); + // sqrt(-ve) is nan + try std.testing.expect(math.isNan(sqrtf(-0x1p-149))); + try std.testing.expect(math.isNan(sqrtf(-0x1p0))); + try std.testing.expect(math.isNan(sqrtf(-math.inf(f32)))); + // random arguments + try std.testing.expectEqual(sqrtf(0x1.4DD57Ep77), 0x1.9D6DA8p38); + try std.testing.expectEqual(sqrtf(0x1.871848p102), 0x1.3C6AFAp51); + try std.testing.expectEqual(sqrtf(0x1.A1D748p-112), 0x1.470EFCp-56); + try std.testing.expectEqual(sqrtf(0x1.E626C2p18), 0x1.60C80Ep9); + try std.testing.expectEqual(sqrtf(0x1.E80E66p-29), 0x1.F3E282p-15); + try std.testing.expectEqual(sqrtf(0x1.B47204p89), 0x1.D8B732p44); + try std.testing.expectEqual(sqrtf(0x1.77F45p15), 0x1.B6BC3Ap7); + try std.testing.expectEqual(sqrtf(0x1.AD5F5p-48), 0x1.4B8A72p-24); + try std.testing.expectEqual(sqrtf(0x1.91A39p-76), 0x1.40A7A8p-38); + try std.testing.expectEqual(sqrtf(0x1.DAE088p79), 0x1.ED16DCp39); +} + +test "sqrt" { + // sqrt(±0) is ±0 + try std.testing.expectEqual(sqrt(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(sqrt(-0x0.0p0), -0x0.0p0); + // sqrt(+max) is finite + try std.testing.expectEqual(sqrt(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511); + // sqrt(4)=2 + try std.testing.expectEqual(sqrt(0x1p2), 0x1p1); + // sqrt(x) for x=1, 1±ulp + try std.testing.expectEqual(sqrt(0x1p0), 0x1p0); + try std.testing.expectEqual(sqrt(0x1p0 + math.floatEps(f64)), 0x1p0); + try std.testing.expectEqual(sqrt(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1); + // sqrt(+min) is non-zero + try std.testing.expectEqual(sqrt(math.floatMin(f64)), 0x1p-511); + // sqrt(min subnormal) is non-zero + try std.testing.expectEqual(sqrt(math.floatTrueMin(f64)), 0x1p-537); + // sqrt(inf) is inf + try std.testing.expect(math.isInf(sqrt(math.inf(f64)))); + // sqrt(nan) is nan + try std.testing.expect(math.isNan(sqrt(math.nan(f64)))); + // sqrt(-ve) is nan + try std.testing.expect(math.isNan(sqrt(-0x1p-1074))); + try std.testing.expect(math.isNan(sqrt(-0x1p0))); + try std.testing.expect(math.isNan(sqrt(-math.inf(f64)))); + // random arguments + try std.testing.expectEqual(sqrt(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235); + try std.testing.expectEqual(sqrt(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395); + try std.testing.expectEqual(sqrt(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69); + try std.testing.expectEqual(sqrt(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139); + try std.testing.expectEqual(sqrt(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458); + try std.testing.expectEqual(sqrt(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125); + try std.testing.expectEqual(sqrt(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243); + try std.testing.expectEqual(sqrt(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169); + try std.testing.expectEqual(sqrt(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133); + try std.testing.expectEqual(sqrt(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178); +} + +test "__sqrtx" { + // sqrt(±0) is ±0 + try std.testing.expectEqual(__sqrtx(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(__sqrtx(-0x0.0p0), -0x0.0p0); + // sqrt(+max) is finite + try std.testing.expectEqual(__sqrtx(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191); + // sqrt(4)=2 + try std.testing.expectEqual(__sqrtx(0x1p2), 0x1p1); + // sqrt(x) for x=1, 1±ulp + try std.testing.expectEqual(__sqrtx(0x1p0), 0x1p0); + try std.testing.expectEqual(__sqrtx(0x1p0 + math.floatEps(f80)), 0x1p0); + try std.testing.expectEqual(__sqrtx(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1); + // sqrt(+min) is non-zero + try std.testing.expectEqual(__sqrtx(math.floatMin(f80)), 0x1p-8191); + // sqrt(min subnormal) is non-zero + try std.testing.expectEqual(__sqrtx(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223); + // sqrt(inf) is inf + try std.testing.expect(math.isInf(__sqrtx(math.inf(f80)))); + // sqrt(nan) is nan + try std.testing.expect(math.isNan(__sqrtx(math.nan(f80)))); + // sqrt(-ve) is nan + try std.testing.expect(math.isNan(__sqrtx(-0x1p-16442))); + try std.testing.expect(math.isNan(__sqrtx(-0x1p0))); + try std.testing.expect(math.isNan(__sqrtx(-math.inf(f80)))); + // random arguments + try std.testing.expectEqual(__sqrtx(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741); + try std.testing.expectEqual(__sqrtx(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165); + try std.testing.expectEqual(__sqrtx(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856); + try std.testing.expectEqual(__sqrtx(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432); + try std.testing.expectEqual(__sqrtx(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591); + try std.testing.expectEqual(__sqrtx(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315); + try std.testing.expectEqual(__sqrtx(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517); + try std.testing.expectEqual(__sqrtx(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706); + try std.testing.expectEqual(__sqrtx(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760); + try std.testing.expectEqual(__sqrtx(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685); +} + +test "sqrtq" { + // sqrt(±0) is ±0 + try std.testing.expectEqual(sqrtq(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(sqrtq(-0x0.0p0), -0x0.0p0); + // sqrt(+max) is finite + try std.testing.expectEqual(sqrtq(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191); + // sqrt(4)=2 + try std.testing.expectEqual(sqrtq(0x1p2), 0x1p1); + // sqrt(x) for x=1, 1±ulp + try std.testing.expectEqual(sqrtq(0x1p0), 0x1p0); + try std.testing.expectEqual(sqrtq(0x1p0 + math.floatEps(f128)), 0x1p0); + try std.testing.expectEqual(sqrtq(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1); + // sqrt(+min) is non-zero + try std.testing.expectEqual(sqrtq(math.floatMin(f128)), 0x1p-8191); + // sqrt(min subnormal) is non-zero + try std.testing.expectEqual(sqrtq(math.floatTrueMin(f128)), 0x1p-8247); + // sqrt(inf) is inf + try std.testing.expect(math.isInf(sqrtq(math.inf(f128)))); + // sqrt(nan) is nan + try std.testing.expect(math.isNan(sqrtq(math.nan(f128)))); + // sqrt(-ve) is nan + try std.testing.expect(math.isNan(sqrtq(-0x1p-16442))); + try std.testing.expect(math.isNan(sqrtq(-0x1p0))); + try std.testing.expect(math.isNan(sqrtq(-math.inf(f128)))); + // random arguments + try std.testing.expectEqual(sqrtq(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681); + try std.testing.expectEqual(sqrtq(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882); + try std.testing.expectEqual(sqrtq(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812); + try std.testing.expectEqual(sqrtq(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031); + try std.testing.expectEqual(sqrtq(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513); + try std.testing.expectEqual(sqrtq(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917); + try std.testing.expectEqual(sqrtq(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256); + try std.testing.expectEqual(sqrtq(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476); + try std.testing.expectEqual(sqrtq(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446); + try std.testing.expectEqual(sqrtq(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976); +} diff --git a/build/compiler_rt/ssp.zig b/build/compiler_rt/ssp.zig new file mode 100644 index 00000000..f0882cff --- /dev/null +++ b/build/compiler_rt/ssp.zig @@ -0,0 +1,143 @@ +//! +//! Small Zig reimplementation of gcc's libssp. +//! +//! This library implements most of the builtins required by the stack smashing +//! protection as implemented by gcc&clang. +//! Missing exports: +//! - __gets_chk +//! - __mempcpy_chk +//! - __snprintf_chk +//! - __sprintf_chk +//! - __stpcpy_chk +//! - __vsnprintf_chk +//! - __vsprintf_chk + +const std = @import("std"); +const common = @import("./common.zig"); +const builtin = @import("builtin"); + +extern fn memset(dest: ?[*]u8, c: u8, n: usize) callconv(.c) ?[*]u8; +extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8; +extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8; + +comptime { + @export(&__stack_chk_fail, .{ .name = "__stack_chk_fail", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__chk_fail, .{ .name = "__chk_fail", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__stack_chk_guard, .{ .name = "__stack_chk_guard", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__strcpy_chk, .{ .name = "__strcpy_chk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__strncpy_chk, .{ .name = "__strncpy_chk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__strcat_chk, .{ .name = "__strcat_chk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__strncat_chk, .{ .name = "__strncat_chk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__memcpy_chk, .{ .name = "__memcpy_chk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__memmove_chk, .{ .name = "__memmove_chk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__memset_chk, .{ .name = "__memset_chk", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __stack_chk_fail() callconv(.c) noreturn { + @panic("stack smashing detected"); +} + +fn __chk_fail() callconv(.c) noreturn { + @panic("buffer overflow detected"); +} + +// TODO: Initialize the canary with random data +var __stack_chk_guard: usize = blk: { + var buf = [1]u8{0} ** @sizeOf(usize); + buf[@sizeOf(usize) - 1] = 255; + buf[@sizeOf(usize) - 2] = '\n'; + break :blk @as(usize, @bitCast(buf)); +}; + +fn __strcpy_chk(dest: [*:0]u8, src: [*:0]const u8, dest_n: usize) callconv(.c) [*:0]u8 { + @setRuntimeSafety(false); + + var i: usize = 0; + while (i < dest_n and src[i] != 0) : (i += 1) { + dest[i] = src[i]; + } + + if (i == dest_n) __chk_fail(); + + dest[i] = 0; + + return dest; +} + +fn __strncpy_chk(dest: [*:0]u8, src: [*:0]const u8, n: usize, dest_n: usize) callconv(.c) [*:0]u8 { + @setRuntimeSafety(false); + if (dest_n < n) __chk_fail(); + var i: usize = 0; + while (i < n and src[i] != 0) : (i += 1) { + dest[i] = src[i]; + } + while (i < n) : (i += 1) { + dest[i] = 0; + } + return dest; +} + +fn __strcat_chk(dest: [*:0]u8, src: [*:0]const u8, dest_n: usize) callconv(.c) [*:0]u8 { + @setRuntimeSafety(false); + + var avail = dest_n; + + var dest_end: usize = 0; + while (avail > 0 and dest[dest_end] != 0) : (dest_end += 1) { + avail -= 1; + } + + if (avail < 1) __chk_fail(); + + var i: usize = 0; + while (avail > 0 and src[i] != 0) : (i += 1) { + dest[dest_end + i] = src[i]; + avail -= 1; + } + + if (avail < 1) __chk_fail(); + + dest[dest_end + i] = 0; + + return dest; +} + +fn __strncat_chk(dest: [*:0]u8, src: [*:0]const u8, n: usize, dest_n: usize) callconv(.c) [*:0]u8 { + @setRuntimeSafety(false); + + var avail = dest_n; + + var dest_end: usize = 0; + while (avail > 0 and dest[dest_end] != 0) : (dest_end += 1) { + avail -= 1; + } + + if (avail < 1) __chk_fail(); + + var i: usize = 0; + while (avail > 0 and i < n and src[i] != 0) : (i += 1) { + dest[dest_end + i] = src[i]; + avail -= 1; + } + + if (avail < 1) __chk_fail(); + + dest[dest_end + i] = 0; + + return dest; +} + +fn __memcpy_chk(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize, dest_n: usize) callconv(.c) ?[*]u8 { + if (dest_n < n) __chk_fail(); + return memcpy(dest, src, n); +} + +fn __memmove_chk(dest: ?[*]u8, src: ?[*]const u8, n: usize, dest_n: usize) callconv(.c) ?[*]u8 { + if (dest_n < n) __chk_fail(); + return memmove(dest, src, n); +} + +fn __memset_chk(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.c) ?[*]u8 { + if (dest_n < n) __chk_fail(); + return memset(dest, c, n); +} diff --git a/build/compiler_rt/stack_probe.zig b/build/compiler_rt/stack_probe.zig new file mode 100644 index 00000000..21259ec4 --- /dev/null +++ b/build/compiler_rt/stack_probe.zig @@ -0,0 +1,271 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const os_tag = builtin.os.tag; +const arch = builtin.cpu.arch; +const abi = builtin.abi; + +pub const panic = common.panic; + +comptime { + if (builtin.os.tag == .windows) { + // Default stack-probe functions emitted by LLVM + if (builtin.target.isMinGW()) { + @export(&_chkstk, .{ .name = "_alloca", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__chkstk, .{ .name = "__chkstk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&___chkstk, .{ .name = "__alloca", .linkage = common.linkage, .visibility = common.visibility }); + @export(&___chkstk, .{ .name = "___chkstk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__chkstk_ms, .{ .name = "__chkstk_ms", .linkage = common.linkage, .visibility = common.visibility }); + @export(&___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = common.linkage, .visibility = common.visibility }); + } else if (!builtin.link_libc) { + // This symbols are otherwise exported by MSVCRT.lib + @export(&_chkstk, .{ .name = "_chkstk", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__chkstk, .{ .name = "__chkstk", .linkage = common.linkage, .visibility = common.visibility }); + } + } + + switch (arch) { + .x86, + .x86_64, + => { + @export(&zig_probe_stack, .{ .name = "__zig_probe_stack", .linkage = common.linkage, .visibility = common.visibility }); + }, + else => {}, + } +} + +// Zig's own stack-probe routine (available only on x86 and x86_64) +pub fn zig_probe_stack() callconv(.naked) void { + @setRuntimeSafety(false); + + // Versions of the Linux kernel before 5.1 treat any access below SP as + // invalid so let's update it on the go, otherwise we'll get a segfault + // instead of triggering the stack growth. + + switch (arch) { + .x86_64 => { + // %rax = probe length, %rsp = stack pointer + asm volatile ( + \\ push %%rcx + \\ mov %%rax, %%rcx + \\ cmp $0x1000,%%rcx + \\ jb 2f + \\ 1: + \\ sub $0x1000,%%rsp + \\ orl $0,16(%%rsp) + \\ sub $0x1000,%%rcx + \\ cmp $0x1000,%%rcx + \\ ja 1b + \\ 2: + \\ sub %%rcx, %%rsp + \\ orl $0,16(%%rsp) + \\ add %%rax,%%rsp + \\ pop %%rcx + \\ ret + ); + }, + .x86 => { + // %eax = probe length, %esp = stack pointer + asm volatile ( + \\ push %%ecx + \\ mov %%eax, %%ecx + \\ cmp $0x1000,%%ecx + \\ jb 2f + \\ 1: + \\ sub $0x1000,%%esp + \\ orl $0,8(%%esp) + \\ sub $0x1000,%%ecx + \\ cmp $0x1000,%%ecx + \\ ja 1b + \\ 2: + \\ sub %%ecx, %%esp + \\ orl $0,8(%%esp) + \\ add %%eax,%%esp + \\ pop %%ecx + \\ ret + ); + }, + else => {}, + } + + unreachable; +} + +fn win_probe_stack_only() void { + @setRuntimeSafety(false); + + switch (arch) { + .thumb => { + asm volatile ( + \\ lsl r4, r4, #2 + \\ mov r12, sp + \\ push {r5, r6} + \\ mov r5, r4 + \\1: + \\ sub r12, r12, #4096 + \\ subs r5, r5, #4096 + \\ ldr r6, [r12] + \\ bgt 1b + \\ pop {r5, r6} + \\ bx lr + ); + }, + .aarch64 => { + asm volatile ( + \\ lsl x16, x15, #4 + \\ mov x17, sp + \\1: + \\ + \\ sub x17, x17, 4096 + \\ subs x16, x16, 4096 + \\ ldr xzr, [x17] + \\ b.gt 1b + \\ + \\ ret + ); + }, + .x86_64 => { + asm volatile ( + \\ pushq %%rcx + \\ pushq %%rax + \\ cmpq $0x1000,%%rax + \\ leaq 24(%%rsp),%%rcx + \\ jb 1f + \\ 2: + \\ subq $0x1000,%%rcx + \\ testq %%rcx,(%%rcx) + \\ subq $0x1000,%%rax + \\ cmpq $0x1000,%%rax + \\ ja 2b + \\ 1: + \\ subq %%rax,%%rcx + \\ testq %%rcx,(%%rcx) + \\ popq %%rax + \\ popq %%rcx + \\ retq + ); + }, + .x86 => { + asm volatile ( + \\ push %%ecx + \\ push %%eax + \\ cmp $0x1000,%%eax + \\ lea 12(%%esp),%%ecx + \\ jb 1f + \\ 2: + \\ sub $0x1000,%%ecx + \\ test %%ecx,(%%ecx) + \\ sub $0x1000,%%eax + \\ cmp $0x1000,%%eax + \\ ja 2b + \\ 1: + \\ sub %%eax,%%ecx + \\ test %%ecx,(%%ecx) + \\ pop %%eax + \\ pop %%ecx + \\ ret + ); + }, + else => {}, + } + + unreachable; +} + +fn win_probe_stack_adjust_sp() void { + @setRuntimeSafety(false); + + switch (arch) { + .x86_64 => { + asm volatile ( + \\ pushq %%rcx + \\ cmpq $0x1000,%%rax + \\ leaq 16(%%rsp),%%rcx + \\ jb 1f + \\ 2: + \\ subq $0x1000,%%rcx + \\ testq %%rcx,(%%rcx) + \\ subq $0x1000,%%rax + \\ cmpq $0x1000,%%rax + \\ ja 2b + \\ 1: + \\ subq %%rax,%%rcx + \\ testq %%rcx,(%%rcx) + \\ + \\ leaq 8(%%rsp),%%rax + \\ movq %%rcx,%%rsp + \\ movq -8(%%rax),%%rcx + \\ pushq (%%rax) + \\ subq %%rsp,%%rax + \\ retq + ); + }, + .x86 => { + asm volatile ( + \\ push %%ecx + \\ cmp $0x1000,%%eax + \\ lea 8(%%esp),%%ecx + \\ jb 1f + \\ 2: + \\ sub $0x1000,%%ecx + \\ test %%ecx,(%%ecx) + \\ sub $0x1000,%%eax + \\ cmp $0x1000,%%eax + \\ ja 2b + \\ 1: + \\ sub %%eax,%%ecx + \\ test %%ecx,(%%ecx) + \\ + \\ lea 4(%%esp),%%eax + \\ mov %%ecx,%%esp + \\ mov -4(%%eax),%%ecx + \\ push (%%eax) + \\ sub %%esp,%%eax + \\ ret + ); + }, + else => {}, + } + + unreachable; +} + +// Windows has a multitude of stack-probing functions with similar names and +// slightly different behaviours: some behave as alloca() and update the stack +// pointer after probing the stack, other do not. +// +// Function name | Adjusts the SP? | +// | x86 | x86_64 | +// ---------------------------------------- +// _chkstk (_alloca) | yes | yes | +// __chkstk | yes | no | +// __chkstk_ms | no | no | +// ___chkstk (__alloca) | yes | yes | +// ___chkstk_ms | no | no | + +pub fn _chkstk() callconv(.naked) void { + @setRuntimeSafety(false); + @call(.always_inline, win_probe_stack_adjust_sp, .{}); +} +pub fn __chkstk() callconv(.naked) void { + @setRuntimeSafety(false); + if (arch == .thumb or arch == .aarch64) { + @call(.always_inline, win_probe_stack_only, .{}); + } else switch (arch) { + .x86 => @call(.always_inline, win_probe_stack_adjust_sp, .{}), + .x86_64 => @call(.always_inline, win_probe_stack_only, .{}), + else => unreachable, + } +} +pub fn ___chkstk() callconv(.naked) void { + @setRuntimeSafety(false); + @call(.always_inline, win_probe_stack_adjust_sp, .{}); +} +pub fn __chkstk_ms() callconv(.naked) void { + @setRuntimeSafety(false); + @call(.always_inline, win_probe_stack_only, .{}); +} +pub fn ___chkstk_ms() callconv(.naked) void { + @setRuntimeSafety(false); + @call(.always_inline, win_probe_stack_only, .{}); +} diff --git a/build/compiler_rt/strlen.zig b/build/compiler_rt/strlen.zig new file mode 100644 index 00000000..01d4e760 --- /dev/null +++ b/build/compiler_rt/strlen.zig @@ -0,0 +1,10 @@ +const std = @import("std"); +const common = @import("common.zig"); + +comptime { + @export(&strlen, .{ .name = "strlen", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn strlen(s: [*:0]const c_char) callconv(.c) usize { + return std.mem.len(s); +} diff --git a/build/compiler_rt/subdf3.zig b/build/compiler_rt/subdf3.zig new file mode 100644 index 00000000..24ded58e --- /dev/null +++ b/build/compiler_rt/subdf3.zig @@ -0,0 +1,25 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_dsub, .{ .name = "__aeabi_dsub", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__subdf3, .{ .name = "__subdf3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +fn __subdf3(a: f64, b: f64) callconv(.c) f64 { + return sub(a, b); +} + +fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return sub(a, b); +} + +inline fn sub(a: f64, b: f64) f64 { + const neg_b = @as(f64, @bitCast(@as(u64, @bitCast(b)) ^ (@as(u64, 1) << 63))); + return addf3(f64, a, neg_b); +} diff --git a/build/compiler_rt/subhf3.zig b/build/compiler_rt/subhf3.zig new file mode 100644 index 00000000..cc42eb92 --- /dev/null +++ b/build/compiler_rt/subhf3.zig @@ -0,0 +1,13 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + @export(&__subhf3, .{ .name = "__subhf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __subhf3(a: f16, b: f16) callconv(.c) f16 { + const neg_b = @as(f16, @bitCast(@as(u16, @bitCast(b)) ^ (@as(u16, 1) << 15))); + return addf3(f16, a, neg_b); +} diff --git a/build/compiler_rt/subo.zig b/build/compiler_rt/subo.zig new file mode 100644 index 00000000..b4fb8f77 --- /dev/null +++ b/build/compiler_rt/subo.zig @@ -0,0 +1,47 @@ +//! subo - subtract overflow +//! * return a-%b. +//! * return if a-b overflows => 1 else => 0 +//! - suboXi4_generic as default + +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__subosi4, .{ .name = "__subosi4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__subodi4, .{ .name = "__subodi4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__suboti4, .{ .name = "__suboti4", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __subosi4(a: i32, b: i32, overflow: *c_int) callconv(.c) i32 { + return suboXi4_generic(i32, a, b, overflow); +} +pub fn __subodi4(a: i64, b: i64, overflow: *c_int) callconv(.c) i64 { + return suboXi4_generic(i64, a, b, overflow); +} +pub fn __suboti4(a: i128, b: i128, overflow: *c_int) callconv(.c) i128 { + return suboXi4_generic(i128, a, b, overflow); +} + +inline fn suboXi4_generic(comptime ST: type, a: ST, b: ST, overflow: *c_int) ST { + overflow.* = 0; + const sum: ST = a -% b; + // Hackers Delight: section Overflow Detection, subsection Signed Add/Subtract + // Let sum = a -% b == a - b - carry == wraparound subtraction. + // Overflow in a-b-carry occurs, iff a and b have opposite signs + // and the sign of a-b-carry is opposite of a (or equivalently same as b). + // Faster routine: res = (a ^ b) & (sum ^ a) + // Slower routine: res = (sum^a) & ~(sum^b) + // Overflow occurred, iff (res < 0) + if (((a ^ b) & (sum ^ a)) < 0) + overflow.* = 1; + return sum; +} + +test { + _ = @import("subosi4_test.zig"); + _ = @import("subodi4_test.zig"); + _ = @import("suboti4_test.zig"); +} diff --git a/build/compiler_rt/subodi4_test.zig b/build/compiler_rt/subodi4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/subosi4_test.zig b/build/compiler_rt/subosi4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/suboti4_test.zig b/build/compiler_rt/suboti4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/subsf3.zig b/build/compiler_rt/subsf3.zig new file mode 100644 index 00000000..f3bb334b --- /dev/null +++ b/build/compiler_rt/subsf3.zig @@ -0,0 +1,25 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_fsub, .{ .name = "__aeabi_fsub", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__subsf3, .{ .name = "__subsf3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +fn __subsf3(a: f32, b: f32) callconv(.c) f32 { + return sub(a, b); +} + +fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + return sub(a, b); +} + +inline fn sub(a: f32, b: f32) f32 { + const neg_b = @as(f32, @bitCast(@as(u32, @bitCast(b)) ^ (@as(u32, 1) << 31))); + return addf3(f32, a, neg_b); +} diff --git a/build/compiler_rt/subtf3.zig b/build/compiler_rt/subtf3.zig new file mode 100644 index 00000000..aff4904a --- /dev/null +++ b/build/compiler_rt/subtf3.zig @@ -0,0 +1,26 @@ +const common = @import("./common.zig"); +const addf3 = @import("./addf3.zig").addf3; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__subtf3, .{ .name = "__subkf3", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_sub, .{ .name = "_Qp_sub", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__subtf3, .{ .name = "__subtf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __subtf3(a: f128, b: f128) callconv(.c) f128 { + return sub(a, b); +} + +fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { + c.* = sub(a.*, b.*); +} + +inline fn sub(a: f128, b: f128) f128 { + const neg_b = @as(f128, @bitCast(@as(u128, @bitCast(b)) ^ (@as(u128, 1) << 127))); + return addf3(f128, a, neg_b); +} diff --git a/build/compiler_rt/subvdi3.zig b/build/compiler_rt/subvdi3.zig new file mode 100644 index 00000000..8248e930 --- /dev/null +++ b/build/compiler_rt/subvdi3.zig @@ -0,0 +1,26 @@ +const subv = @import("subo.zig"); +const common = @import("./common.zig"); +const testing = @import("std").testing; + +pub const panic = common.panic; + +comptime { + @export(&__subvdi3, .{ .name = "__subvdi3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 { + var overflow: c_int = 0; + const sum = subv.__subodi4(a, b, &overflow); + if (overflow != 0) @panic("compiler-rt: integer overflow"); + return sum; +} + +test "subvdi3" { + // min i64 = -9223372036854775808 + // max i64 = 9223372036854775807 + // TODO write panic handler for testing panics + // try test__subvdi3(-9223372036854775808, -1, -1); // panic + // try test__addvdi3(9223372036854775807, 1, 1); // panic + try testing.expectEqual(-9223372036854775808, __subvdi3(-9223372036854775807, 1)); + try testing.expectEqual(9223372036854775807, __subvdi3(9223372036854775806, -1)); +} diff --git a/build/compiler_rt/subvsi3.zig b/build/compiler_rt/subvsi3.zig new file mode 100644 index 00000000..8a2ea6c6 --- /dev/null +++ b/build/compiler_rt/subvsi3.zig @@ -0,0 +1,26 @@ +const subv = @import("subo.zig"); +const common = @import("./common.zig"); +const testing = @import("std").testing; + +pub const panic = common.panic; + +comptime { + @export(&__subvsi3, .{ .name = "__subvsi3", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 { + var overflow: c_int = 0; + const sum = subv.__subosi4(a, b, &overflow); + if (overflow != 0) @panic("compiler-rt: integer overflow"); + return sum; +} + +test "subvsi3" { + // min i32 = -2147483648 + // max i32 = 2147483647 + // TODO write panic handler for testing panics + // try test__subvsi3(-2147483648, -1, -1); // panic + // try test__subvsi3(2147483647, 1, 1); // panic + try testing.expectEqual(-2147483648, __subvsi3(-2147483647, 1)); + try testing.expectEqual(2147483647, __subvsi3(2147483646, -1)); +} diff --git a/build/compiler_rt/subxf3.zig b/build/compiler_rt/subxf3.zig new file mode 100644 index 00000000..e79dd230 --- /dev/null +++ b/build/compiler_rt/subxf3.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const common = @import("./common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__subxf3, .{ .name = "__subxf3", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __subxf3(a: f80, b: f80) callconv(.c) f80 { + var b_rep = std.math.F80.fromFloat(b); + b_rep.exp ^= 0x8000; + const neg_b = b_rep.toFloat(); + return a + neg_b; +} diff --git a/build/compiler_rt/tan.zig b/build/compiler_rt/tan.zig new file mode 100644 index 00000000..af8d68eb --- /dev/null +++ b/build/compiler_rt/tan.zig @@ -0,0 +1,182 @@ +//! Ported from musl, which is licensed under the MIT license: +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/tanf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/tan.c +//! https://golang.org/src/math/tan.go + +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; + +const kernel = @import("trig.zig"); +const rem_pio2 = @import("rem_pio2.zig").rem_pio2; +const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; + +const arch = builtin.cpu.arch; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__tanh, .{ .name = "__tanh", .linkage = common.linkage, .visibility = common.visibility }); + @export(&tanf, .{ .name = "tanf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&tan, .{ .name = "tan", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__tanx, .{ .name = "__tanx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&tanq, .{ .name = "tanf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&tanq, .{ .name = "tanq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&tanl, .{ .name = "tanl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __tanh(x: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(tanf(x)); +} + +pub fn tanf(x: f32) callconv(.c) f32 { + // Small multiples of pi/2 rounded to double precision. + const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 + const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 + const t3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 + const t4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18 + + var ix: u32 = @bitCast(x); + const sign = ix >> 31 != 0; + ix &= 0x7fffffff; + + if (ix <= 0x3f490fda) { // |x| ~<= pi/4 + if (ix < 0x39800000) { // |x| < 2**-12 + // raise inexact if x!=0 and underflow if subnormal + if (common.want_float_exceptions) { + if (ix < 0x00800000) { + mem.doNotOptimizeAway(x / 0x1p120); + } else { + mem.doNotOptimizeAway(x + 0x1p120); + } + } + return x; + } + return kernel.__tandf(x, false); + } + if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 + if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4 + return kernel.__tandf((if (sign) x + t1pio2 else x - t1pio2), true); + } else { + return kernel.__tandf((if (sign) x + t2pio2 else x - t2pio2), false); + } + } + if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 + if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4 + return kernel.__tandf((if (sign) x + t3pio2 else x - t3pio2), true); + } else { + return kernel.__tandf((if (sign) x + t4pio2 else x - t4pio2), false); + } + } + + // tan(Inf or NaN) is NaN + if (ix >= 0x7f800000) { + return x - x; + } + + var y: f64 = undefined; + const n = rem_pio2f(x, &y); + return kernel.__tandf(y, n & 1 != 0); +} + +pub fn tan(x: f64) callconv(.c) f64 { + var ix = @as(u64, @bitCast(x)) >> 32; + ix &= 0x7fffffff; + + // |x| ~< pi/4 + if (ix <= 0x3fe921fb) { + if (ix < 0x3e400000) { // |x| < 2**-27 + // raise inexact if x!=0 and underflow if subnormal + if (common.want_float_exceptions) { + if (ix < 0x00100000) { + mem.doNotOptimizeAway(x / 0x1p120); + } else { + mem.doNotOptimizeAway(x + 0x1p120); + } + } + return x; + } + return kernel.__tan(x, 0.0, false); + } + + // tan(Inf or NaN) is NaN + if (ix >= 0x7ff00000) { + return x - x; + } + + var y: [2]f64 = undefined; + const n = rem_pio2(x, &y); + return kernel.__tan(y[0], y[1], n & 1 != 0); +} + +pub fn __tanx(x: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(tanq(x)); +} + +pub fn tanq(x: f128) callconv(.c) f128 { + // TODO: more correct implementation + return tan(@floatCast(x)); +} + +pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __tanh(x), + 32 => return tanf(x), + 64 => return tan(x), + 80 => return __tanx(x), + 128 => return tanq(x), + else => @compileError("unreachable"), + } +} + +test "tan" { + try expect(tan(@as(f32, 0.0)) == tanf(0.0)); + try expect(tan(@as(f64, 0.0)) == tan(0.0)); +} + +test "tan32" { + const epsilon = 0.00001; + + try expect(math.approxEqAbs(f32, tanf(0.0), 0.0, epsilon)); + try expect(math.approxEqAbs(f32, tanf(0.2), 0.202710, epsilon)); + try expect(math.approxEqAbs(f32, tanf(0.8923), 1.240422, epsilon)); + try expect(math.approxEqAbs(f32, tanf(1.5), 14.101420, epsilon)); + try expect(math.approxEqAbs(f32, tanf(37.45), -0.254397, epsilon)); + try expect(math.approxEqAbs(f32, tanf(89.123), 2.285852, epsilon)); +} + +test "tan64" { + const epsilon = 0.000001; + + try expect(math.approxEqAbs(f64, tan(0.0), 0.0, epsilon)); + try expect(math.approxEqAbs(f64, tan(0.2), 0.202710, epsilon)); + try expect(math.approxEqAbs(f64, tan(0.8923), 1.240422, epsilon)); + try expect(math.approxEqAbs(f64, tan(1.5), 14.101420, epsilon)); + try expect(math.approxEqAbs(f64, tan(37.45), -0.254397, epsilon)); + try expect(math.approxEqAbs(f64, tan(89.123), 2.2858376, epsilon)); +} + +test "tan32.special" { + try expect(tanf(0.0) == 0.0); + try expect(tanf(-0.0) == -0.0); + try expect(math.isNan(tanf(math.inf(f32)))); + try expect(math.isNan(tanf(-math.inf(f32)))); + try expect(math.isNan(tanf(math.nan(f32)))); +} + +test "tan64.special" { + try expect(tan(0.0) == 0.0); + try expect(tan(-0.0) == -0.0); + try expect(math.isNan(tan(math.inf(f64)))); + try expect(math.isNan(tan(-math.inf(f64)))); + try expect(math.isNan(tan(math.nan(f64)))); +} diff --git a/build/compiler_rt/trig.zig b/build/compiler_rt/trig.zig new file mode 100644 index 00000000..616dcf53 --- /dev/null +++ b/build/compiler_rt/trig.zig @@ -0,0 +1,273 @@ +// Ported from musl, which is licensed under the MIT license: +// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +// +// https://git.musl-libc.org/cgit/musl/tree/src/math/__cos.c +// https://git.musl-libc.org/cgit/musl/tree/src/math/__cosdf.c +// https://git.musl-libc.org/cgit/musl/tree/src/math/__sin.c +// https://git.musl-libc.org/cgit/musl/tree/src/math/__sindf.c +// https://git.musl-libc.org/cgit/musl/tree/src/math/__tand.c +// https://git.musl-libc.org/cgit/musl/tree/src/math/__tandf.c + +/// kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 +/// Input x is assumed to be bounded by ~pi/4 in magnitude. +/// Input y is the tail of x. +/// +/// Algorithm +/// 1. Since cos(-x) = cos(x), we need only to consider positive x. +/// 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. +/// 3. cos(x) is approximated by a polynomial of degree 14 on +/// [0,pi/4] +/// 4 14 +/// cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x +/// where the remez error is +/// +/// | 2 4 6 8 10 12 14 | -58 +/// |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 +/// | | +/// +/// 4 6 8 10 12 14 +/// 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then +/// cos(x) ~ 1 - x*x/2 + r +/// since cos(x+y) ~ cos(x) - sin(x)*y +/// ~ cos(x) - x*y, +/// a correction term is necessary in cos(x) and hence +/// cos(x+y) = 1 - (x*x/2 - (r - x*y)) +/// For better accuracy, rearrange to +/// cos(x+y) ~ w + (tmp + (r-x*y)) +/// where w = 1 - x*x/2 and tmp is a tiny correction term +/// (1 - x*x/2 == w + tmp exactly in infinite precision). +/// The exactness of w + tmp in infinite precision depends on w +/// and tmp having the same precision as x. If they have extra +/// precision due to compiler bugs, then the extra precision is +/// only good provided it is retained in all terms of the final +/// expression for cos(). Retention happens in all cases tested +/// under FreeBSD, so don't pessimize things by forcibly clipping +/// any extra precision in w. +pub fn __cos(x: f64, y: f64) f64 { + const C1 = 4.16666666666666019037e-02; // 0x3FA55555, 0x5555554C + const C2 = -1.38888888888741095749e-03; // 0xBF56C16C, 0x16C15177 + const C3 = 2.48015872894767294178e-05; // 0x3EFA01A0, 0x19CB1590 + const C4 = -2.75573143513906633035e-07; // 0xBE927E4F, 0x809C52AD + const C5 = 2.08757232129817482790e-09; // 0x3E21EE9E, 0xBDB4B1C4 + const C6 = -1.13596475577881948265e-11; // 0xBDA8FAE9, 0xBE8838D4 + + const z = x * x; + const zs = z * z; + const r = z * (C1 + z * (C2 + z * C3)) + zs * zs * (C4 + z * (C5 + z * C6)); + const hz = 0.5 * z; + const w = 1.0 - hz; + return w + (((1.0 - w) - hz) + (z * r - x * y)); +} + +pub fn __cosdf(x: f64) f32 { + // |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). + const C0 = -0x1ffffffd0c5e81.0p-54; // -0.499999997251031003120 + const C1 = 0x155553e1053a42.0p-57; // 0.0416666233237390631894 + const C2 = -0x16c087e80f1e27.0p-62; // -0.00138867637746099294692 + const C3 = 0x199342e0ee5069.0p-68; // 0.0000243904487962774090654 + + // Try to optimize for parallel evaluation as in __tandf.c. + const z = x * x; + const w = z * z; + const r = C2 + z * C3; + return @floatCast(((1.0 + z * C0) + w * C1) + (w * z) * r); +} + +/// kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 +/// Input x is assumed to be bounded by ~pi/4 in magnitude. +/// Input y is the tail of x. +/// Input iy indicates whether y is 0. (if iy=0, y assume to be 0). +/// +/// Algorithm +/// 1. Since sin(-x) = -sin(x), we need only to consider positive x. +/// 2. Callers must return sin(-0) = -0 without calling here since our +/// odd polynomial is not evaluated in a way that preserves -0. +/// Callers may do the optimization sin(x) ~ x for tiny x. +/// 3. sin(x) is approximated by a polynomial of degree 13 on +/// [0,pi/4] +/// 3 13 +/// sin(x) ~ x + S1*x + ... + S6*x +/// where +/// +/// |sin(x) 2 4 6 8 10 12 | -58 +/// |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 +/// | x | +/// +/// 4. sin(x+y) = sin(x) + sin'(x')*y +/// ~ sin(x) + (1-x*x/2)*y +/// For better accuracy, let +/// 3 2 2 2 2 +/// r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) +/// then 3 2 +/// sin(x) = x + (S1*x + (x *(r-y/2)+y)) +pub fn __sin(x: f64, y: f64, iy: i32) f64 { + const S1 = -1.66666666666666324348e-01; // 0xBFC55555, 0x55555549 + const S2 = 8.33333333332248946124e-03; // 0x3F811111, 0x1110F8A6 + const S3 = -1.98412698298579493134e-04; // 0xBF2A01A0, 0x19C161D5 + const S4 = 2.75573137070700676789e-06; // 0x3EC71DE3, 0x57B1FE7D + const S5 = -2.50507602534068634195e-08; // 0xBE5AE5E6, 0x8A2B9CEB + const S6 = 1.58969099521155010221e-10; // 0x3DE5D93A, 0x5ACFD57C + + const z = x * x; + const w = z * z; + const r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6); + const v = z * x; + if (iy == 0) { + return x + v * (S1 + z * r); + } else { + return x - ((z * (0.5 * y - v * r) - y) - v * S1); + } +} + +pub fn __sindf(x: f64) f32 { + // |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). + const S1 = -0x15555554cbac77.0p-55; // -0.166666666416265235595 + const S2 = 0x111110896efbb2.0p-59; // 0.0083333293858894631756 + const S3 = -0x1a00f9e2cae774.0p-65; // -0.000198393348360966317347 + const S4 = 0x16cd878c3b46a7.0p-71; // 0.0000027183114939898219064 + + // Try to optimize for parallel evaluation as in __tandf.c. + const z = x * x; + const w = z * z; + const r = S3 + z * S4; + const s = z * x; + return @floatCast((x + s * (S1 + z * S2)) + s * w * r); +} + +/// kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 +/// Input x is assumed to be bounded by ~pi/4 in magnitude. +/// Input y is the tail of x. +/// Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned. +/// +/// Algorithm +/// 1. Since tan(-x) = -tan(x), we need only to consider positive x. +/// 2. Callers must return tan(-0) = -0 without calling here since our +/// odd polynomial is not evaluated in a way that preserves -0. +/// Callers may do the optimization tan(x) ~ x for tiny x. +/// 3. tan(x) is approximated by a odd polynomial of degree 27 on +/// [0,0.67434] +/// 3 27 +/// tan(x) ~ x + T1*x + ... + T13*x +/// where +/// +/// |tan(x) 2 4 26 | -59.2 +/// |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 +/// | x | +/// +/// Note: tan(x+y) = tan(x) + tan'(x)*y +/// ~ tan(x) + (1+x*x)*y +/// Therefore, for better accuracy in computing tan(x+y), let +/// 3 2 2 2 2 +/// r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) +/// then +/// 3 2 +/// tan(x+y) = x + (T1*x + (x *(r+y)+y)) +/// +/// 4. For x in [0.67434,pi/4], let y = pi/4 - x, then +/// tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) +/// = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) +pub fn __tan(x_: f64, y_: f64, odd: bool) f64 { + var x = x_; + var y = y_; + + const T = [_]f64{ + 3.33333333333334091986e-01, // 3FD55555, 55555563 + 1.33333333333201242699e-01, // 3FC11111, 1110FE7A + 5.39682539762260521377e-02, // 3FABA1BA, 1BB341FE + 2.18694882948595424599e-02, // 3F9664F4, 8406D637 + 8.86323982359930005737e-03, // 3F8226E3, E96E8493 + 3.59207910759131235356e-03, // 3F6D6D22, C9560328 + 1.45620945432529025516e-03, // 3F57DBC8, FEE08315 + 5.88041240820264096874e-04, // 3F4344D8, F2F26501 + 2.46463134818469906812e-04, // 3F3026F7, 1A8D1068 + 7.81794442939557092300e-05, // 3F147E88, A03792A6 + 7.14072491382608190305e-05, // 3F12B80F, 32F0A7E9 + -1.85586374855275456654e-05, // BEF375CB, DB605373 + 2.59073051863633712884e-05, // 3EFB2A70, 74BF7AD4 + }; + const pio4 = 7.85398163397448278999e-01; // 3FE921FB, 54442D18 + const pio4lo = 3.06161699786838301793e-17; // 3C81A626, 33145C07 + + var z: f64 = undefined; + var r: f64 = undefined; + var v: f64 = undefined; + var w: f64 = undefined; + var s: f64 = undefined; + var a: f64 = undefined; + var w0: f64 = undefined; + var a0: f64 = undefined; + var hx: u32 = undefined; + var sign: bool = undefined; + + hx = @intCast(@as(u64, @bitCast(x)) >> 32); + const big = (hx & 0x7fffffff) >= 0x3FE59428; // |x| >= 0.6744 + if (big) { + sign = hx >> 31 != 0; + if (sign) { + x = -x; + y = -y; + } + x = (pio4 - x) + (pio4lo - y); + y = 0.0; + } + z = x * x; + w = z * z; + + // Break x^5*(T[1]+x^2*T[2]+...) into + // x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + // x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] + w * T[11])))); + v = z * (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] + w * T[12]))))); + s = z * x; + r = y + z * (s * (r + v) + y) + s * T[0]; + w = x + r; + if (big) { + s = @floatFromInt(1 - 2 * @as(i3, @intFromBool(odd))); + v = s - 2.0 * (x + (r - w * w / (w + s))); + return if (sign) -v else v; + } + if (!odd) { + return w; + } + // -1.0/(x+r) has up to 2ulp error, so compute it accurately + w0 = w; + w0 = @bitCast(@as(u64, @bitCast(w0)) & 0xffffffff00000000); + v = r - (w0 - x); // w0+v = r+x + a = -1.0 / w; + a0 = a; + a0 = @bitCast(@as(u64, @bitCast(a0)) & 0xffffffff00000000); + return a0 + a * (1.0 + a0 * w0 + a0 * v); +} + +pub fn __tandf(x: f64, odd: bool) f32 { + // |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). + const T = [_]f64{ + 0x15554d3418c99f.0p-54, // 0.333331395030791399758 + 0x1112fd38999f72.0p-55, // 0.133392002712976742718 + 0x1b54c91d865afe.0p-57, // 0.0533812378445670393523 + 0x191df3908c33ce.0p-58, // 0.0245283181166547278873 + 0x185dadfcecf44e.0p-61, // 0.00297435743359967304927 + 0x1362b9bf971bcd.0p-59, // 0.00946564784943673166728 + }; + + const z = x * x; + // Split up the polynomial into small independent terms to give + // opportunities for parallel evaluation. The chosen splitting is + // micro-optimized for Athlons (XP, X64). It costs 2 multiplications + // relative to Horner's method on sequential machines. + // + // We add the small terms from lowest degree up for efficiency on + // non-sequential machines (the lowest degree terms tend to be ready + // earlier). Apart from this, we don't care about order of + // operations, and don't need to to care since we have precision to + // spare. However, the chosen splitting is good for accuracy too, + // and would give results as accurate as Horner's method if the + // small terms were added from highest degree down. + const r = T[4] + z * T[5]; + const t = T[2] + z * T[3]; + const w = z * z; + const s = z * x; + const u = T[0] + z * T[1]; + const r0 = (x + s * u) + (s * w) * (t + w * r); + return @floatCast(if (odd) -1.0 / r0 else r0); +} diff --git a/build/compiler_rt/trunc.zig b/build/compiler_rt/trunc.zig new file mode 100644 index 00000000..ff829ea7 --- /dev/null +++ b/build/compiler_rt/trunc.zig @@ -0,0 +1,153 @@ +//! Ported from musl, which is MIT licensed. +//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT +//! +//! https://git.musl-libc.org/cgit/musl/tree/src/math/truncf.c +//! https://git.musl-libc.org/cgit/musl/tree/src/math/trunc.c + +const std = @import("std"); +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; +const math = std.math; +const mem = std.mem; +const expect = std.testing.expect; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__trunch, .{ .name = "__trunch", .linkage = common.linkage, .visibility = common.visibility }); + @export(&truncf, .{ .name = "truncf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&trunc, .{ .name = "trunc", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__truncx, .{ .name = "__truncx", .linkage = common.linkage, .visibility = common.visibility }); + if (common.want_ppc_abi) { + @export(&truncq, .{ .name = "truncf128", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&truncq, .{ .name = "truncq", .linkage = common.linkage, .visibility = common.visibility }); + @export(&truncl, .{ .name = "truncl", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __trunch(x: f16) callconv(.c) f16 { + // TODO: more efficient implementation + return @floatCast(truncf(x)); +} + +pub fn truncf(x: f32) callconv(.c) f32 { + const u: u32 = @bitCast(x); + var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9; + var m: u32 = undefined; + + if (e >= 23 + 9) { + return x; + } + if (e < 9) { + e = 1; + } + + m = @as(u32, math.maxInt(u32)) >> @intCast(e); + if (u & m == 0) { + return x; + } else { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); + return @bitCast(u & ~m); + } +} + +pub fn trunc(x: f64) callconv(.c) f64 { + const u: u64 = @bitCast(x); + var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12; + var m: u64 = undefined; + + if (e >= 52 + 12) { + return x; + } + if (e < 12) { + e = 1; + } + + m = @as(u64, math.maxInt(u64)) >> @intCast(e); + if (u & m == 0) { + return x; + } else { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); + return @bitCast(u & ~m); + } +} + +pub fn __truncx(x: f80) callconv(.c) f80 { + // TODO: more efficient implementation + return @floatCast(truncq(x)); +} + +pub fn truncq(x: f128) callconv(.c) f128 { + const u: u128 = @bitCast(x); + var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16; + var m: u128 = undefined; + + if (e >= 112 + 16) { + return x; + } + if (e < 16) { + e = 1; + } + + m = @as(u128, math.maxInt(u128)) >> @intCast(e); + if (u & m == 0) { + return x; + } else { + if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); + return @bitCast(u & ~m); + } +} + +pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble { + switch (@typeInfo(c_longdouble).float.bits) { + 16 => return __trunch(x), + 32 => return truncf(x), + 64 => return trunc(x), + 80 => return __truncx(x), + 128 => return truncq(x), + else => @compileError("unreachable"), + } +} + +test "trunc32" { + try expect(truncf(1.3) == 1.0); + try expect(truncf(-1.3) == -1.0); + try expect(truncf(0.2) == 0.0); +} + +test "trunc64" { + try expect(trunc(1.3) == 1.0); + try expect(trunc(-1.3) == -1.0); + try expect(trunc(0.2) == 0.0); +} + +test "trunc128" { + try expect(truncq(1.3) == 1.0); + try expect(truncq(-1.3) == -1.0); + try expect(truncq(0.2) == 0.0); +} + +test "trunc32.special" { + try expect(truncf(0.0) == 0.0); // 0x3F800000 + try expect(truncf(-0.0) == -0.0); + try expect(math.isPositiveInf(truncf(math.inf(f32)))); + try expect(math.isNegativeInf(truncf(-math.inf(f32)))); + try expect(math.isNan(truncf(math.nan(f32)))); +} + +test "trunc64.special" { + try expect(trunc(0.0) == 0.0); + try expect(trunc(-0.0) == -0.0); + try expect(math.isPositiveInf(trunc(math.inf(f64)))); + try expect(math.isNegativeInf(trunc(-math.inf(f64)))); + try expect(math.isNan(trunc(math.nan(f64)))); +} + +test "trunc128.special" { + try expect(truncq(0.0) == 0.0); + try expect(truncq(-0.0) == -0.0); + try expect(math.isPositiveInf(truncq(math.inf(f128)))); + try expect(math.isNegativeInf(truncq(-math.inf(f128)))); + try expect(math.isNan(truncq(math.nan(f128)))); +} diff --git a/build/compiler_rt/truncdfhf2.zig b/build/compiler_rt/truncdfhf2.zig new file mode 100644 index 00000000..a24650dd --- /dev/null +++ b/build/compiler_rt/truncdfhf2.zig @@ -0,0 +1,19 @@ +const common = @import("./common.zig"); +const truncf = @import("./truncf.zig").truncf; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_d2h, .{ .name = "__aeabi_d2h", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__truncdfhf2, .{ .name = "__truncdfhf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __truncdfhf2(a: f64) callconv(.c) common.F16T(f64) { + return @bitCast(truncf(f16, f64, a)); +} + +fn __aeabi_d2h(a: f64) callconv(.{ .arm_aapcs = .{} }) u16 { + return @bitCast(truncf(f16, f64, a)); +} diff --git a/build/compiler_rt/truncdfsf2.zig b/build/compiler_rt/truncdfsf2.zig new file mode 100644 index 00000000..fd42d5d3 --- /dev/null +++ b/build/compiler_rt/truncdfsf2.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const truncf = @import("./truncf.zig").truncf; + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_d2f, .{ .name = "__aeabi_d2f", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__truncdfsf2, .{ .name = "__truncdfsf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __truncdfsf2(a: f64) callconv(.c) f32 { + return truncf(f32, f64, a); +} + +fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 { + return truncf(f32, f64, a); +} diff --git a/build/compiler_rt/truncf.zig b/build/compiler_rt/truncf.zig new file mode 100644 index 00000000..5c116811 --- /dev/null +++ b/build/compiler_rt/truncf.zig @@ -0,0 +1,186 @@ +const std = @import("std"); + +pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { + const src_rep_t = std.meta.Int(.unsigned, @typeInfo(src_t).float.bits); + const dst_rep_t = std.meta.Int(.unsigned, @typeInfo(dst_t).float.bits); + const srcSigBits = std.math.floatMantissaBits(src_t); + const dstSigBits = std.math.floatMantissaBits(dst_t); + + // Various constants whose values follow from the type parameters. + // Any reasonable optimizer will fold and propagate all of these. + const srcBits = @typeInfo(src_t).float.bits; + const srcExpBits = srcBits - srcSigBits - 1; + const srcInfExp = (1 << srcExpBits) - 1; + const srcExpBias = srcInfExp >> 1; + + const srcMinNormal = 1 << srcSigBits; + const srcSignificandMask = srcMinNormal - 1; + const srcInfinity = srcInfExp << srcSigBits; + const srcSignMask = 1 << (srcSigBits + srcExpBits); + const srcAbsMask = srcSignMask - 1; + const roundMask = (1 << (srcSigBits - dstSigBits)) - 1; + const halfway = 1 << (srcSigBits - dstSigBits - 1); + const srcQNaN = 1 << (srcSigBits - 1); + const srcNaNCode = srcQNaN - 1; + + const dstBits = @typeInfo(dst_t).float.bits; + const dstExpBits = dstBits - dstSigBits - 1; + const dstInfExp = (1 << dstExpBits) - 1; + const dstExpBias = dstInfExp >> 1; + + const underflowExponent = srcExpBias + 1 - dstExpBias; + const overflowExponent = srcExpBias + dstInfExp - dstExpBias; + const underflow = underflowExponent << srcSigBits; + const overflow = overflowExponent << srcSigBits; + + const dstQNaN = 1 << (dstSigBits - 1); + const dstNaNCode = dstQNaN - 1; + + // Break a into a sign and representation of the absolute value + const aRep: src_rep_t = @bitCast(a); + const aAbs: src_rep_t = aRep & srcAbsMask; + const sign: src_rep_t = aRep & srcSignMask; + var absResult: dst_rep_t = undefined; + + if (aAbs -% underflow < aAbs -% overflow) { + // The exponent of a is within the range of normal numbers in the + // destination format. We can convert by simply right-shifting with + // rounding and adjusting the exponent. + absResult = @truncate(aAbs >> (srcSigBits - dstSigBits)); + absResult -%= @as(dst_rep_t, srcExpBias - dstExpBias) << dstSigBits; + + const roundBits: src_rep_t = aAbs & roundMask; + if (roundBits > halfway) { + // Round to nearest + absResult += 1; + } else if (roundBits == halfway) { + // Ties to even + absResult += absResult & 1; + } + } else if (aAbs > srcInfinity) { + // a is NaN. + // Conjure the result by beginning with infinity, setting the qNaN + // bit and inserting the (truncated) trailing NaN field. + absResult = @as(dst_rep_t, @intCast(dstInfExp)) << dstSigBits; + absResult |= dstQNaN; + absResult |= @intCast(((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode); + } else if (aAbs >= overflow) { + // a overflows to infinity. + absResult = @as(dst_rep_t, @intCast(dstInfExp)) << dstSigBits; + } else { + // a underflows on conversion to the destination type or is an exact + // zero. The result may be a denormal or zero. Extract the exponent + // to get the shift amount for the denormalization. + const aExp: u32 = @intCast(aAbs >> srcSigBits); + const shift: u32 = @intCast(srcExpBias - dstExpBias - aExp + 1); + + const significand: src_rep_t = (aRep & srcSignificandMask) | srcMinNormal; + + // Right shift by the denormalization amount with sticky. + if (shift > srcSigBits) { + absResult = 0; + } else { + const sticky: src_rep_t = @intFromBool(significand << @intCast(srcBits - shift) != 0); + const denormalizedSignificand: src_rep_t = significand >> @intCast(shift) | sticky; + absResult = @intCast(denormalizedSignificand >> (srcSigBits - dstSigBits)); + const roundBits: src_rep_t = denormalizedSignificand & roundMask; + if (roundBits > halfway) { + // Round to nearest + absResult += 1; + } else if (roundBits == halfway) { + // Ties to even + absResult += absResult & 1; + } + } + } + + const result: dst_rep_t align(@alignOf(dst_t)) = absResult | + @as(dst_rep_t, @truncate(sign >> @intCast(srcBits - dstBits))); + return @bitCast(result); +} + +pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t { + const dst_rep_t = std.meta.Int(.unsigned, @typeInfo(dst_t).float.bits); + const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit + const dst_sig_bits = std.math.floatMantissaBits(dst_t); + + const src_exp_bias = 16383; + + const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1; + const halfway = 1 << (src_sig_bits - dst_sig_bits - 1); + + const dst_bits = @typeInfo(dst_t).float.bits; + const dst_exp_bits = dst_bits - dst_sig_bits - 1; + const dst_inf_exp = (1 << dst_exp_bits) - 1; + const dst_exp_bias = dst_inf_exp >> 1; + + const underflow = src_exp_bias + 1 - dst_exp_bias; + const overflow = src_exp_bias + dst_inf_exp - dst_exp_bias; + + const dst_qnan = 1 << (dst_sig_bits - 1); + const dst_nan_mask = dst_qnan - 1; + + // Break a into a sign and representation of the absolute value + var a_rep = std.math.F80.fromFloat(a); + const sign = a_rep.exp & 0x8000; + a_rep.exp &= 0x7FFF; + a_rep.fraction &= 0x7FFFFFFFFFFFFFFF; + var abs_result: dst_rep_t = undefined; + + if (a_rep.exp -% underflow < a_rep.exp -% overflow) { + // The exponent of a is within the range of normal numbers in the + // destination format. We can convert by simply right-shifting with + // rounding and adjusting the exponent. + abs_result = @as(dst_rep_t, a_rep.exp) << dst_sig_bits; + abs_result |= @truncate(a_rep.fraction >> (src_sig_bits - dst_sig_bits)); + abs_result -%= @as(dst_rep_t, src_exp_bias - dst_exp_bias) << dst_sig_bits; + + const round_bits = a_rep.fraction & round_mask; + if (round_bits > halfway) { + // Round to nearest + abs_result += 1; + } else if (round_bits == halfway) { + // Ties to even + abs_result += abs_result & 1; + } + } else if (a_rep.exp == 0x7FFF and a_rep.fraction != 0) { + // a is NaN. + // Conjure the result by beginning with infinity, setting the qNaN + // bit and inserting the (truncated) trailing NaN field. + abs_result = @as(dst_rep_t, @intCast(dst_inf_exp)) << dst_sig_bits; + abs_result |= dst_qnan; + abs_result |= @intCast((a_rep.fraction >> (src_sig_bits - dst_sig_bits)) & dst_nan_mask); + } else if (a_rep.exp >= overflow) { + // a overflows to infinity. + abs_result = @as(dst_rep_t, @intCast(dst_inf_exp)) << dst_sig_bits; + } else { + // a underflows on conversion to the destination type or is an exact + // zero. The result may be a denormal or zero. Extract the exponent + // to get the shift amount for the denormalization. + const shift = src_exp_bias - dst_exp_bias - a_rep.exp; + + // Right shift by the denormalization amount with sticky. + if (shift > src_sig_bits) { + abs_result = 0; + } else { + const sticky = @intFromBool(a_rep.fraction << @intCast(shift) != 0); + const denormalized_significand = a_rep.fraction >> @intCast(shift) | sticky; + abs_result = @intCast(denormalized_significand >> (src_sig_bits - dst_sig_bits)); + const round_bits = denormalized_significand & round_mask; + if (round_bits > halfway) { + // Round to nearest + abs_result += 1; + } else if (round_bits == halfway) { + // Ties to even + abs_result += abs_result & 1; + } + } + } + + const result align(@alignOf(dst_t)) = abs_result | @as(dst_rep_t, sign) << dst_bits - 16; + return @bitCast(result); +} + +test { + _ = @import("truncf_test.zig"); +} diff --git a/build/compiler_rt/truncf_test.zig b/build/compiler_rt/truncf_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/truncsfhf2.zig b/build/compiler_rt/truncsfhf2.zig new file mode 100644 index 00000000..18d5854c --- /dev/null +++ b/build/compiler_rt/truncsfhf2.zig @@ -0,0 +1,25 @@ +const common = @import("./common.zig"); +const truncf = @import("./truncf.zig").truncf; + +pub const panic = common.panic; + +comptime { + if (common.gnu_f16_abi) { + @export(&__gnu_f2h_ieee, .{ .name = "__gnu_f2h_ieee", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_aeabi) { + @export(&__aeabi_f2h, .{ .name = "__aeabi_f2h", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__truncsfhf2, .{ .name = "__truncsfhf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __truncsfhf2(a: f32) callconv(.c) common.F16T(f32) { + return @bitCast(truncf(f16, f32, a)); +} + +fn __gnu_f2h_ieee(a: f32) callconv(.c) common.F16T(f32) { + return @bitCast(truncf(f16, f32, a)); +} + +fn __aeabi_f2h(a: f32) callconv(.{ .arm_aapcs = .{} }) u16 { + return @bitCast(truncf(f16, f32, a)); +} diff --git a/build/compiler_rt/trunctfdf2.zig b/build/compiler_rt/trunctfdf2.zig new file mode 100644 index 00000000..37b9227e --- /dev/null +++ b/build/compiler_rt/trunctfdf2.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const truncf = @import("./truncf.zig").truncf; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__trunctfdf2, .{ .name = "__trunckfdf2", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_qtod, .{ .name = "_Qp_qtod", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__trunctfdf2, .{ .name = "__trunctfdf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __trunctfdf2(a: f128) callconv(.c) f64 { + return truncf(f64, f128, a); +} + +fn _Qp_qtod(a: *const f128) callconv(.c) f64 { + return truncf(f64, f128, a.*); +} diff --git a/build/compiler_rt/trunctfhf2.zig b/build/compiler_rt/trunctfhf2.zig new file mode 100644 index 00000000..daf47761 --- /dev/null +++ b/build/compiler_rt/trunctfhf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const truncf = @import("./truncf.zig").truncf; + +pub const panic = common.panic; + +comptime { + @export(&__trunctfhf2, .{ .name = "__trunctfhf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __trunctfhf2(a: f128) callconv(.c) common.F16T(f128) { + return @bitCast(truncf(f16, f128, a)); +} diff --git a/build/compiler_rt/trunctfsf2.zig b/build/compiler_rt/trunctfsf2.zig new file mode 100644 index 00000000..e238e35f --- /dev/null +++ b/build/compiler_rt/trunctfsf2.zig @@ -0,0 +1,21 @@ +const common = @import("./common.zig"); +const truncf = @import("./truncf.zig").truncf; + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__trunctfsf2, .{ .name = "__trunckfsf2", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + @export(&_Qp_qtos, .{ .name = "_Qp_qtos", .linkage = common.linkage, .visibility = common.visibility }); + } + @export(&__trunctfsf2, .{ .name = "__trunctfsf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __trunctfsf2(a: f128) callconv(.c) f32 { + return truncf(f32, f128, a); +} + +fn _Qp_qtos(a: *const f128) callconv(.c) f32 { + return truncf(f32, f128, a.*); +} diff --git a/build/compiler_rt/trunctfxf2.zig b/build/compiler_rt/trunctfxf2.zig new file mode 100644 index 00000000..ddc97794 --- /dev/null +++ b/build/compiler_rt/trunctfxf2.zig @@ -0,0 +1,68 @@ +const math = @import("std").math; +const common = @import("./common.zig"); +const trunc_f80 = @import("./truncf.zig").trunc_f80; + +pub const panic = common.panic; + +comptime { + @export(&__trunctfxf2, .{ .name = "__trunctfxf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __trunctfxf2(a: f128) callconv(.c) f80 { + const src_sig_bits = math.floatMantissaBits(f128); + const dst_sig_bits = math.floatMantissaBits(f80) - 1; // -1 for the integer bit + + // Various constants whose values follow from the type parameters. + // Any reasonable optimizer will fold and propagate all of these. + const src_bits = @typeInfo(f128).float.bits; + const src_exp_bits = src_bits - src_sig_bits - 1; + const src_inf_exp = 0x7FFF; + + const src_inf = src_inf_exp << src_sig_bits; + const src_sign_mask = 1 << (src_sig_bits + src_exp_bits); + const src_abs_mask = src_sign_mask - 1; + const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1; + const halfway = 1 << (src_sig_bits - dst_sig_bits - 1); + + // Break a into a sign and representation of the absolute value + const a_rep = @as(u128, @bitCast(a)); + const a_abs = a_rep & src_abs_mask; + const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0; + const integer_bit = 1 << 63; + + var res: math.F80 = undefined; + + if (a_abs > src_inf) { + // a is NaN. + // Conjure the result by beginning with infinity, setting the qNaN + // bit and inserting the (truncated) trailing NaN field. + res.exp = 0x7fff; + res.fraction = 0x8000000000000000; + res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))); + } else { + // The exponent of a is within the range of normal numbers in the + // destination format. We can convert by simply right-shifting with + // rounding, adding the explicit integer bit, and adjusting the exponent + res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit; + res.exp = @truncate(a_abs >> src_sig_bits); + + const round_bits = a_abs & round_mask; + if (round_bits > halfway) { + // Round to nearest + const ov = @addWithOverflow(res.fraction, 1); + res.fraction = ov[0]; + res.exp += ov[1]; + res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry + } else if (round_bits == halfway) { + // Ties to even + const ov = @addWithOverflow(res.fraction, res.fraction & 1); + res.fraction = ov[0]; + res.exp += ov[1]; + res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry + } + if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals + } + + res.exp |= sign; + return res.toFloat(); +} diff --git a/build/compiler_rt/truncxfdf2.zig b/build/compiler_rt/truncxfdf2.zig new file mode 100644 index 00000000..f45a0796 --- /dev/null +++ b/build/compiler_rt/truncxfdf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const trunc_f80 = @import("./truncf.zig").trunc_f80; + +pub const panic = common.panic; + +comptime { + @export(&__truncxfdf2, .{ .name = "__truncxfdf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __truncxfdf2(a: f80) callconv(.c) f64 { + return trunc_f80(f64, a); +} diff --git a/build/compiler_rt/truncxfhf2.zig b/build/compiler_rt/truncxfhf2.zig new file mode 100644 index 00000000..34ee97c0 --- /dev/null +++ b/build/compiler_rt/truncxfhf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const trunc_f80 = @import("./truncf.zig").trunc_f80; + +pub const panic = common.panic; + +comptime { + @export(&__truncxfhf2, .{ .name = "__truncxfhf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __truncxfhf2(a: f80) callconv(.c) common.F16T(f80) { + return @bitCast(trunc_f80(f16, a)); +} diff --git a/build/compiler_rt/truncxfsf2.zig b/build/compiler_rt/truncxfsf2.zig new file mode 100644 index 00000000..136e941a --- /dev/null +++ b/build/compiler_rt/truncxfsf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const trunc_f80 = @import("./truncf.zig").trunc_f80; + +pub const panic = common.panic; + +comptime { + @export(&__truncxfsf2, .{ .name = "__truncxfsf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __truncxfsf2(a: f80) callconv(.c) f32 { + return trunc_f80(f32, a); +} diff --git a/build/compiler_rt/ucmpdi2_test.zig b/build/compiler_rt/ucmpdi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/ucmpsi2_test.zig b/build/compiler_rt/ucmpsi2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/ucmpti2_test.zig b/build/compiler_rt/ucmpti2_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/udivmod.zig b/build/compiler_rt/udivmod.zig new file mode 100644 index 00000000..bf6aaade --- /dev/null +++ b/build/compiler_rt/udivmod.zig @@ -0,0 +1,149 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const Log2Int = std.math.Log2Int; +const common = @import("common.zig"); +const HalveInt = common.HalveInt; + +const lo = switch (builtin.cpu.arch.endian()) { + .big => 1, + .little => 0, +}; +const hi = 1 - lo; + +// Let _u1 and _u0 be the high and low limbs of U respectively. +// Returns U / v_ and sets r = U % v_. +fn divwide_generic(comptime T: type, _u1: T, _u0: T, v_: T, r: *T) T { + const HalfT = HalveInt(T, false).HalfT; + @setRuntimeSafety(common.test_safety); + var v = v_; + + const b = @as(T, 1) << (@bitSizeOf(T) / 2); + var un64: T = undefined; + var un10: T = undefined; + + const s: Log2Int(T) = @intCast(@clz(v)); + if (s > 0) { + // Normalize divisor + v <<= s; + un64 = (_u1 << s) | (_u0 >> @intCast((@bitSizeOf(T) - @as(T, @intCast(s))))); + un10 = _u0 << s; + } else { + // Avoid undefined behavior of (u0 >> @bitSizeOf(T)) + un64 = _u1; + un10 = _u0; + } + + // Break divisor up into two 32-bit digits + const vn1 = v >> (@bitSizeOf(T) / 2); + const vn0 = v & std.math.maxInt(HalfT); + + // Break right half of dividend into two digits + const un1 = un10 >> (@bitSizeOf(T) / 2); + const un0 = un10 & std.math.maxInt(HalfT); + + // Compute the first quotient digit, q1 + var q1 = un64 / vn1; + var rhat = un64 -% q1 *% vn1; + + // q1 has at most error 2. No more than 2 iterations + while (q1 >= b or q1 * vn0 > b * rhat + un1) { + q1 -= 1; + rhat += vn1; + if (rhat >= b) break; + } + + const un21 = un64 *% b +% un1 -% q1 *% v; + + // Compute the second quotient digit + var q0 = un21 / vn1; + rhat = un21 -% q0 *% vn1; + + // q0 has at most error 2. No more than 2 iterations. + while (q0 >= b or q0 * vn0 > b * rhat + un0) { + q0 -= 1; + rhat += vn1; + if (rhat >= b) break; + } + + r.* = (un21 *% b +% un0 -% q0 *% v) >> s; + return q1 *% b +% q0; +} + +fn divwide(comptime T: type, _u1: T, _u0: T, v: T, r: *T) T { + @setRuntimeSafety(common.test_safety); + if (T == u64 and builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag != .windows) { + var rem: T = undefined; + const quo = asm ( + \\divq %[v] + : [_] "={rax}" (-> T), + [_] "={rdx}" (rem), + : [v] "r" (v), + [_] "{rax}" (_u0), + [_] "{rdx}" (_u1), + ); + r.* = rem; + return quo; + } else { + return divwide_generic(T, _u1, _u0, v, r); + } +} + +// Returns a_ / b_ and sets maybe_rem = a_ % b. +pub fn udivmod(comptime T: type, a_: T, b_: T, maybe_rem: ?*T) T { + @setRuntimeSafety(common.test_safety); + const HalfT = HalveInt(T, false).HalfT; + const SignedT = std.meta.Int(.signed, @bitSizeOf(T)); + + if (b_ > a_) { + if (maybe_rem) |rem| { + rem.* = a_; + } + return 0; + } + + const a: [2]HalfT = @bitCast(a_); + const b: [2]HalfT = @bitCast(b_); + var q: [2]HalfT = undefined; + var r: [2]HalfT = undefined; + + // When the divisor fits in 64 bits, we can use an optimized path + if (b[hi] == 0) { + r[hi] = 0; + if (a[hi] < b[lo]) { + // The result fits in 64 bits + q[hi] = 0; + q[lo] = divwide(HalfT, a[hi], a[lo], b[lo], &r[lo]); + } else { + // First, divide with the high part to get the remainder. After that a_hi < b_lo. + q[hi] = a[hi] / b[lo]; + q[lo] = divwide(HalfT, a[hi] % b[lo], a[lo], b[lo], &r[lo]); + } + if (maybe_rem) |rem| { + rem.* = @bitCast(r); + } + return @bitCast(q); + } + + // 0 <= shift <= 63 + const shift: Log2Int(T) = @clz(b[hi]) - @clz(a[hi]); + var af: T = @bitCast(a); + var bf = @as(T, @bitCast(b)) << shift; + q = @bitCast(@as(T, 0)); + + for (0..shift + 1) |_| { + q[lo] <<= 1; + // Branchless version of: + // if (af >= bf) { + // af -= bf; + // q[lo] |= 1; + // } + const s = @as(SignedT, @bitCast(bf -% af -% 1)) >> (@bitSizeOf(T) - 1); + q[lo] |= @intCast(s & 1); + af -= bf & @as(T, @bitCast(s)); + bf >>= 1; + } + if (maybe_rem) |rem| { + rem.* = @bitCast(af); + } + return @bitCast(q); +} diff --git a/build/compiler_rt/udivmoddi4_test.zig b/build/compiler_rt/udivmoddi4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/udivmodei4.zig b/build/compiler_rt/udivmodei4.zig new file mode 100644 index 00000000..0923f3f2 --- /dev/null +++ b/build/compiler_rt/udivmodei4.zig @@ -0,0 +1,149 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const common = @import("common.zig"); +const shr = std.math.shr; +const shl = std.math.shl; + +const max_limbs = std.math.divCeil(usize, 65535, 32) catch unreachable; // max supported type is u65535 + +comptime { + @export(&__udivei4, .{ .name = "__udivei4", .linkage = common.linkage, .visibility = common.visibility }); + @export(&__umodei4, .{ .name = "__umodei4", .linkage = common.linkage, .visibility = common.visibility }); +} + +const endian = builtin.cpu.arch.endian(); + +/// Get the value of a limb. +inline fn limb(x: []const u32, i: usize) u32 { + return if (endian == .little) x[i] else x[x.len - 1 - i]; +} + +/// Change the value of a limb. +inline fn limb_set(x: []u32, i: usize, v: u32) void { + if (endian == .little) { + x[i] = v; + } else { + x[x.len - 1 - i] = v; + } +} + +/// Uses Knuth's Algorithm D, 4.3.1, p. 272. +pub fn divmod(q: ?[]u32, r: ?[]u32, u: []const u32, v: []const u32) !void { + if (q) |q_| @memset(q_[0..], 0); + if (r) |r_| @memset(r_[0..], 0); + + if (u.len == 0 or v.len == 0) return error.DivisionByZero; + + var m = u.len - 1; + var n = v.len - 1; + while (limb(u, m) == 0) : (m -= 1) { + if (m == 0) return; + } + while (limb(v, n) == 0) : (n -= 1) { + if (n == 0) return error.DivisionByZero; + } + + if (n > m) { + if (r) |r_| @memcpy(r_[0..u.len], u); + return; + } + + const s = @clz(limb(v, n)); + + var vn: [max_limbs]u32 = undefined; + var i = n; + while (i > 0) : (i -= 1) { + limb_set(&vn, i, shl(u32, limb(v, i), s) | shr(u32, limb(v, i - 1), 32 - s)); + } + limb_set(&vn, 0, shl(u32, limb(v, 0), s)); + + var un: [max_limbs + 1]u32 = undefined; + limb_set(&un, m + 1, shr(u32, limb(u, m), 32 - s)); + i = m; + while (i > 0) : (i -= 1) { + limb_set(&un, i, shl(u32, limb(u, i), s) | shr(u32, limb(u, i - 1), 32 - s)); + } + limb_set(&un, 0, shl(u32, limb(u, 0), s)); + + var j = m - n; + while (true) : (j -= 1) { + const uu = (@as(u64, limb(&un, j + n + 1)) << 32) + limb(&un, j + n); + var qhat = uu / limb(&vn, n); + var rhat = uu % limb(&vn, n); + + while (true) { + if (qhat >= (1 << 32) or (n > 0 and qhat * limb(&vn, n - 1) > (rhat << 32) + limb(&un, j + n - 1))) { + qhat -= 1; + rhat += limb(&vn, n); + if (rhat < (1 << 32)) continue; + } + break; + } + var carry: i64 = 0; + i = 0; + while (i <= n) : (i += 1) { + const p = qhat * limb(&vn, i); + const t = limb(&un, i + j) - carry - @as(u32, @truncate(p)); + limb_set(&un, i + j, @as(u32, @truncate(@as(u64, @bitCast(t))))); + carry = @as(i64, @intCast(p >> 32)) - @as(i64, @intCast(t >> 32)); + } + const t = limb(&un, j + n + 1) -% carry; + limb_set(&un, j + n + 1, @as(u32, @truncate(@as(u64, @bitCast(t))))); + if (q) |q_| limb_set(q_, j, @as(u32, @truncate(qhat))); + if (t < 0) { + if (q) |q_| limb_set(q_, j, limb(q_, j) - 1); + var carry2: u64 = 0; + i = 0; + while (i <= n) : (i += 1) { + const t2 = @as(u64, limb(&un, i + j)) + @as(u64, limb(&vn, i)) + carry2; + limb_set(&un, i + j, @as(u32, @truncate(t2))); + carry2 = t2 >> 32; + } + limb_set(&un, j + n + 1, @as(u32, @truncate(limb(&un, j + n + 1) + carry2))); + } + if (j == 0) break; + } + if (r) |r_| { + i = 0; + while (i <= n) : (i += 1) { + limb_set(r_, i, shr(u32, limb(&un, i), s) | shl(u32, limb(&un, i + 1), 32 - s)); + } + limb_set(r_, n, shr(u32, limb(&un, n), s)); + } +} + +pub fn __udivei4(q_p: [*]u8, u_p: [*]const u8, v_p: [*]const u8, bits: usize) callconv(.c) void { + @setRuntimeSafety(common.test_safety); + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + const q: []u32 = @ptrCast(@alignCast(q_p[0..byte_size])); + const u: []const u32 = @ptrCast(@alignCast(u_p[0..byte_size])); + const v: []const u32 = @ptrCast(@alignCast(v_p[0..byte_size])); + @call(.always_inline, divmod, .{ q, null, u, v }) catch unreachable; +} + +pub fn __umodei4(r_p: [*]u8, u_p: [*]const u8, v_p: [*]const u8, bits: usize) callconv(.c) void { + @setRuntimeSafety(common.test_safety); + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + const r: []u32 = @ptrCast(@alignCast(r_p[0..byte_size])); + const u: []const u32 = @ptrCast(@alignCast(u_p[0..byte_size])); + const v: []const u32 = @ptrCast(@alignCast(v_p[0..byte_size])); + @call(.always_inline, divmod, .{ null, r, u, v }) catch unreachable; +} + +test "__udivei4/__umodei4" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + const RndGen = std.Random.DefaultPrng; + var rnd = RndGen.init(42); + var i: usize = 10000; + while (i > 0) : (i -= 1) { + const u = rnd.random().int(u1000); + const v = 1 + rnd.random().int(u1200); + const q = u / v; + const r = u % v; + const z = q * v + r; + try std.testing.expect(z == u); + } +} diff --git a/build/compiler_rt/udivmodsi4_test.zig b/build/compiler_rt/udivmodsi4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/udivmodti4.zig b/build/compiler_rt/udivmodti4.zig new file mode 100644 index 00000000..9e9585c6 --- /dev/null +++ b/build/compiler_rt/udivmodti4.zig @@ -0,0 +1,28 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const udivmod = @import("udivmod.zig").udivmod; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__udivmodti4, .{ .name = "__udivmodti4", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) callconv(.c) u128 { + return udivmod(u128, a, b, maybe_rem); +} + +const v2u64 = @Vector(2, u64); + +fn __udivmodti4_windows_x86_64(a: v2u64, b: v2u64, maybe_rem: ?*u128) callconv(.c) v2u64 { + return @bitCast(udivmod(u128, @bitCast(a), @bitCast(b), maybe_rem)); +} + +test { + _ = @import("udivmodti4_test.zig"); +} diff --git a/build/compiler_rt/udivmodti4_test.zig b/build/compiler_rt/udivmodti4_test.zig new file mode 100644 index 00000000..e69de29b diff --git a/build/compiler_rt/udivti3.zig b/build/compiler_rt/udivti3.zig new file mode 100644 index 00000000..8423c1df --- /dev/null +++ b/build/compiler_rt/udivti3.zig @@ -0,0 +1,24 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const udivmod = @import("udivmod.zig").udivmod; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__udivti3, .{ .name = "__udivti3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __udivti3(a: u128, b: u128) callconv(.c) u128 { + return udivmod(u128, a, b, null); +} + +const v2u64 = @Vector(2, u64); + +fn __udivti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.c) v2u64 { + return @bitCast(udivmod(u128, @bitCast(a), @bitCast(b), null)); +} diff --git a/build/compiler_rt/umodti3.zig b/build/compiler_rt/umodti3.zig new file mode 100644 index 00000000..592bc443 --- /dev/null +++ b/build/compiler_rt/umodti3.zig @@ -0,0 +1,28 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const udivmod = @import("udivmod.zig").udivmod; +const common = @import("common.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_windows_v2u64_abi) { + @export(&__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__umodti3, .{ .name = "__umodti3", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __umodti3(a: u128, b: u128) callconv(.c) u128 { + var r: u128 = undefined; + _ = udivmod(u128, a, b, &r); + return r; +} + +const v2u64 = @Vector(2, u64); + +fn __umodti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.c) v2u64 { + var r: u128 = undefined; + _ = udivmod(u128, @bitCast(a), @bitCast(b), &r); + return @bitCast(r); +} diff --git a/build/compiler_rt/unorddf2.zig b/build/compiler_rt/unorddf2.zig new file mode 100644 index 00000000..dcc8762c --- /dev/null +++ b/build/compiler_rt/unorddf2.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_dcmpun, .{ .name = "__aeabi_dcmpun", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__unorddf2, .{ .name = "__unorddf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __unorddf2(a: f64, b: f64) callconv(.c) i32 { + return comparef.unordcmp(f64, a, b); +} + +fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return comparef.unordcmp(f64, a, b); +} diff --git a/build/compiler_rt/unordhf2.zig b/build/compiler_rt/unordhf2.zig new file mode 100644 index 00000000..2c2edad8 --- /dev/null +++ b/build/compiler_rt/unordhf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__unordhf2, .{ .name = "__unordhf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __unordhf2(a: f16, b: f16) callconv(.c) i32 { + return comparef.unordcmp(f16, a, b); +} diff --git a/build/compiler_rt/unordsf2.zig b/build/compiler_rt/unordsf2.zig new file mode 100644 index 00000000..a403fa4f --- /dev/null +++ b/build/compiler_rt/unordsf2.zig @@ -0,0 +1,20 @@ +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_aeabi) { + @export(&__aeabi_fcmpun, .{ .name = "__aeabi_fcmpun", .linkage = common.linkage, .visibility = common.visibility }); + } else { + @export(&__unordsf2, .{ .name = "__unordsf2", .linkage = common.linkage, .visibility = common.visibility }); + } +} + +pub fn __unordsf2(a: f32, b: f32) callconv(.c) i32 { + return comparef.unordcmp(f32, a, b); +} + +fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return comparef.unordcmp(f32, a, b); +} diff --git a/build/compiler_rt/unordtf2.zig b/build/compiler_rt/unordtf2.zig new file mode 100644 index 00000000..618f1482 --- /dev/null +++ b/build/compiler_rt/unordtf2.zig @@ -0,0 +1,18 @@ +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + if (common.want_ppc_abi) { + @export(&__unordtf2, .{ .name = "__unordkf2", .linkage = common.linkage, .visibility = common.visibility }); + } else if (common.want_sparc_abi) { + // These exports are handled in cmptf2.zig because unordered comparisons + // are based on calling _Qp_cmp. + } + @export(&__unordtf2, .{ .name = "__unordtf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +fn __unordtf2(a: f128, b: f128) callconv(.c) i32 { + return comparef.unordcmp(f128, a, b); +} diff --git a/build/compiler_rt/unordxf2.zig b/build/compiler_rt/unordxf2.zig new file mode 100644 index 00000000..97a4f8d0 --- /dev/null +++ b/build/compiler_rt/unordxf2.zig @@ -0,0 +1,12 @@ +const common = @import("./common.zig"); +const comparef = @import("./comparef.zig"); + +pub const panic = common.panic; + +comptime { + @export(&__unordxf2, .{ .name = "__unordxf2", .linkage = common.linkage, .visibility = common.visibility }); +} + +pub fn __unordxf2(a: f80, b: f80) callconv(.c) i32 { + return comparef.unordcmp(f80, a, b); +} diff --git a/src/afl.c b/src/afl.c new file mode 100644 index 00000000..1f291053 --- /dev/null +++ b/src/afl.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include +#include + +/* Main entry point. */ + +/* To ensure checks are not optimized out it is recommended to disable + code optimization for the fuzzer harness main() */ +#pragma clang optimize off +#pragma GCC optimize("O0") + + +// Zig integration +void zig_fuzz_init(); +void zig_fuzz_test(unsigned char *, ssize_t); + + +// bug in compilation causes init func to never get called +// TODO: remove this once bug is fixed +uint32_t __start___sancov_guards; +uint32_t __stop___sancov_guards; +void __sanitizer_cov_trace_pc_guard_init(uint32_t*, uint32_t*); + + + +// Symbols not defined by afl-compiler-rt +__attribute__((visibility("default"))) __attribute__((tls_model("initial-exec"))) _Thread_local uintptr_t __sancov_lowest_stack; + +void __sanitizer_cov_trace_pc_indir () {} +void __sanitizer_cov_8bit_counters_init () {} +void __sanitizer_cov_pcs_init () {} + +//__AFL_FUZZ_INIT() +int __afl_sharedmem_fuzzing = 1; +extern __attribute__((visibility("default"))) unsigned int *__afl_fuzz_len; +extern __attribute__((visibility("default"))) unsigned char *__afl_fuzz_ptr; +unsigned char __afl_fuzz_alt[1048576]; +unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt; + +int main(int argc, char **argv) { + __sanitizer_cov_trace_pc_guard_init(&__start___sancov_guards, &__stop___sancov_guards); + + // __AFL_INIT(); + static volatile const char *_A __attribute__((used,unused)); + _A = (const char*)"##SIG_AFL_DEFER_FORKSRV##"; +#ifdef __APPLE__ + __attribute__((visibility("default"))) + void _I(void) __asm__("___afl_manual_init"); +#else + __attribute__((visibility("default"))) + void _I(void) __asm__("__afl_manual_init"); +#endif + _I(); + + + zig_fuzz_init(); + + // unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; + unsigned char *buf = __afl_fuzz_ptr ? __afl_fuzz_ptr : __afl_fuzz_alt_ptr; + + // while (__AFL_LOOP(UINT_MAX)) { + while (({ static volatile const char *_B __attribute__((used,unused)); _B = (const char*)"##SIG_AFL_PERSISTENT##"; extern __attribute__((visibility("default"))) int __afl_connected; + #ifdef __APPLE__ + __attribute__((visibility("default"))) int _L(unsigned int) __asm__("___afl_persistent_loop"); + #else + __attribute__((visibility("default"))) int _L(unsigned int) __asm__("__afl_persistent_loop"); + #endif + _L(__afl_connected ? UINT_MAX : 1); })) { + + // int len = __AFL_FUZZ_TESTCASE_LEN; + int len = __afl_fuzz_ptr ? *__afl_fuzz_len : + (*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1048576)) == 0xffffffff ? 0 : + *__afl_fuzz_len; + + + zig_fuzz_test(buf, len); + } + + return 0; +} diff --git a/src/behavior.zig b/src/behavior.zig index c4490ce2..67b02cab 100644 --- a/src/behavior.zig +++ b/src/behavior.zig @@ -3,6 +3,7 @@ const Runner = @import("Runner.zig"); const io = @import("io.zig"); const Parser = @import("Parser.zig"); const BuildOptions = @import("build_options"); +const clap = @import("clap"); // Because of https://github.com/ziglang/zig/issues/15091 test that write to stdout will hang // However I think its completely legitimate for a tested code to output to stdout and I @@ -10,73 +11,99 @@ const BuildOptions = @import("build_options"); const black_listed_tests = std.StaticStringMap(void).initComptime( .{ - .{ "tests/027-run-file.buzz", {} }, + .{ "tests/behavior/027-run-file.buzz", {} }, }, ); const Result = struct { - total: usize, - failed: usize, - skipped: usize, + total: usize = 0, + failed: std.ArrayList([]const u8) = .empty, + skipped: usize = 0, + hanged: std.ArrayList([]const u8) = .empty, + + pub fn hasFailed(self: *@This()) bool { + return self.failed.items.len > 0 or self.hanged.items.len > 0; + } + + pub fn merge(self: *@This(), allocator: std.mem.Allocator, other: *@This()) error{OutOfMemory}!void { + self.total += other.total; + self.skipped += other.skipped; + + try self.failed.appendSlice(allocator, other.failed.items); + try self.hanged.appendSlice(allocator, other.hanged.items); + } + + pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void { + for (self.failed.items) |f| { + allocator.free(f); + } + + for (self.hanged.items) |f| { + allocator.free(f); + } + + self.failed.deinit(allocator); + self.hanged.deinit(allocator); + } }; -fn testBehaviors(allocator: std.mem.Allocator) !Result { - var count: usize = 0; - var fail_count: usize = 0; - var skipped: usize = 0; +fn testBehaviors(allocator: std.mem.Allocator, fail_fast: bool) !Result { + var result = Result{}; - var test_dir = try std.fs.cwd().openDir( - "tests", - .{ - .iterate = true, - }, - ); - var it = test_dir.iterate(); + const dirs = [_][]const u8{ "tests/behavior", "tests" }; - while (try it.next()) |file| : (count += 1) { - if (file.kind == .file and std.mem.endsWith(u8, file.name, ".buzz")) { - const file_name = try allocator.alloc(u8, 6 + file.name.len); - _ = try std.fmt.bufPrint(file_name, "tests/{s}", .{file.name}); - defer allocator.free(file_name); + for (dirs) |dir| { + var test_dir = try std.fs.cwd().openDir( + dir, + .{ + .iterate = true, + }, + ); + var it = test_dir.iterate(); - if (black_listed_tests.has(file_name)) { - skipped += 1; - io.print("\u{001b}[33m[{s} >>]\u{001b}[0m\n", .{file_name}); - continue; - } + while (try it.next()) |file| : (result.total += 1) { + if (file.kind == .file and std.mem.endsWith(u8, file.name, ".buzz")) { + var file_name = std.Io.Writer.Allocating.init(allocator); + defer file_name.deinit(); + try file_name.writer.print( + "{s}/{s}", + .{ + dir, + file.name, + }, + ); + + if (black_listed_tests.has(file_name.written())) { + result.skipped += 1; + continue; + } - io.print("\u{001b}[33m[{s} ...]\u{001b}[0m\n", .{file_name}); + // io.print("\u{001b}[33m[{s} ...]\u{001b}[0m\n", .{file_name.written()}); - var had_error: bool = false; - var runner: Runner = undefined; - try runner.init(allocator, .Test, null); + var had_error: bool = false; + var runner: Runner = undefined; + try runner.init(allocator, .Test, null); - runner.runFile( - file_name, - &[_][:0]u8{}, - ) catch { - io.print("\u{001b}[31m[{s} ✕]\u{001b}[0m\n", .{file.name}); - had_error = true; - fail_count += 1; - }; + runner.runFile( + file_name.written(), + &[_][:0]u8{}, + ) catch { + had_error = true; + try result.failed.append(allocator, try file_name.toOwnedSlice()); - if (!had_error) { - io.print("\u{001b}[32m[{s} ✓]\u{001b}[0m\n", .{file.name}); + if (fail_fast) { + break; + } + }; } } } - return .{ - .total = count, - .failed = fail_count, - .skipped = skipped, - }; + return result; } -fn testCompileErrors(allocator: std.mem.Allocator) !Result { - var count: usize = 0; - var fail_count: usize = 0; - var skipped: usize = 0; +fn testCompileErrors(allocator: std.mem.Allocator, fail_fast: bool) !Result { + var result = Result{}; var test_dir = try std.fs.cwd().openDir( "tests/compile_errors", @@ -86,21 +113,20 @@ fn testCompileErrors(allocator: std.mem.Allocator) !Result { ); var it = test_dir.iterate(); - while (try it.next()) |file| : (count += 1) { + while (try it.next()) |file| : (result.total += 1) { if (file.kind == .file and std.mem.endsWith(u8, file.name, ".buzz")) { - const file_name: []u8 = try allocator.alloc(u8, 21 + file.name.len); - defer allocator.free(file_name); - _ = try std.fmt.bufPrint(file_name, "tests/compile_errors/{s}", .{file.name}); + var file_name = std.Io.Writer.Allocating.init(allocator); + defer file_name.deinit(); + try file_name.writer.print("tests/compile_errors/{s}", .{file.name}); - if (black_listed_tests.has(file_name)) { - skipped += 1; - io.print("\u{001b}[33m[{s} >>]\u{001b}[0m\n", .{file.name}); + if (black_listed_tests.has(file_name.written())) { + result.skipped += 1; continue; } // First line of test file is expected error message const test_file = try std.fs.cwd().openFile( - file_name, + file_name.written(), .{ .mode = .read_only, }, @@ -127,39 +153,179 @@ fn testCompileErrors(allocator: std.mem.Allocator) !Result { ) catch unreachable; defer allocator.free(arg0); - const result = try std.process.Child.run( + const run_result = try std.process.Child.run( .{ .allocator = allocator, .argv = &.{ arg0, "-t", - file_name, + file_name.written(), }, }, ); - if (!std.mem.containsAtLeast(u8, result.stderr, 1, first_line[2..])) { - fail_count += 1; - io.print( - "Expected error `{s}` got `{s}`\n", + if (!std.mem.containsAtLeast(u8, run_result.stderr, 1, first_line[2..])) { + // io.print( + // "Expected error `{s}` got `{s}`\n", + // .{ + // first_line[2..], + // run_result.stderr, + // }, + // ); + + try result.failed.append(allocator, try file_name.toOwnedSlice()); + + if (fail_fast) { + break; + } + } + } + } + + return result; +} + +// FIXME: should run files in dist/default/hangs with a timeout +// is the only solution for to spawn the process in a thread? seems like we can't wait for spawned process with a timeout +fn testFuzzCrashes(allocator: std.mem.Allocator, fail_fast: bool) !Result { + var result = Result{}; + + // Get resolved tests + var resolved = std.StringArrayHashMapUnmanaged(void).empty; + + var resolved_file = try std.fs.cwd().createFile( + "dist/resolved.txt", + .{ + .truncate = false, + .read = true, + }, + ); + + const raw = try allocator.alloc(u8, (try resolved_file.stat()).size); + defer allocator.free(raw); + + _ = try resolved_file.readAll(raw); + + { + var it = std.mem.splitAny(u8, raw, "\n"); + while (it.next()) |r| { + try resolved.put(allocator, r, {}); + } + } + + resolved_file.close(); + + // Re open in to write new resolved tests + resolved_file = try std.fs.cwd().openFile( + "dist/resolved.txt", + .{ .mode = .write_only }, + ); + defer resolved_file.close(); + try resolved_file.seekFromEnd(0); + + var resolved_writer = resolved_file.writer(&.{}); + + for ([_][]const u8{ + "dist/default/crashes", + "dist/default/hangs", + }) |dir| { + var test_dir = try std.fs.cwd().openDir( + dir, + .{ + .iterate = true, + }, + ); + var it = test_dir.iterate(); + + while (try it.next()) |file| : (result.total += 1) { + if (file.kind == .file) { + // Was it resolved? + if (resolved.get(file.name) != null) { + continue; + } + + var file_name = std.Io.Writer.Allocating.init(allocator); + defer file_name.deinit(); + try file_name.writer.print("{s}/{s}", .{ dir, file.name }); + + if (black_listed_tests.has(file_name.written())) { + result.skipped += 1; + continue; + } + + const arg0 = std.fmt.allocPrint( + allocator, + "{s}/bin/buzz", + .{ + try Parser.buzzPrefix(allocator), + }, + ) catch unreachable; + defer allocator.free(arg0); + + var child = std.process.Child.init( + &.{ + arg0, + "-t", + file_name.written(), + }, + allocator, + ); + + try child.spawn(); + + // Run in a thread so we can abort hanging tests + var done = false; + const thread = try std.Thread.spawn( + .{ + .allocator = allocator, + }, + struct { + fn wait(process: *std.process.Child, over: *bool) void { + _ = process.wait() catch @panic("Could not wait for buzz process"); + + over.* = true; + } + }.wait, .{ - first_line[2..], - result.stderr, + &child, + &done, }, ); - io.print("\u{001b}[31m[{s}... ✕]\u{001b}[0m\n", .{file.name}); - } else { - io.print("\u{001b}[32m[{s}... ✓]\u{001b}[0m\n", .{file.name}); + var timer = try std.time.Timer.start(); + while (!done and timer.read() < 2 * std.time.ns_per_s) {} + + if (child.term) |term| { + thread.join(); + + const uterm = term catch null; + if (uterm == null or uterm.? != .Exited) { + try result.failed.append(allocator, try file_name.toOwnedSlice()); + + if (fail_fast) { + break; + } + } else { + try resolved_writer.interface.print("{s}\n", .{file.name}); + try resolved_writer.interface.flush(); + } + } else { + try result.hanged.append(allocator, try file_name.toOwnedSlice()); + std.posix.kill(child.id, std.posix.SIG.TERM) catch {}; + // FIXME: Not sure i understands this but it seems that child.kill() kills the process and then wait for the now + // non existing process? + // _ = child.kill() catch {}; + thread.join(); + + if (fail_fast) { + break; + } + } } } } - return .{ - .total = count, - .failed = fail_count, - .skipped = skipped, - }; + return result; } pub fn main() !u8 { @@ -172,30 +338,114 @@ pub fn main() !u8 { @import("mimalloc.zig").mim_allocator else std.heap.c_allocator; - var count: usize = 0; - var fail_count: usize = 0; - var skipped: usize = 0; - const behaviors_result = try testBehaviors(allocator); - const comp_result = try testCompileErrors(allocator); + const params = comptime clap.parseParamsComptime( + \\-h, --help Show help and exit + \\-a, --all Run all tests + \\-b, --behavior Run behavior tests + \\-c, --compile-error Run compile error tests + \\-f, --fuzz Run fuzz tests + \\--fast Fail fast + \\ + ); - count += comp_result.total + behaviors_result.total; - fail_count += comp_result.failed + behaviors_result.failed; - skipped += comp_result.skipped + behaviors_result.skipped; + var diag = clap.Diagnostic{}; + var res = clap.parse( + clap.Help, + ¶ms, + clap.parsers.default, + .{ + .allocator = allocator, + .diagnostic = &diag, + }, + ) catch |err| { + // Report useful error and exit + diag.report(io.stderrWriter, err) catch {}; + return 1; + }; + defer res.deinit(); + + if (res.args.help == 1) { + io.print("👨â€ðŸš€ Behavior tests for the buzz programming language\n\nUsage: buzz_behavior ", .{}); + + clap.usage( + io.stderrWriter, + clap.Help, + ¶ms, + ) catch return 1; + + io.print("\n\n", .{}); + + clap.help( + io.stderrWriter, + clap.Help, + ¶ms, + .{ + .description_on_new_line = false, + .description_indent = 4, + .spacing_between_parameters = 0, + }, + ) catch return 1; + + return 0; + } + + var result: Result = .{}; + defer result.deinit(allocator); + + const do_all = res.args.all == 1 or (res.args.behavior != 1 and res.args.@"compile-error" != 1 and res.args.fuzz != 1); + + if (do_all or res.args.behavior == 1) { + var tests_result = try testBehaviors(allocator, res.args.fast == 1); + try result.merge( + allocator, + &tests_result, + ); + } - if (fail_count == 0) { + if (do_all or res.args.@"compile-error" == 1) { + var tests_result = try testCompileErrors(allocator, res.args.fast == 1); + try result.merge( + allocator, + &tests_result, + ); + } + + if (do_all or res.args.fuzz == 1) { + var tests_result = try testFuzzCrashes(allocator, res.args.fast == 1); + try result.merge( + allocator, + &tests_result, + ); + } + + if (result.failed.items.len > 0) { + io.print("Failed tests:\n", .{}); + for (result.failed.items) |failed| { + io.print(" \u{001b}[31m{s}]\u{001b}[0m\n", .{failed}); + } + } + + if (result.hanged.items.len > 0) { + io.print("Hanged tests:\n", .{}); + for (result.hanged.items) |hanged| { + io.print(" \u{001b}[31m{s}]\u{001b}[0m\n", .{hanged}); + } + } + + if (result.hasFailed()) { io.print("\n\u{001b}[32m", .{}); } else { io.print("\n\u{001b}[31m", .{}); } - io.print("Ran {}, Failed: {}, Skipped {}\u{001b}[0m\n", .{ - count, - fail_count, - skipped, + io.print("Ran {}, Ok: {}, Failed: {}, Hanged {}, Skipped {}\u{001b}[0m\n", .{ + result.total, + result.total - result.failed.items.len - result.hanged.items.len, + result.failed.items.len, + result.hanged.items.len, + result.skipped, }); - try std.testing.expect(fail_count == 0); - - return if (fail_count > 0) 1 else 0; + return if (result.hasFailed()) 1 else 0; } diff --git a/src/fuzz.zig b/src/fuzz.zig new file mode 100644 index 00000000..e0a7103e --- /dev/null +++ b/src/fuzz.zig @@ -0,0 +1,22 @@ +const std = @import("std"); +const Runner = @import("Runner.zig"); + +export fn zig_fuzz_init() callconv(.c) void {} + +export fn zig_fuzz_test(buf: [*]u8, len: isize) callconv(.c) void { + var gpa: std.heap.GeneralPurposeAllocator(.{}) = .{}; + const allocator = gpa.allocator(); + + const src = buf[0..@intCast(len)]; + + var runner: Runner = undefined; + runner.init(allocator, .Test, null) catch @panic("Could not initialize runner"); + defer runner.deinit(); + + _ = runner.runSource( + src, + "fuzz", + ) catch { + // TODO: is there some catchable errors we would like AFL to consider as a crash? + }; +} diff --git a/tests/001-basic-types.buzz b/tests/behavior/001-basic-types.buzz similarity index 100% rename from tests/001-basic-types.buzz rename to tests/behavior/001-basic-types.buzz diff --git a/tests/002-operators.buzz b/tests/behavior/002-operators.buzz similarity index 100% rename from tests/002-operators.buzz rename to tests/behavior/002-operators.buzz diff --git a/tests/003-control-flow.buzz b/tests/behavior/003-control-flow.buzz similarity index 100% rename from tests/003-control-flow.buzz rename to tests/behavior/003-control-flow.buzz diff --git a/tests/004-lists.buzz b/tests/behavior/004-lists.buzz similarity index 100% rename from tests/004-lists.buzz rename to tests/behavior/004-lists.buzz diff --git a/tests/005-maps.buzz b/tests/behavior/005-maps.buzz similarity index 100% rename from tests/005-maps.buzz rename to tests/behavior/005-maps.buzz diff --git a/tests/006-enums.buzz b/tests/behavior/006-enums.buzz similarity index 100% rename from tests/006-enums.buzz rename to tests/behavior/006-enums.buzz diff --git a/tests/007-objects.buzz b/tests/behavior/007-objects.buzz similarity index 100% rename from tests/007-objects.buzz rename to tests/behavior/007-objects.buzz diff --git a/tests/008-inline-catch.buzz b/tests/behavior/008-inline-catch.buzz similarity index 100% rename from tests/008-inline-catch.buzz rename to tests/behavior/008-inline-catch.buzz diff --git a/tests/009-gc.buzz b/tests/behavior/009-gc.buzz similarity index 100% rename from tests/009-gc.buzz rename to tests/behavior/009-gc.buzz diff --git a/tests/010-placeholder-cycle.buzz b/tests/behavior/010-placeholder-cycle.buzz similarity index 100% rename from tests/010-placeholder-cycle.buzz rename to tests/behavior/010-placeholder-cycle.buzz diff --git a/tests/011-list-map-properties.buzz b/tests/behavior/011-list-map-properties.buzz similarity index 100% rename from tests/011-list-map-properties.buzz rename to tests/behavior/011-list-map-properties.buzz diff --git a/tests/012-lambda.buzz b/tests/behavior/012-lambda.buzz similarity index 100% rename from tests/012-lambda.buzz rename to tests/behavior/012-lambda.buzz diff --git a/tests/013-import-export.buzz b/tests/behavior/013-import-export.buzz similarity index 100% rename from tests/013-import-export.buzz rename to tests/behavior/013-import-export.buzz diff --git a/tests/014-import-lib.buzz b/tests/behavior/014-import-lib.buzz similarity index 100% rename from tests/014-import-lib.buzz rename to tests/behavior/014-import-lib.buzz diff --git a/tests/015-interpolation.buzz b/tests/behavior/015-interpolation.buzz similarity index 100% rename from tests/015-interpolation.buzz rename to tests/behavior/015-interpolation.buzz diff --git a/tests/016-optionals.buzz b/tests/behavior/016-optionals.buzz similarity index 100% rename from tests/016-optionals.buzz rename to tests/behavior/016-optionals.buzz diff --git a/tests/017-for.buzz b/tests/behavior/017-for.buzz similarity index 100% rename from tests/017-for.buzz rename to tests/behavior/017-for.buzz diff --git a/tests/018-foreach.buzz b/tests/behavior/018-foreach.buzz similarity index 100% rename from tests/018-foreach.buzz rename to tests/behavior/018-foreach.buzz diff --git a/tests/019-is.buzz b/tests/behavior/019-is.buzz similarity index 100% rename from tests/019-is.buzz rename to tests/behavior/019-is.buzz diff --git a/tests/021-upvalues.buzz b/tests/behavior/021-upvalues.buzz similarity index 100% rename from tests/021-upvalues.buzz rename to tests/behavior/021-upvalues.buzz diff --git a/tests/023-std.buzz b/tests/behavior/023-std.buzz similarity index 100% rename from tests/023-std.buzz rename to tests/behavior/023-std.buzz diff --git a/tests/025-fs.buzz b/tests/behavior/025-fs.buzz similarity index 100% rename from tests/025-fs.buzz rename to tests/behavior/025-fs.buzz diff --git a/tests/026-break-continue.buzz b/tests/behavior/026-break-continue.buzz similarity index 100% rename from tests/026-break-continue.buzz rename to tests/behavior/026-break-continue.buzz diff --git a/tests/028-math.buzz b/tests/behavior/028-math.buzz similarity index 100% rename from tests/028-math.buzz rename to tests/behavior/028-math.buzz diff --git a/tests/029-default-arguments.buzz b/tests/behavior/029-default-arguments.buzz similarity index 100% rename from tests/029-default-arguments.buzz rename to tests/behavior/029-default-arguments.buzz diff --git a/tests/030-str.buzz b/tests/behavior/030-str.buzz similarity index 100% rename from tests/030-str.buzz rename to tests/behavior/030-str.buzz diff --git a/tests/032-debug.buzz b/tests/behavior/032-debug.buzz similarity index 100% rename from tests/032-debug.buzz rename to tests/behavior/032-debug.buzz diff --git a/tests/033-invoke.buzz b/tests/behavior/033-invoke.buzz similarity index 100% rename from tests/033-invoke.buzz rename to tests/behavior/033-invoke.buzz diff --git a/tests/034-scope.buzz b/tests/behavior/034-scope.buzz similarity index 100% rename from tests/034-scope.buzz rename to tests/behavior/034-scope.buzz diff --git a/tests/035-const-expr.buzz b/tests/behavior/035-const-expr.buzz similarity index 100% rename from tests/035-const-expr.buzz rename to tests/behavior/035-const-expr.buzz diff --git a/tests/036-pattern.buzz b/tests/behavior/036-pattern.buzz similarity index 100% rename from tests/036-pattern.buzz rename to tests/behavior/036-pattern.buzz diff --git a/tests/037-dead-branches.buzz b/tests/behavior/037-dead-branches.buzz similarity index 100% rename from tests/037-dead-branches.buzz rename to tests/behavior/037-dead-branches.buzz diff --git a/tests/038-fibers.buzz b/tests/behavior/038-fibers.buzz similarity index 100% rename from tests/038-fibers.buzz rename to tests/behavior/038-fibers.buzz diff --git a/tests/039-buffer.buzz b/tests/behavior/039-buffer.buzz similarity index 100% rename from tests/039-buffer.buzz rename to tests/behavior/039-buffer.buzz diff --git a/tests/040-bitwise.buzz b/tests/behavior/040-bitwise.buzz similarity index 100% rename from tests/040-bitwise.buzz rename to tests/behavior/040-bitwise.buzz diff --git a/tests/041-iterator.buzz b/tests/behavior/041-iterator.buzz similarity index 100% rename from tests/041-iterator.buzz rename to tests/behavior/041-iterator.buzz diff --git a/tests/042-anonymous-objects.buzz b/tests/behavior/042-anonymous-objects.buzz similarity index 100% rename from tests/042-anonymous-objects.buzz rename to tests/behavior/042-anonymous-objects.buzz diff --git a/tests/044-break-continue.buzz b/tests/behavior/044-break-continue.buzz similarity index 100% rename from tests/044-break-continue.buzz rename to tests/behavior/044-break-continue.buzz diff --git a/tests/045-mutual-import.buzz b/tests/behavior/045-mutual-import.buzz similarity index 100% rename from tests/045-mutual-import.buzz rename to tests/behavior/045-mutual-import.buzz diff --git a/tests/046-try-catch.buzz b/tests/behavior/046-try-catch.buzz similarity index 100% rename from tests/046-try-catch.buzz rename to tests/behavior/046-try-catch.buzz diff --git a/tests/047-if-arrow.buzz b/tests/behavior/047-if-arrow.buzz similarity index 100% rename from tests/047-if-arrow.buzz rename to tests/behavior/047-if-arrow.buzz diff --git a/tests/048-generics.buzz b/tests/behavior/048-generics.buzz similarity index 100% rename from tests/048-generics.buzz rename to tests/behavior/048-generics.buzz diff --git a/tests/050-protocols.buzz b/tests/behavior/050-protocols.buzz similarity index 100% rename from tests/050-protocols.buzz rename to tests/behavior/050-protocols.buzz diff --git a/tests/051-functional.buzz b/tests/behavior/051-functional.buzz similarity index 100% rename from tests/051-functional.buzz rename to tests/behavior/051-functional.buzz diff --git a/tests/052-inline-if.buzz b/tests/behavior/052-inline-if.buzz similarity index 100% rename from tests/052-inline-if.buzz rename to tests/behavior/052-inline-if.buzz diff --git a/tests/053-range.buzz b/tests/behavior/053-range.buzz similarity index 100% rename from tests/053-range.buzz rename to tests/behavior/053-range.buzz diff --git a/tests/056-crypto.buzz b/tests/behavior/056-crypto.buzz similarity index 100% rename from tests/056-crypto.buzz rename to tests/behavior/056-crypto.buzz diff --git a/tests/057-any.buzz b/tests/behavior/057-any.buzz similarity index 100% rename from tests/057-any.buzz rename to tests/behavior/057-any.buzz diff --git a/tests/059-types-as-value.buzz b/tests/behavior/059-types-as-value.buzz similarity index 100% rename from tests/059-types-as-value.buzz rename to tests/behavior/059-types-as-value.buzz diff --git a/tests/060-free-identifiers.buzz b/tests/behavior/060-free-identifiers.buzz similarity index 100% rename from tests/060-free-identifiers.buzz rename to tests/behavior/060-free-identifiers.buzz diff --git a/tests/061-utf8.buzz b/tests/behavior/061-utf8.buzz similarity index 100% rename from tests/061-utf8.buzz rename to tests/behavior/061-utf8.buzz diff --git a/tests/062-discarded-value.buzz b/tests/behavior/062-discarded-value.buzz similarity index 100% rename from tests/062-discarded-value.buzz rename to tests/behavior/062-discarded-value.buzz diff --git a/tests/063-nullable-default.buzz b/tests/behavior/063-nullable-default.buzz similarity index 100% rename from tests/063-nullable-default.buzz rename to tests/behavior/063-nullable-default.buzz diff --git a/tests/064-throw-inside-try.buzz b/tests/behavior/064-throw-inside-try.buzz similarity index 100% rename from tests/064-throw-inside-try.buzz rename to tests/behavior/064-throw-inside-try.buzz diff --git a/tests/065-inferred-var-type.buzz b/tests/behavior/065-inferred-var-type.buzz similarity index 100% rename from tests/065-inferred-var-type.buzz rename to tests/behavior/065-inferred-var-type.buzz diff --git a/tests/066-object-generics.buzz b/tests/behavior/066-object-generics.buzz similarity index 100% rename from tests/066-object-generics.buzz rename to tests/behavior/066-object-generics.buzz diff --git a/tests/069-named-expr.buzz b/tests/behavior/069-named-expr.buzz similarity index 100% rename from tests/069-named-expr.buzz rename to tests/behavior/069-named-expr.buzz diff --git a/tests/070-block-expression.buzz b/tests/behavior/070-block-expression.buzz similarity index 100% rename from tests/070-block-expression.buzz rename to tests/behavior/070-block-expression.buzz diff --git a/tests/071-tail-call.buzz b/tests/behavior/071-tail-call.buzz similarity index 100% rename from tests/071-tail-call.buzz rename to tests/behavior/071-tail-call.buzz diff --git a/tests/072-labels.buzz b/tests/behavior/072-labels.buzz similarity index 100% rename from tests/072-labels.buzz rename to tests/behavior/072-labels.buzz diff --git a/tests/073-tuples.buzz b/tests/behavior/073-tuples.buzz similarity index 100% rename from tests/073-tuples.buzz rename to tests/behavior/073-tuples.buzz diff --git a/tests/074-checked-subscript.buzz b/tests/behavior/074-checked-subscript.buzz similarity index 100% rename from tests/074-checked-subscript.buzz rename to tests/behavior/074-checked-subscript.buzz diff --git a/tests/075-composite-assign.buzz b/tests/behavior/075-composite-assign.buzz similarity index 100% rename from tests/075-composite-assign.buzz rename to tests/behavior/075-composite-assign.buzz From 61d9c431d6f55449c8eb98a8ca568c23dd0bef98 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Sat, 1 Nov 2025 12:58:31 +0100 Subject: [PATCH 02/17] fix: Several bugs found by fuzzing --- src/Ast.zig | 2 +- src/Codegen.zig | 13 +- src/Debugger.zig | 4 +- src/FFI.zig | 341 +++++++++++++++++++++++-------------------- src/Jit.zig | 33 ++++- src/Parser.zig | 177 +++++++++++++--------- src/Reporter.zig | 1 + src/Runner.zig | 4 +- src/Scanner.zig | 23 ++- src/builtin/list.zig | 49 +++++-- src/builtin/map.zig | 52 ++++--- src/buzz_api.zig | 14 +- src/lib/buzz_api.zig | 2 +- src/obj.zig | 25 ++-- src/vm.zig | 35 ++++- src/zigtypes.zig | 4 +- 16 files changed, 476 insertions(+), 303 deletions(-) diff --git a/src/Ast.zig b/src/Ast.zig index 7e20e6a8..9a8a76f0 100644 --- a/src/Ast.zig +++ b/src/Ast.zig @@ -894,7 +894,7 @@ pub const Slice = struct { }; } - return value.*.?; + return value.* orelse Value.Void; } }; diff --git a/src/Codegen.zig b/src/Codegen.zig index 163c31d4..459a3ec3 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -1158,7 +1158,7 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj ); } - if (components.arguments.len > args.count()) { + if (components.arguments.len > arg_count) { self.reporter.reportErrorAt( .call_arguments, self.ast.tokens.get(locations[node]), @@ -1170,6 +1170,10 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj // First push on the stack arguments has they are parsed var needs_reorder = false; for (components.arguments, 0..) |argument, index| { + if (index >= arg_count) { + break; + } + var argument_type_def = type_defs[argument.value].?; const arg_key = if (argument.name) |arg_name| try self.gc.copyString(lexemes[arg_name]) @@ -1251,6 +1255,7 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj } } + // Not enough arguments? if (missing_arguments.count() > 0) { var missing = std.Io.Writer.Allocating.init(self.gc.allocator); defer missing.deinit(); @@ -1283,8 +1288,8 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj ); } - // Reorder arguments - if (needs_reorder) { + // Reorder arguments (don't bother is something failed before) + if (self.reporter.last_error == null and needs_reorder) { // Until ordered while (true) { var ordered = true; @@ -4751,7 +4756,7 @@ fn generateZdef(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjF try self.emitConstant(location, element.zdef.type_def.toValue()); }, - else => unreachable, + else => {}, } try self.OP_DEFINE_GLOBAL( location, diff --git a/src/Debugger.zig b/src/Debugger.zig index 332b1d2f..23b485cf 100644 --- a/src/Debugger.zig +++ b/src/Debugger.zig @@ -1271,7 +1271,9 @@ pub fn main() !u8 { ), .configurationDone => { // Now the configuration phase is done, we start the program and it's up to the VM to call handlRequest at safepoints - debugger.session.?.runner.vm.run(); + debugger.session.?.runner.vm.run() catch { + // TODO + }; // Program is over, send terminated and stop event debugger.adapter.emitEvent( diff --git a/src/FFI.zig b/src/FFI.zig index 67e2d391..0ed20c44 100644 --- a/src/FFI.zig +++ b/src/FFI.zig @@ -11,6 +11,13 @@ const GC = @import("GC.zig"); const Self = @This(); +pub const Error = error{ + CantCompile, + NoSpaceLeft, + OutOfMemory, + WriteFailed, +}; + const basic_types = std.StaticStringMap(o.ObjTypeDef).initComptime( .{ .{ "u8", o.ObjTypeDef{ .def_type = .Integer } }, @@ -278,7 +285,7 @@ pub fn parse(self: *Self, parser: ?*Parser, source: Ast.TokenIndex, type_expr: ? const root_decls = self.state.?.ast.rootDecls(); if (root_decls.len == 0) { - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.report( .zdef, @@ -298,6 +305,11 @@ pub fn parse(self: *Self, parser: ?*Parser, source: Ast.TokenIndex, type_expr: ? } } + if (self.reporter.last_error != null) { + zdefs.deinit(self.gc.allocator); + return Error.CantCompile; + } + return try zdefs.toOwnedSlice(self.gc.allocator); } @@ -355,7 +367,7 @@ fn getZdef(self: *Self, decl_index: Ast.Node.Index) !?*Zdef { else => {}, } - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.reportErrorFmt( .zdef, location, @@ -387,7 +399,7 @@ fn getZdef(self: *Self, decl_index: Ast.Node.Index) !?*Zdef { }; if (uzdef.zig_type != .Pointer) { - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.reportErrorAt( .zdef, @@ -404,7 +416,7 @@ fn getZdef(self: *Self, decl_index: Ast.Node.Index) !?*Zdef { }, else => fail: { - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.reportErrorFmt( .zdef, location, @@ -419,7 +431,7 @@ fn getZdef(self: *Self, decl_index: Ast.Node.Index) !?*Zdef { }; } -fn containerDecl(self: *Self, name: []const u8, decl_index: Ast.Node.Index) anyerror!*Zdef { +fn containerDecl(self: *Self, name: []const u8, decl_index: Ast.Node.Index) Error!*Zdef { const container_node_tag = self.state.?.ast.nodeTag(decl_index); var buf: [2]Ast.Node.Index = undefined; @@ -435,7 +447,7 @@ fn containerDecl(self: *Self, name: []const u8, decl_index: Ast.Node.Index) anye const main_token = self.state.?.ast.tokens.get(container.ast.main_token).tag; if ((container.layout_token == null or self.state.?.ast.tokens.get(container.layout_token.?).tag != .keyword_extern) and main_token != .keyword_opaque) { - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.reportErrorAt( .zdef, location, @@ -449,7 +461,7 @@ fn containerDecl(self: *Self, name: []const u8, decl_index: Ast.Node.Index) anye .keyword_union => self.unionContainer(name, container), else => unsupported: { - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.reportErrorFmt( .zdef, location, @@ -470,52 +482,52 @@ fn containerDecl(self: *Self, name: []const u8, decl_index: Ast.Node.Index) anye }; } -fn unionContainer(self: *Self, name: []const u8, container: Ast.full.ContainerDecl) anyerror!*Zdef { +fn unionContainer(self: *Self, name: []const u8, container: Ast.full.ContainerDecl) Error!*Zdef { var fields = std.ArrayList(ZigType.UnionField).empty; var get_set_fields = std.StringArrayHashMapUnmanaged(o.ObjForeignContainer.ContainerDef.Field).empty; var buzz_fields = std.StringArrayHashMapUnmanaged(*o.ObjTypeDef).empty; var decls = std.ArrayList(ZigType.Declaration).empty; var next_field: ?*Zdef = null; for (container.ast.members, 0..) |member, idx| { - const member_zdef = next_field orelse try self.getZdef(member); - - next_field = if (idx < container.ast.members.len - 1) - try self.getZdef(container.ast.members[idx + 1]) - else - null; - - try fields.append( - self.gc.allocator, - ZigType.UnionField{ - .name = member_zdef.?.name, - .type = &member_zdef.?.zig_type, - .alignment = member_zdef.?.zig_type.alignment(), - }, - ); + if (next_field orelse try self.getZdef(member)) |member_zdef| { + next_field = if (idx < container.ast.members.len - 1) + try self.getZdef(container.ast.members[idx + 1]) + else + null; + + try fields.append( + self.gc.allocator, + ZigType.UnionField{ + .name = member_zdef.name, + .type = &member_zdef.zig_type, + .alignment = member_zdef.zig_type.alignment(), + }, + ); - try decls.append( - self.gc.allocator, - ZigType.Declaration{ - .name = member_zdef.?.name, - }, - ); + try decls.append( + self.gc.allocator, + ZigType.Declaration{ + .name = member_zdef.name, + }, + ); - try buzz_fields.put( - self.gc.allocator, - member_zdef.?.name, - member_zdef.?.type_def, - ); + try buzz_fields.put( + self.gc.allocator, + member_zdef.name, + member_zdef.type_def, + ); - try get_set_fields.put( - self.gc.allocator, - member_zdef.?.name, - .{ - // Always 0 since this is an enum - .offset = 0, - .getter = undefined, - .setter = undefined, - }, - ); + try get_set_fields.put( + self.gc.allocator, + member_zdef.name, + .{ + // Always 0 since this is an enum + .offset = 0, + .getter = undefined, + .setter = undefined, + }, + ); + } } const zig_type = ZigType{ @@ -563,7 +575,7 @@ fn unionContainer(self: *Self, name: []const u8, container: Ast.full.ContainerDe return zdef; } -fn structContainer(self: *Self, name: []const u8, container: Ast.full.ContainerDecl) anyerror!*Zdef { +fn structContainer(self: *Self, name: []const u8, container: Ast.full.ContainerDecl) Error!*Zdef { var fields = std.ArrayList(ZigType.StructField).empty; var get_set_fields = std.StringArrayHashMapUnmanaged(o.ObjForeignContainer.ContainerDef.Field).empty; var buzz_fields = std.StringArrayHashMapUnmanaged(*o.ObjTypeDef).empty; @@ -571,59 +583,59 @@ fn structContainer(self: *Self, name: []const u8, container: Ast.full.ContainerD var offset: usize = 0; var next_field: ?*Zdef = null; for (container.ast.members, 0..) |member, idx| { - const member_zdef = next_field orelse try self.getZdef(member); - - next_field = if (idx < container.ast.members.len - 1) - try self.getZdef(container.ast.members[idx + 1]) - else - null; - - try fields.append( - self.gc.allocator, - ZigType.StructField{ - .name = member_zdef.?.name, - .type = &member_zdef.?.zig_type, - .default_value = null, - .is_comptime = false, - .alignment = member_zdef.?.zig_type.alignment(), - }, - ); + if (next_field orelse try self.getZdef(member)) |member_zdef| { + next_field = if (idx < container.ast.members.len - 1) + try self.getZdef(container.ast.members[idx + 1]) + else + null; + + try fields.append( + self.gc.allocator, + ZigType.StructField{ + .name = member_zdef.name, + .type = &member_zdef.zig_type, + .default_value = null, + .is_comptime = false, + .alignment = member_zdef.zig_type.alignment(), + }, + ); - try decls.append( - self.gc.allocator, - ZigType.Declaration{ - .name = member_zdef.?.name, - }, - ); + try decls.append( + self.gc.allocator, + ZigType.Declaration{ + .name = member_zdef.name, + }, + ); - try buzz_fields.put( - self.gc.allocator, - member_zdef.?.name, - member_zdef.?.type_def, - ); + try buzz_fields.put( + self.gc.allocator, + member_zdef.name, + member_zdef.type_def, + ); - try get_set_fields.put( - self.gc.allocator, - member_zdef.?.name, - .{ - .offset = offset, - .getter = undefined, - .setter = undefined, - }, - ); + try get_set_fields.put( + self.gc.allocator, + member_zdef.name, + .{ + .offset = offset, + .getter = undefined, + .setter = undefined, + }, + ); - offset += member_zdef.?.zig_type.size(); + offset += member_zdef.zig_type.size(); - // Round up the end of the previous field to a multiple of the next field's alignment - if (next_field) |next| { - const next_field_align = next.zig_type.alignment(); - const current_field_size = member_zdef.?.zig_type.size(); + // Round up the end of the previous field to a multiple of the next field's alignment + if (next_field) |next| { + const next_field_align = next.zig_type.alignment(); + const current_field_size = member_zdef.zig_type.size(); - const div = @as(f64, @floatFromInt(current_field_size)) / @as(f64, @floatFromInt(next_field_align)); - const fpart = std.math.modf(div).fpart; - const padding = @as(usize, @intFromFloat(fpart * @as(f64, @floatFromInt(next_field_align)))); + const div = @as(f64, @floatFromInt(current_field_size)) / @as(f64, @floatFromInt(next_field_align)); + const fpart = std.math.modf(div).fpart; + const padding = @as(usize, @intFromFloat(fpart * @as(f64, @floatFromInt(next_field_align)))); - offset += padding; + offset += padding; + } } } @@ -661,16 +673,18 @@ fn structContainer(self: *Self, name: []const u8, container: Ast.full.ContainerD return zdef; } -fn containerField(self: *Self, decl_index: Ast.Node.Index) anyerror!*Zdef { +fn containerField(self: *Self, decl_index: Ast.Node.Index) Error!?*Zdef { const container_field = self.state.?.ast.containerFieldInit(decl_index); - var zdef = (try self.getZdef(container_field.ast.type_expr.unwrap().?)).?; - zdef.name = self.state.?.ast.tokenSlice(self.state.?.ast.nodeMainToken(decl_index)); + if (try self.getZdef(container_field.ast.type_expr.unwrap().?)) |zdef| { + zdef.name = self.state.?.ast.tokenSlice(self.state.?.ast.nodeMainToken(decl_index)); + return zdef; + } - return zdef; + return null; } -fn identifier(self: *Self, decl_index: Ast.Node.Index) anyerror!*Zdef { +fn identifier(self: *Self, decl_index: Ast.Node.Index) Error!*Zdef { const id = self.state.?.ast.tokenSlice(self.state.?.ast.nodeMainToken(decl_index)); var type_def = if (basic_types.get(id)) |basic_type| @@ -716,7 +730,7 @@ fn identifier(self: *Self, decl_index: Ast.Node.Index) anyerror!*Zdef { } if (type_def == null or zig_type == null) { - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.reportErrorFmt( .zdef, @@ -725,6 +739,8 @@ fn identifier(self: *Self, decl_index: Ast.Node.Index) anyerror!*Zdef { "Unknown or unsupported type `{s}`", .{id}, ); + + zig_type = null; } const zdef = try self.gc.allocator.create(Zdef); @@ -737,7 +753,7 @@ fn identifier(self: *Self, decl_index: Ast.Node.Index) anyerror!*Zdef { return zdef; } -fn ptrType(self: *Self, tag: Ast.Node.Tag, decl_index: Ast.Node.Index) anyerror!*Zdef { +fn ptrType(self: *Self, tag: Ast.Node.Tag, decl_index: Ast.Node.Index) Error!*Zdef { const ptr_type = switch (tag) { .ptr_type_aligned => self.state.?.ast.ptrTypeAligned(decl_index), .ptr_type_sentinel => self.state.?.ast.ptrTypeSentinel(decl_index), @@ -745,72 +761,75 @@ fn ptrType(self: *Self, tag: Ast.Node.Tag, decl_index: Ast.Node.Index) anyerror! else => unreachable, }; - const child_type = (try self.getZdef(ptr_type.ast.child_type)).?; - const sentinel_node_tag = if (ptr_type.ast.sentinel.unwrap()) |sentinel| self.state.?.ast.nodeTag(sentinel) else null; - const sentinel_node_main_token = if (ptr_type.ast.sentinel.unwrap()) |sentinel| self.state.?.ast.nodeMainToken(sentinel) else null; - - // Is it a null terminated string? - const zdef = try self.gc.allocator.create(Zdef); - zdef.* = if (ptr_type.const_token != null and - child_type.zig_type == .Int and - child_type.zig_type.Int.bits == 8 and - sentinel_node_tag == .number_literal and - std.mem.eql(u8, self.state.?.ast.tokenSlice(sentinel_node_main_token.?), "0")) - .{ - .type_def = self.gc.type_registry.str_type, - .zig_type = ZigType{ - .Pointer = .{ - .size = .c, - .is_const = ptr_type.const_token != null, - .is_volatile = undefined, - .alignment = undefined, - .address_space = undefined, - .child = &child_type.zig_type, - .is_allowzero = undefined, - .sentinel = undefined, + if (try self.getZdef(ptr_type.ast.child_type)) |child_type| { + const sentinel_node_tag = if (ptr_type.ast.sentinel.unwrap()) |sentinel| self.state.?.ast.nodeTag(sentinel) else null; + const sentinel_node_main_token = if (ptr_type.ast.sentinel.unwrap()) |sentinel| self.state.?.ast.nodeMainToken(sentinel) else null; + + // Is it a null terminated string? + const zdef = try self.gc.allocator.create(Zdef); + zdef.* = if (ptr_type.const_token != null and + child_type.zig_type == .Int and + child_type.zig_type.Int.bits == 8 and + sentinel_node_tag == .number_literal and + std.mem.eql(u8, self.state.?.ast.tokenSlice(sentinel_node_main_token.?), "0")) + .{ + .type_def = self.gc.type_registry.str_type, + .zig_type = ZigType{ + .Pointer = .{ + .size = .c, + .is_const = ptr_type.const_token != null, + .is_volatile = undefined, + .alignment = undefined, + .address_space = undefined, + .child = &child_type.zig_type, + .is_allowzero = undefined, + .sentinel = undefined, + }, }, - }, - .name = "ptr", - } - else if (child_type.type_def.def_type == .ForeignContainer) - .{ - .type_def = child_type.type_def, - .zig_type = ZigType{ - .Pointer = .{ - .size = .c, - .is_const = ptr_type.const_token != null, - .is_volatile = undefined, - .alignment = undefined, - .address_space = undefined, - .child = &child_type.zig_type, - .is_allowzero = undefined, - .sentinel = undefined, + .name = "ptr", + } + else if (child_type.type_def.def_type == .ForeignContainer) + .{ + .type_def = child_type.type_def, + .zig_type = ZigType{ + .Pointer = .{ + .size = .c, + .is_const = ptr_type.const_token != null, + .is_volatile = undefined, + .alignment = undefined, + .address_space = undefined, + .child = &child_type.zig_type, + .is_allowzero = undefined, + .sentinel = undefined, + }, }, - }, - .name = "ptr", - } - else - .{ - .type_def = self.gc.type_registry.ud_type, - .zig_type = ZigType{ - .Pointer = .{ - .size = .c, - .is_const = ptr_type.const_token != null, - .is_volatile = undefined, - .alignment = undefined, - .address_space = undefined, - .child = &child_type.zig_type, - .is_allowzero = undefined, - .sentinel = undefined, + .name = "ptr", + } + else + .{ + .type_def = self.gc.type_registry.ud_type, + .zig_type = ZigType{ + .Pointer = .{ + .size = .c, + .is_const = ptr_type.const_token != null, + .is_volatile = undefined, + .alignment = undefined, + .address_space = undefined, + .child = &child_type.zig_type, + .is_allowzero = undefined, + .sentinel = undefined, + }, }, - }, - .name = "ptr", - }; + .name = "ptr", + }; - return zdef; + return zdef; + } + + return error.CantCompile; } -fn fnProto(self: *Self, tag: Ast.Node.Tag, decl_index: Ast.Node.Index) anyerror!*Zdef { +fn fnProto(self: *Self, tag: Ast.Node.Tag, decl_index: Ast.Node.Index) Error!*Zdef { var buffer = [1]Ast.Node.Index{undefined}; const fn_proto = switch (tag) { .fn_proto_simple => self.state.?.ast.fnProtoSimple(&buffer, decl_index), @@ -824,7 +843,7 @@ fn fnProto(self: *Self, tag: Ast.Node.Tag, decl_index: Ast.Node.Index) anyerror! const name = if (fn_proto.name_token) |token| self.state.?.ast.tokenSlice(token) else null; if (name == null) { - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.report( .zdef, location, @@ -869,7 +888,7 @@ fn fnProto(self: *Self, tag: Ast.Node.Tag, decl_index: Ast.Node.Index) anyerror! null; if (param_name == null) { - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.report( .zdef, location, @@ -923,7 +942,7 @@ fn reportZigError(self: *Self, err: Ast.Error) void { message.writer.print("zdef could not be parsed: {}", .{err.tag}) catch unreachable; - const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source); + const location = self.state.?.buzz_ast.?.tokens.get(self.state.?.source - 4); self.reporter.report( .zdef, location, diff --git a/src/Jit.zig b/src/Jit.zig index 747143c8..4c2653d3 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -2341,6 +2341,23 @@ fn generateHandleExternReturn( self.append(continue_label); } + // Uncatchable runtime error? + const continue_label = m.MIR_new_label(self.ctx); + + self.BNE( + continue_label, + return_code, + m.MIR_new_int_op(self.ctx, -2), + ); + + try self.buildExternApiCall( + .exit, + null, + &[_]m.MIR_op_t{m.MIR_new_uint_op(self.ctx, 1)}, + ); + + self.append(continue_label); + const result = try self.REG("result", m.MIR_T_I64); if (should_return) { try self.buildPop(m.MIR_new_reg_op(self.ctx, result)); @@ -5563,7 +5580,7 @@ pub fn compileZdef(self: *Self, buzz_ast: Ast.Slice, zdef: Ast.Zdef.ZdefElement) ); } -fn zigToMIRType(zig_type: ZigType) m.MIR_type_t { +fn zigToMIRType(zig_type: ZigType) Error!m.MIR_type_t { return switch (zig_type) { .Int => if (zig_type.Int.signedness == .signed) switch (zig_type.Int.bits) { @@ -5591,8 +5608,8 @@ fn zigToMIRType(zig_type: ZigType) m.MIR_type_t { .Optional, => m.MIR_T_I64, // See https://github.com/vnmakarov/mir/issues/332 passing struct by values will need some work - .Struct => unreachable, //m.MIR_T_BLK, - else => unreachable, + .Struct => error.CantCompile, //m.MIR_T_BLK, + else => error.CantCompile, }; } @@ -5690,7 +5707,7 @@ fn buildZdefWrapper(self: *Self, zdef_element: Ast.Zdef.ZdefElement) Error!m.MIR try arg_types.append( self.vm.gc.allocator, .{ - .type = zigToMIRType( + .type = try zigToMIRType( if (param.type) |param_type| param_type.* else @@ -5910,7 +5927,7 @@ fn buildZdefUnionGetter( const field_ptr = m.MIR_new_mem_op( self.ctx, - zigToMIRType(zig_type.*), + try zigToMIRType(zig_type.*), 0, data_reg, index, @@ -6027,7 +6044,7 @@ fn buildZdefUnionSetter( const field_ptr = m.MIR_new_mem_op( self.ctx, - zigToMIRType(zig_type.*), + try zigToMIRType(zig_type.*), 0, data_reg, index, @@ -6113,7 +6130,7 @@ fn buildZdefContainerGetter( const field_ptr = m.MIR_new_mem_op( self.ctx, - zigToMIRType(zig_type.*), + try zigToMIRType(zig_type.*), @intCast(offset), data_reg, index, @@ -6218,7 +6235,7 @@ fn buildZdefContainerSetter( const field_ptr = m.MIR_new_mem_op( self.ctx, - zigToMIRType(zig_type.*), + try zigToMIRType(zig_type.*), @intCast(offset), data_reg, index, diff --git a/src/Parser.zig b/src/Parser.zig index ddf94e2a..99820503 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -677,6 +677,8 @@ pub fn advance(self: *Self) !void { "Unknown Error", }, ); + + return error.CantCompile; } _ = try self.ast.appendToken(new_token); @@ -700,8 +702,8 @@ fn advancePastEof(self: *Self) !void { self.current_token = if (self.current_token) |ct| ct - 1 else 0; self.reporter.reportErrorFmt( .unknown, - self.ast.tokens.get(self.current_token.? - 1), - self.ast.tokens.get(self.current_token.? - 1), + self.ast.tokens.get(self.current_token.?), + self.ast.tokens.get(self.current_token.?), "{s}", .{ if (new_token.literal == .String) @@ -873,7 +875,7 @@ fn synchronize(self: *Self) !void { self.reporter.panic_mode = false; while (self.ast.tokens.items(.tag)[self.current_token.?] != .Eof) : (try self.advance()) { - if (self.ast.tokens.items(.tag)[self.current_token.? - 1] == .Semicolon) { + if (self.current_token.? == 0 or self.ast.tokens.items(.tag)[self.current_token.? - 1] == .Semicolon) { return; } @@ -916,7 +918,31 @@ pub fn parse(self: *Self, source: []const u8, file_name: ?[]const u8, name: []co self.scanner = null; } - self.scanner = Scanner.init(self.gc.allocator, file_name orelse name, source); + // Source must be valid UTF8 + if (!std.unicode.utf8ValidateSlice(source)) { + const loc = Token{ + .column = 0, + .line = 0, + .source = source, + .script_name = file_name orelse name, + .tag = .Error, + .lexeme = "", + }; + self.reporter.report( + .source_not_utf8, + loc, + loc, + "Script must be valid UTF-8.", + ); + + return null; + } + + self.scanner = Scanner.init( + self.gc.allocator, + file_name orelse name, + source, + ); const function_type: obj.ObjFunction.FunctionType = if (!self.imported and self.flavor == .Repl) .Repl @@ -1315,6 +1341,18 @@ fn parsePrecedence(self: *Self, precedence: Precedence, hanging: bool) Error!Ast const previous_opt_jumps = self.opt_jumps; self.opt_jumps = null; + if (self.ast.tokens.items(.tag)[self.current_token.?] == .Eof) { + const loc = self.ast.tokens.get(self.current_token.?); + self.reporter.reportErrorAt( + .syntax, + loc, + loc, + "Expected expression, got EOF.", + ); + + return error.CantCompile; + } + // If hanging is true, that means we already read the start of the expression if (!hanging) { _ = try self.advance(); @@ -3741,27 +3779,29 @@ fn parseUserType(self: *Self, instance: bool, mutable: bool) Error!Ast.Node.Inde location, "Expected at least one type", ); + } else if (var_type.?.def_type == .Object) { + var_type = try var_type.?.populateGenerics( + self.current_token.? - 1, + var_type.?.resolved_type.?.Object.id, + try resolved_generics.toOwnedSlice(self.gc.allocator), + &self.gc.type_registry, + self.gc.allocator, + null, + ); + break :gn try self.ast.appendNode( + .{ + .tag = .GenericResolveType, + .location = generic_start, + .end_location = self.current_token.? - 1, + .type_def = var_type, + .components = .{ + .GenericResolveType = try generic_nodes.toOwnedSlice(self.gc.allocator), + }, + }, + ); } - var_type = try var_type.?.populateGenerics( - self.current_token.? - 1, - var_type.?.resolved_type.?.Object.id, - try resolved_generics.toOwnedSlice(self.gc.allocator), - &self.gc.type_registry, - self.gc.allocator, - null, - ); - break :gn try self.ast.appendNode( - .{ - .tag = .GenericResolveType, - .location = generic_start, - .end_location = self.current_token.? - 1, - .type_def = var_type, - .components = .{ - .GenericResolveType = try generic_nodes.toOwnedSlice(self.gc.allocator), - }, - }, - ); + break :gn null; } else null; std.debug.assert(!mutable or self.ast.tokens.items(.tag)[user_type_name[0] - 1] == .Mut); @@ -3860,13 +3900,13 @@ fn parseGenericResolve(self: *Self, callee_type_def: *obj.ObjTypeDef, expr: ?Ast fn subscript(self: *Self, can_assign: bool, subscripted: Ast.Node.Index) Error!Ast.Node.Index { const start_location = self.ast.nodes.items(.location)[subscripted]; - const subscript_type_def = self.ast.nodes.items(.type_def)[subscripted]; + const subscript_type_def = self.ast.nodes.items(.type_def)[subscripted] orelse self.gc.type_registry.any_type; const checked = try self.match(.Question); const index = try self.expression(false); const index_type_def = self.ast.nodes.items(.type_def)[index]; const type_defs = self.ast.nodes.items(.type_def); - if (subscript_type_def.?.def_type == .Placeholder and index_type_def.?.def_type == .Placeholder) { + if (subscript_type_def.def_type == .Placeholder and index_type_def.?.def_type == .Placeholder) { try obj.PlaceholderDef.link( self.gc.allocator, type_defs[subscripted].?, @@ -3928,14 +3968,14 @@ fn subscript(self: *Self, can_assign: bool, subscripted: Ast.Node.Index) Error!A try self.consume(.RightBracket, "Expected `]`."); var value: ?Ast.Node.Index = null; - if (can_assign and (subscript_type_def == null or subscript_type_def.?.def_type != .String) and try self.match(.Equal)) { + if (can_assign and (subscript_type_def.def_type != .Any or subscript_type_def.def_type != .String) and try self.match(.Equal)) { value = try self.expression(false); const value_type_def = self.ast.nodes.items(.type_def)[value.?]; - if (subscript_type_def.?.def_type == .Placeholder and value_type_def.?.def_type == .Placeholder) { + if (subscript_type_def.def_type == .Placeholder and value_type_def.?.def_type == .Placeholder) { try obj.PlaceholderDef.link( self.gc.allocator, - subscript_type_def.?, + subscript_type_def, value_type_def.?, .Subscript, ); @@ -5108,7 +5148,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind } const generic_resolve = if (try self.match(.DoubleColon)) - try self.parseGenericResolve(property_type.?, null) + try self.parseGenericResolve(property_type orelse self.gc.type_registry.any_type, null) else null; @@ -5138,7 +5178,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind } else if (try self.match(.LeftParen)) { // Do we call it // `call` will look to the parent node for the function definition self.ast.nodes.items(.type_def)[dot_node] = property_type; - components[dot_node].Dot.member_type_def = property_type.?; + components[dot_node].Dot.member_type_def = property_type orelse self.gc.type_registry.any_type; const call_node = try self.call(can_assign, dot_node); components = self.ast.nodes.items(.components); // ptr might have been invalidated components[dot_node].Dot.member_kind = .Call; @@ -5178,7 +5218,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind .property_does_not_exists, location, location, - "Property `{s}` does not exists in object `{s}`", + "Property `{s}` does not exists in container `{s}`", .{ member_name, f_def.name.string, @@ -5238,6 +5278,8 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind property_type = placeholder; } else if (property_type == null) { + property_type = self.gc.type_registry.any_type; + const location = self.ast.tokens.get(member_name_token); self.reporter.reportErrorFmt( .property_does_not_exists, @@ -5249,7 +5291,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind } const generic_resolve = if (try self.match(.DoubleColon)) - try self.parseGenericResolve(property_type.?, null) + try self.parseGenericResolve(property_type orelse self.gc.type_registry.any_type, null) else null; @@ -5280,7 +5322,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind // `call` will look to the parent node for the function definition self.ast.nodes.items(.type_def)[dot_node] = property_type; components[dot_node].Dot.member_kind = .Call; - components[dot_node].Dot.member_type_def = property_type.?; + components[dot_node].Dot.member_type_def = property_type orelse self.gc.type_registry.any_type; const call_node = try self.call(can_assign, dot_node); components = self.ast.nodes.items(.components); // ptr might have been invalidated components[dot_node].Dot.value_or_call_or_enum = .{ @@ -5333,7 +5375,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind // `call` will look to the parent node for the function definition self.ast.nodes.items(.type_def)[dot_node] = method_type; components[dot_node].Dot.member_kind = .Call; - components[dot_node].Dot.member_type_def = method_type.?; + components[dot_node].Dot.member_type_def = method_type orelse self.gc.type_registry.any_type; const call_node = try self.call(can_assign, dot_node); components = self.ast.nodes.items(.components); // ptr might have been invalidated components[dot_node].Dot.value_or_call_or_enum = .{ @@ -5350,22 +5392,29 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind .Enum => { const enum_def = callee_type_def.?.resolved_type.?.Enum; + self.ast.nodes.items(.type_def)[dot_node] = try self.gc.type_registry.getTypeDef( + .{ + .optional = false, + .def_type = .EnumInstance, + .resolved_type = .{ + .EnumInstance = .{ + .of = callee_type_def orelse self.gc.type_registry.any_type, + .mutable = false, + }, + }, + }, + ); + + const components = self.ast.nodes.items(.components); + components[dot_node].Dot.member_kind = .EnumCase; + components[dot_node].Dot.value_or_call_or_enum = .{ + .EnumCase = 0, // We put it at 0 in the event that the requested case does not exists + }; + + var found = false; for (enum_def.cases, 0..) |case, index| { if (std.mem.eql(u8, case, member_name)) { - self.ast.nodes.items(.type_def)[dot_node] = try self.gc.type_registry.getTypeDef( - .{ - .optional = false, - .def_type = .EnumInstance, - .resolved_type = .{ - .EnumInstance = .{ - .of = callee_type_def.?, - .mutable = false, - }, - }, - }, - ); - const components = self.ast.nodes.items(.components); - components[dot_node].Dot.member_kind = .EnumCase; + found = true; components[dot_node].Dot.value_or_call_or_enum = .{ .EnumCase = @intCast(index), }; @@ -5373,7 +5422,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind } } - if (self.ast.nodes.items(.type_def)[dot_node] == null) { + if (!found) { const location = self.ast.tokens.get(member_name_token); self.reporter.reportErrorFmt( .enum_case, @@ -5443,6 +5492,8 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind location, "List property doesn't exist.", ); + + self.ast.nodes.items(.type_def)[dot_node] = self.gc.type_registry.any_type; } }, .Map => { @@ -5553,6 +5604,8 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind } }, else => { + self.ast.nodes.items(.type_def)[dot_node] = self.gc.type_registry.any_type; + self.reportErrorAtNode( .field_access, callee, @@ -5579,7 +5632,7 @@ fn forceUnwrap(self: *Self, _: bool, unwrapped: Ast.Node.Index) Error!Ast.Node.I } fn unwrap(self: *Self, force: bool, unwrapped: Ast.Node.Index) Error!Ast.Node.Index { - const unwrapped_type_def = self.ast.nodes.items(.type_def)[unwrapped].?; + const unwrapped_type_def = self.ast.nodes.items(.type_def)[unwrapped] orelse self.gc.type_registry.any_type; const node = self.ast.appendNode( .{ @@ -5643,7 +5696,10 @@ fn unary(self: *Self, _: bool) Error!Ast.Node.Index { } fn genericResolve(self: *Self, _: bool, expr: Ast.Node.Index) Error!Ast.Node.Index { - return try self.parseGenericResolve(self.ast.nodes.items(.type_def)[expr].?, expr); + return try self.parseGenericResolve( + self.ast.nodes.items(.type_def)[expr] orelse self.gc.type_registry.any_type, + expr, + ); } fn @"or"(self: *Self, _: bool, left: Ast.Node.Index) Error!Ast.Node.Index { @@ -6534,8 +6590,8 @@ fn asyncCall(self: *Self, _: bool) Error!Ast.Node.Index { .{ .tag = .AsyncCall, .location = start_location, - .end_location = undefined, - .type_def = null, + .end_location = start_location, + .type_def = self.gc.type_registry.any_type, .components = .{ .AsyncCall = callable_node, }, @@ -6622,15 +6678,6 @@ fn asyncCall(self: *Self, _: bool) Error!Ast.Node.Index { ); } else { if (function_type.def_type != .Function) { - io.print( - "function_type.def_type {}\ncall_components.Call.callee {}\ncallable.tag {}\ncall_node tag {}\n", - .{ - function_type.def_type, - self.ast.nodes.items(.tag)[call_components.Call.callee], - callable.tag, - self.ast.nodes.items(.tag)[call_node], - }, - ); self.reportErrorAtNode( .callable, self.ast.nodes.items(.components)[call_node].Call.callee, @@ -9309,9 +9356,9 @@ fn zdefStatement(self: *Self) Error!Ast.Node.Index { const zdefs = if (!is_wasm) (self.ffi.parse(self, source, null) catch { return Error.CantCompile; - }) orelse &[_]*FFI.Zdef{} + }) orelse return Error.CantCompile else - &[_]*FFI.Zdef{}; + return Error.CantCompile; var elements = std.ArrayList(Ast.Zdef.ZdefElement).empty; if (!is_wasm) { @@ -9775,7 +9822,7 @@ fn forEachStatement(self: *Self) Error!Ast.Node.Index { ); const iterable = try self.expression(false); - const iterable_type_def = self.ast.nodes.items(.type_def)[iterable].?; + const iterable_type_def = self.ast.nodes.items(.type_def)[iterable] orelse self.gc.type_registry.any_type; self.current.?.locals[iterable_slot].type_def = iterable_type_def; diff --git a/src/Reporter.zig b/src/Reporter.zig index f533bf8f..156f19ec 100644 --- a/src/Reporter.zig +++ b/src/Reporter.zig @@ -133,6 +133,7 @@ pub const Error = enum(u8) { not_mutable = 100, mutable_forbidden = 101, unassigned_final_local = 102, + source_not_utf8 = 103, }; // Inspired by https://github.com/zesterer/ariadne diff --git a/src/Runner.zig b/src/Runner.zig index f6ffe6f5..8b5d62e0 100644 --- a/src/Runner.zig +++ b/src/Runner.zig @@ -315,7 +315,7 @@ pub fn evaluate(self: *Runner, parent_fiber: *Fiber, parent_frame: *CallFrame, e ); // Run it - self.vm.run(); + try self.vm.run(); // This will only have defined our eval function as a new global, // now we get that global and call it with the locals as arguments @@ -352,7 +352,7 @@ pub fn evaluate(self: *Runner, parent_fiber: *Fiber, parent_frame: *CallFrame, e ); // Run again - self.vm.run(); + try self.vm.run(); // We always return something, even void return self.vm.pop(); diff --git a/src/Scanner.zig b/src/Scanner.zig index 97656d29..b3964eb7 100644 --- a/src/Scanner.zig +++ b/src/Scanner.zig @@ -256,8 +256,13 @@ fn atIdentifier(self: *Self) Token { self.current.start_line = self.current.line; self.current.start_column = self.current.column; - if (self.advance() != '"') { - return self.makeToken(.Error, .{ .String = "Unterminated identifier." }); + if (self.current.offset >= self.source.len or self.advance() != '"') { + return self.makeToken( + .Error, + .{ + .String = "Unterminated identifier.", + }, + ); } const string_token = self.string(false); @@ -395,12 +400,22 @@ fn hexa(self: *Self) Token { return self.makeToken(.Error, .{ .String = "'_' must be between digits" }); } + if (self.isEOF()) { + return self.makeToken(.Error, .{ .String = "Unterminated hexa literal" }); + } + _ = self.advance(); // Consume 'x' var peeked: u8 = self.peek(); - while (isNumber(peeked) or (peeked >= 'A' and peeked <= 'F') or (peeked >= 'a' and peeked <= 'f') or peeked == '_') { + var digits: usize = 0; + while (!self.isEOF() and (isNumber(peeked) or (peeked >= 'A' and peeked <= 'F') or (peeked >= 'a' and peeked <= 'f') or peeked == '_')) { _ = self.advance(); peeked = self.peek(); + digits += 1; + } + + if (self.isEOF() or digits == 0) { + return self.makeToken(.Error, .{ .String = "Unterminated hexa literal" }); } if (self.source[self.current.offset - 1] == '_') { @@ -418,7 +433,7 @@ fn hexa(self: *Self) Token { } fn pattern(self: *Self) Token { - if (self.advance() != '"') { + if (self.isEOF() or self.advance() != '"') { return self.makeToken(.Error, .{ .String = "Unterminated pattern." }); } diff --git a/src/builtin/list.zig b/src/builtin/list.zig index 3e86e62c..3b6a8765 100644 --- a/src/builtin/list.zig +++ b/src/builtin/list.zig @@ -113,18 +113,23 @@ pub fn remove(ctx: *o.NativeCtx) callconv(.c) c_int { const SortContext = struct { sort_closure: v.Value, ctx: *o.NativeCtx, + had_error: bool = false, }; -fn lessThan(context: SortContext, lhs: v.Value, rhs: v.Value) bool { +fn lessThan(context: *SortContext, lhs: v.Value, rhs: v.Value) bool { var args = [_]*const v.Value{ &lhs, &rhs }; - buzz_api.bz_call( + if (!buzz_api.bz_call( context.ctx.vm, context.sort_closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + context.had_error = true; + + return false; + } return context.ctx.vm.pop().boolean(); } @@ -134,15 +139,21 @@ pub fn sort(ctx: *o.NativeCtx) callconv(.c) c_int { // fun compare(T lhs, T rhs) > bool const sort_closure = ctx.vm.peek(0); + var context = SortContext{ + .sort_closure = sort_closure, + .ctx = ctx, + }; std.sort.insertion( v.Value, self.items.items, - SortContext{ - .sort_closure = sort_closure, - .ctx = ctx, - }, + &context, lessThan, ); + + if (context.had_error) { + return -2; + } + ctx.vm.gc.markObjDirty(self.toObj()) catch @panic("Out of memory"); ctx.vm.push(self.toValue()); @@ -325,13 +336,15 @@ pub fn forEach(ctx: *o.NativeCtx) callconv(.c) c_int { var args = [_]*const v.Value{ &index_value, &item }; - buzz_api.bz_call( + if (!buzz_api.bz_call( ctx.vm, closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + return -2; + } } return 0; @@ -351,13 +364,15 @@ pub fn reduce(ctx: *o.NativeCtx) callconv(.c) c_int { &accumulator, }; - buzz_api.bz_call( + if (!buzz_api.bz_call( ctx.vm, closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + return -2; + } accumulator = ctx.vm.pop(); } @@ -388,13 +403,15 @@ pub fn filter(ctx: *o.NativeCtx) callconv(.c) c_int { const index_value = v.Value.fromInteger(@as(v.Integer, @intCast(index))); var args = [_]*const v.Value{ &index_value, &item }; - buzz_api.bz_call( + if (!buzz_api.bz_call( ctx.vm, closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + return -2; + } if (ctx.vm.pop().boolean()) { new_list.rawAppend(ctx.vm.gc, item) catch { @@ -448,13 +465,15 @@ pub fn map(ctx: *o.NativeCtx) callconv(.c) c_int { const index_value = v.Value.fromInteger(@as(v.Integer, @intCast(index))); var args = [_]*const v.Value{ &index_value, &item }; - buzz_api.bz_call( + if (!buzz_api.bz_call( ctx.vm, closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + return -2; + } new_list.rawAppend(ctx.vm.gc, ctx.vm.pop()) catch { ctx.vm.panic("Out of memory"); diff --git a/src/builtin/map.zig b/src/builtin/map.zig index 4ea11d62..a999da07 100644 --- a/src/builtin/map.zig +++ b/src/builtin/map.zig @@ -52,13 +52,15 @@ pub fn reduce(ctx: *o.NativeCtx) callconv(.c) c_int { while (it.next()) |kv| { var args = [_]*const v.Value{ kv.key_ptr, kv.value_ptr, &accumulator }; - buzz_api.bz_call( + if (!buzz_api.bz_call( ctx.vm, closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + return -2; + } accumulator = ctx.vm.pop(); } @@ -89,13 +91,15 @@ pub fn filter(ctx: *o.NativeCtx) callconv(.c) c_int { while (it.next()) |kv| { var args = [_]*const v.Value{ kv.key_ptr, kv.value_ptr }; - buzz_api.bz_call( + if (!buzz_api.bz_call( ctx.vm, closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + return -2; + } if (ctx.vm.pop().boolean()) { new_map.set(ctx.vm.gc, kv.key_ptr.*, kv.value_ptr.*) catch { @@ -118,13 +122,15 @@ pub fn forEach(ctx: *o.NativeCtx) callconv(.c) c_int { while (it.next()) |kv| { var args = [_]*const v.Value{ kv.key_ptr, kv.value_ptr }; - buzz_api.bz_call( + if (!buzz_api.bz_call( ctx.vm, closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + return -2; + } } return 0; @@ -170,13 +176,15 @@ pub fn map(ctx: *o.NativeCtx) callconv(.c) c_int { while (it.next()) |kv| { var args = [_]*const v.Value{ kv.key_ptr, kv.value_ptr }; - buzz_api.bz_call( + if (!buzz_api.bz_call( ctx.vm, closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + return -2; + } const instance = o.ObjObjectInstance.cast(ctx.vm.pop().obj()).?; const object_def = instance.type_def.resolved_type.?.ObjectInstance.of @@ -201,21 +209,25 @@ const SortContext = struct { sort_closure: v.Value, ctx: *o.NativeCtx, map: *o.ObjMap, + had_error: bool = false, - pub fn lessThan(context: SortContext, lhs_index: usize, rhs_index: usize) bool { + pub fn lessThan(context: *SortContext, lhs_index: usize, rhs_index: usize) bool { const map_keys = context.map.map.keys(); const lhs = map_keys[lhs_index]; const rhs = map_keys[rhs_index]; var args = [_]*const v.Value{ &lhs, &rhs }; - buzz_api.bz_call( + if (!buzz_api.bz_call( context.ctx.vm, context.sort_closure, @ptrCast(&args), @intCast(args.len), null, - ); + )) { + context.had_error = true; + return false; + } return context.ctx.vm.pop().boolean(); } @@ -225,13 +237,17 @@ pub fn sort(ctx: *o.NativeCtx) callconv(.c) c_int { const self = o.ObjMap.cast(ctx.vm.peek(1).obj()).?; const sort_closure = ctx.vm.peek(0); - self.map.sort( - SortContext{ - .sort_closure = sort_closure, - .ctx = ctx, - .map = self, - }, - ); + var context = SortContext{ + .sort_closure = sort_closure, + .ctx = ctx, + .map = self, + }; + self.map.sort(&context); + + if (context.had_error) { + return -2; + } + ctx.vm.gc.markObjDirty(self.toObj()) catch @panic("Out of memory"); ctx.vm.push(self.toValue()); diff --git a/src/buzz_api.zig b/src/buzz_api.zig index 1d4f5f3e..3aa19776 100644 --- a/src/buzz_api.zig +++ b/src/buzz_api.zig @@ -710,7 +710,8 @@ pub export fn bz_invoke( // If not compiled, run it with the VM loop if (!calleeIsCompiled(callee)) { - self.run(); + // TODO: catch properly + self.run() catch unreachable; } self.currentFrame().?.in_native_call = was_in_native_call; @@ -722,7 +723,7 @@ pub export fn bz_call( arguments: ?[*]const *const v.Value, len: u8, catch_value: ?*v.Value, -) callconv(.c) void { +) callconv(.c) bool { std.debug.assert(closure_value.obj().obj_type == .Closure); self.push(closure_value); @@ -731,12 +732,11 @@ pub export fn bz_call( self.push(arguments.?[i].*); } - // TODO: catch properly self.callValue( closure_value, len, if (catch_value) |val| val.* else null, - ) catch unreachable; + ) catch return false; // If not compiled, run it with the VM loop if (closure_value.obj().access( @@ -744,8 +744,12 @@ pub export fn bz_call( .Closure, self.gc, ).?.function.native == null) { - self.run(); + self.run() catch return false; + + return true; } + + return false; } export fn bz_newQualifiedObjectInstance(self: *VM, qualified_name: [*]const u8, len: usize, mutable: bool) callconv(.c) v.Value { diff --git a/src/lib/buzz_api.zig b/src/lib/buzz_api.zig index 70928272..bff73b0a 100644 --- a/src/lib/buzz_api.zig +++ b/src/lib/buzz_api.zig @@ -203,7 +203,7 @@ pub const VM = opaque { pub extern fn bz_deinitVM(self: *VM) callconv(.c) void; pub extern fn bz_panic(vm: *VM, msg: [*]const u8, len: usize) callconv(.c) void; pub extern fn bz_run(self: *VM, source: ?[*]const u8, source_len: usize, file_name: ?[*]const u8, file_name_len: usize) callconv(.c) bool; - pub extern fn bz_call(self: *VM, closure: Value, arguments: ?[*]const *const Value, len: usize, catch_value: ?*Value) callconv(.c) void; + pub extern fn bz_call(self: *VM, closure: Value, arguments: ?[*]const *const Value, len: usize, catch_value: ?*Value) callconv(.c) bool; pub extern fn bz_push(self: *VM, value: Value) callconv(.c) void; pub extern fn bz_pop(self: *VM) callconv(.c) Value; pub extern fn bz_peek(self: *VM, distance: u32) callconv(.c) Value; diff --git a/src/obj.zig b/src/obj.zig index 5c4a25e7..07dafda8 100644 --- a/src/obj.zig +++ b/src/obj.zig @@ -4463,13 +4463,10 @@ pub const ObjTypeDef = struct { break :placeholder placeholder; }, - .Generic => generic: { - if (self.resolved_type.?.Generic.origin == origin) { - break :generic generics[self.resolved_type.?.Generic.index]; - } - - break :generic self; - }, + .Generic => if (self.resolved_type.?.Generic.origin == origin and generics.len > self.resolved_type.?.Generic.index) + generics[self.resolved_type.?.Generic.index] + else + self, .Fiber => fiber: { const new_fiber_def = ObjFiber.FiberDef{ @@ -4852,12 +4849,14 @@ pub const ObjTypeDef = struct { // Link won't be made if parent already exists placeholder.resolved_type.?.Placeholder.parent = null; - try PlaceholderDef.link( - type_registry.gc.allocator, - clone.resolved_type.?.Placeholder.parent.?, - placeholder, - clone.resolved_type.?.Placeholder.parent_relation.?, - ); + if (clone.resolved_type.?.Placeholder.parent) |parent| { + try PlaceholderDef.link( + type_registry.gc.allocator, + parent, + placeholder, + clone.resolved_type.?.Placeholder.parent_relation.?, + ); + } // FIXME: this previous clone placeholder becomes useless? diff --git a/src/vm.zig b/src/vm.zig index 7b07054c..7cd0cf99 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -627,7 +627,7 @@ pub const VM = struct { // If debugging, don't run the entry point right away if (self.debugger == null or function.type_def.resolved_type.?.Function.function_type != .ScriptEntryPoint) { - self.run(); + try self.run(); } } @@ -3856,6 +3856,11 @@ pub const VM = struct { const right = self.pop(); const left = self.pop(); + if (right.integer() == 0) { + self.reportRuntimeErrorWithCurrentStack("Division by zero."); + return; + } + self.push( Value.fromInteger(@divTrunc(left.integer(), right.integer())), ); @@ -3878,6 +3883,11 @@ pub const VM = struct { const right = self.pop(); const left = self.pop(); + if (right.double() == 0) { + self.reportRuntimeErrorWithCurrentStack("Division by zero."); + return; + } + self.push( Value.fromDouble( left.double() / right.double(), @@ -3902,6 +3912,11 @@ pub const VM = struct { const right = self.pop(); const left = self.pop(); + if (right.integer() == 0) { + self.reportRuntimeErrorWithCurrentStack("Division by zero."); + return; + } + self.push( Value.fromInteger( @mod(left.integer(), right.integer()), @@ -3926,6 +3941,11 @@ pub const VM = struct { const right = self.pop(); const left = self.pop(); + if (right.double() == 0) { + self.reportRuntimeErrorWithCurrentStack("Division by zero."); + return; + } + self.push( Value.fromDouble( @mod(left.double(), right.double()), @@ -4644,7 +4664,7 @@ pub const VM = struct { ); } - pub fn run(self: *Self) void { + pub fn run(self: *Self) error{RuntimeError}!void { const next_current_frame: *CallFrame = self.currentFrame().?; const next_full_instruction = self.readInstruction(); const next_instruction: Chunk.OpCode = getCode(next_full_instruction); @@ -4674,6 +4694,10 @@ pub const VM = struct { next_instruction, next_arg, ); + + if (self.reporter.last_error != null) { + return error.RuntimeError; + } } pub fn throw(self: *Self, code: Error, payload: Value, previous_stack: ?*std.ArrayList(CallFrame), previous_error_site: ?Ast.TokenIndex) Error!void { @@ -4889,6 +4913,8 @@ pub const VM = struct { }; err_report.reportStderr(&self.reporter) catch @panic("Could not report error"); + + self.reporter.last_error = .runtime; } fn compileAndCall(self: *Self, closure: *obj.ObjClosure, arg_count: u8, catch_value: ?Value) Error!bool { @@ -5093,7 +5119,7 @@ pub const VM = struct { self.current_fiber.stack_top = self.current_fiber.stack_top - arg_count - 1; self.push(result); - } else { + } else if (native_return == -1) { // An error occured within the native function -> call error handlers if (catch_value != null) { // We discard the error @@ -5118,6 +5144,9 @@ pub const VM = struct { null, ); } + } else if (native_return == -2) { + // A non-catchable runtime error happened + return error.RuntimeError; } } diff --git a/src/zigtypes.zig b/src/zigtypes.zig index 8c675e31..be342fe2 100644 --- a/src/zigtypes.zig +++ b/src/zigtypes.zig @@ -83,7 +83,7 @@ pub const Type = union(enum) { break :uni union_size; }, - else => unreachable, + else => 0, }; } @@ -115,7 +115,7 @@ pub const Type = union(enum) { break :uni max_align; }, .Pointer => 8, - else => unreachable, + else => 1, }; } From 3b45f5d5d07a0e18aedc0e4a9d768e4bfd2cd028 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Tue, 4 Nov 2025 10:32:47 +0100 Subject: [PATCH 03/17] feat: fuzz tests --- src/behavior.zig | 172 ++++++++------- tests/fuzzed/README.txt | 14 ++ ...c:000051,time:929,execs:782,op:quick,pos:0 | 5 + ...863917,execs:18330,op:quick,pos:104,val:+1 | 6 + ...00051,time:13766,execs:1095,op:flip1,pos:1 | 5 + ...3,time:932808,execs:18686,op:flip1,pos:105 | 6 + ...00051,time:13812,execs:1096,op:flip1,pos:1 | 5 + ...3,time:934683,execs:18688,op:flip1,pos:105 | 6 + ...00051,time:15542,execs:1136,op:flip1,pos:1 | 5 + ...3,time:944955,execs:18702,op:flip1,pos:108 | 6 + ...00051,time:45178,execs:1765,op:flip2,pos:1 | 5 + ...3,time:982430,execs:18918,op:flip2,pos:105 | 6 + ...00051,time:46425,execs:1794,op:flip2,pos:1 | 5 + ...13,time:1726632,execs:23371,op:havoc,rep:4 | 6 + ...0051,time:66728,execs:2227,op:flip2,pos:66 | 5 + ...13,time:1755372,execs:23546,op:havoc,rep:2 | 6 + ...00051,time:69064,execs:2277,op:flip4,pos:1 | 5 + ...13,time:1831679,execs:24074,op:havoc,rep:4 | 6 + ...00051,time:69114,execs:2278,op:flip4,pos:1 | 5 + ...13,time:1878199,execs:24397,op:havoc,rep:1 | 6 + ...00051,time:71379,execs:2330,op:flip4,pos:4 | 5 + ...13,time:1937548,execs:24820,op:havoc,rep:2 | 6 + ...0051,time:83385,execs:2556,op:flip4,pos:49 | 5 + ...13,time:2225913,execs:26757,op:havoc,rep:4 | 6 + ...0051,time:88769,execs:2664,op:flip32,pos:3 | 5 + ...13,time:2297408,execs:27208,op:havoc,rep:1 | 6 + ...051,time:88966,execs:2669,op:flip32,pos:12 | 3 + ...817091,execs:29065,op:quick,pos:488,val:+1 | 29 +++ ...:116999,execs:3388,op:arith8,pos:12,val:+5 | 5 + ...819714,execs:29070,op:quick,pos:492,val:+1 | 29 +++ ...120257,execs:3463,op:arith8,pos:12,val:-23 | 5 + ...,time:3034101,execs:29776,op:flip1,pos:379 | 29 +++ ...126085,execs:3567,op:arith8,pos:13,val:+26 | 4 + ...,time:3036220,execs:29779,op:flip1,pos:379 | 29 +++ ...192476,execs:4807,op:arith8,pos:67,val:+23 | 5 + ...,time:3038341,execs:29782,op:flip1,pos:379 | 29 +++ ...193738,execs:4829,op:arith8,pos:67,val:+28 | 5 + ...,time:3155723,execs:30217,op:flip2,pos:379 | 29 +++ ...194012,execs:4833,op:arith8,pos:67,val:+30 | 5 + ...08,time:3677561,execs:32267,op:havoc,rep:2 | 29 +++ ...195179,execs:4854,op:arith8,pos:67,val:+35 | 5 + ...08,time:3919860,execs:33298,op:havoc,rep:1 | 27 +++ ...me:218857,execs:5246,op:int16,pos:1,val:+1 | Bin 0 -> 68 bytes ...187468,execs:38213,op:quick,pos:492,val:+6 | 29 +++ ...0051,time:304934,execs:7111,op:havoc,rep:6 | 4 + ...539582,execs:39686,op:quick,pos:251,val:+1 | 16 ++ ...051,time:317141,execs:7388,op:havoc,rep:10 | 5 + ...562885,execs:39790,op:quick,pos:330,val:+1 | 16 ++ ...051,time:317455,execs:7395,op:havoc,rep:14 | Bin 0 -> 124 bytes ...564772,execs:39792,op:quick,pos:331,val:+1 | 16 ++ ...051,time:324656,execs:7522,op:havoc,rep:11 | 8 + ...55,time:6940331,execs:46733,op:havoc,rep:1 | 16 ++ ...0051,time:341820,execs:7862,op:havoc,rep:5 | 6 + ...8384774,execs:58114,op:quick,pos:79,val:+2 | 47 +++++ ...051,time:345967,execs:7955,op:havoc,rep:16 | Bin 0 -> 92 bytes ...439302,execs:58339,op:quick,pos:255,val:+2 | 47 +++++ ...051,time:347472,execs:7988,op:havoc,rep:13 | 2 + ...492973,execs:58552,op:quick,pos:431,val:+2 | 47 +++++ ...0051,time:347609,execs:7991,op:havoc,rep:6 | Bin 0 -> 114 bytes ...557626,execs:58806,op:quick,pos:612,val:+2 | 47 +++++ ...051,time:400266,execs:9041,op:havoc,rep:14 | Bin 0 -> 88 bytes ...611425,execs:59012,op:quick,pos:781,val:+2 | 47 +++++ ...0051,time:401374,execs:9066,op:havoc,rep:9 | 6 + ...42115,execs:59845,op:quick,pos:1313,val:+2 | 47 +++++ ...051,time:408249,execs:9208,op:havoc,rep:14 | 3 + ...25,time:9590514,execs:62692,op:havoc,rep:3 | 47 +++++ ...051,time:414648,execs:9350,op:havoc,rep:10 | 7 + ...25,time:9938774,execs:64109,op:havoc,rep:3 | 46 ++++ ...0051,time:421281,execs:9487,op:havoc,rep:4 | 4 + ...5,time:10025436,execs:64464,op:havoc,rep:1 | 47 +++++ ...051,time:429246,execs:9657,op:havoc,rep:16 | Bin 0 -> 98 bytes ...time:13064132,execs:70410,op:quick,pos:868 | 79 +++++++ ...0051,time:435014,execs:9787,op:havoc,rep:6 | 3 + ...ime:13199030,execs:70941,op:quick,pos:1182 | 79 +++++++ ...051,time:458317,execs:10266,op:havoc,rep:7 | 3 + ...ime:13268403,execs:71209,op:quick,pos:1413 | 79 +++++++ ...51,time:462379,execs:10345,op:havoc,rep:15 | Bin 0 -> 100 bytes ...2,time:13686254,execs:72978,op:havoc,rep:1 | 79 +++++++ ...51,time:464531,execs:10395,op:havoc,rep:13 | Bin 0 -> 55 bytes ...2,time:14303774,execs:75567,op:havoc,rep:2 | 80 +++++++ ...051,time:475463,execs:10632,op:havoc,rep:9 | 5 + ...190307,execs:87650,op:quick,pos:152,val:+1 | 107 ++++++++++ ...51,time:486723,execs:10886,op:havoc,rep:12 | 5 + ...293232,execs:88058,op:quick,pos:391,val:+1 | 107 ++++++++++ ...051,time:487763,execs:10912,op:havoc,rep:9 | Bin 0 -> 87 bytes ...392405,execs:88430,op:quick,pos:678,val:+1 | 107 ++++++++++ ...051,time:503456,execs:11261,op:havoc,rep:4 | Bin 0 -> 107 bytes ...,time:18612333,execs:93274,op:quick,pos:96 | 80 +++++++ ...51,time:514440,execs:11517,op:havoc,rep:11 | Bin 0 -> 83 bytes ...time:18759009,execs:93868,op:quick,pos:617 | 80 +++++++ ...51,time:520847,execs:11652,op:havoc,rep:14 | 8 + ...ime:19033188,execs:94894,op:quick,pos:1522 | 80 +++++++ ...051,time:523723,execs:11720,op:havoc,rep:6 | Bin 0 -> 75 bytes ...ime:19108064,execs:95159,op:quick,pos:1774 | 80 +++++++ ...51,time:528438,execs:11825,op:havoc,rep:15 | Bin 0 -> 49 bytes ...042119,execs:98972,op:quick,pos:215,val:+4 | 43 ++++ ...51,time:547324,execs:12257,op:havoc,rep:14 | Bin 0 -> 64 bytes ...216929,execs:99679,op:quick,pos:825,val:+4 | 43 ++++ ...51,time:557798,execs:12486,op:havoc,rep:16 | Bin 0 -> 137 bytes ...92375,execs:99967,op:quick,pos:1112,val:+4 | 43 ++++ ...51,time:591401,execs:13229,op:havoc,rep:16 | Bin 0 -> 136 bytes ...16152,execs:105200,op:quick,pos:228,val:+3 | 136 ++++++++++++ ...051,time:624596,execs:13922,op:havoc,rep:6 | 4 + ...89771,execs:105475,op:quick,pos:454,val:+3 | 136 ++++++++++++ ...51,time:628015,execs:13999,op:havoc,rep:16 | 2 + ...54674,execs:105711,op:quick,pos:653,val:+3 | 136 ++++++++++++ ...51,time:638876,execs:14245,op:havoc,rep:13 | 5 + ...28271,execs:105976,op:quick,pos:869,val:+3 | 136 ++++++++++++ ...51,time:656502,execs:14649,op:havoc,rep:14 | 5 + ...1873,execs:106306,op:quick,pos:1162,val:+3 | 136 ++++++++++++ ...51,time:662089,execs:14767,op:havoc,rep:13 | 4 + ...,time:22766394,execs:109675,op:havoc,rep:2 | 136 ++++++++++++ ...459,time:709950,execs:15892,op:havoc,rep:8 | Bin 0 -> 115 bytes ...08324,execs:115372,op:quick,pos:418,val:+2 | 80 +++++++ ...459,time:737512,execs:16496,op:havoc,rep:2 | Bin 0 -> 89 bytes ...2052,execs:116487,op:quick,pos:1520,val:+2 | 80 +++++++ ...56,time:792567,execs:17714,op:havoc,rep:12 | 1 + ...6580338,execs:124145,op:quick,pos:8,val:+3 | 198 ++++++++++++++++++ ...56,time:792739,execs:17718,op:havoc,rep:11 | Bin 0 -> 79 bytes ...13047,execs:124255,op:quick,pos:105,val:+3 | 198 ++++++++++++++++++ ...3,time:1038554,execs:19208,op:flip16,pos:7 | 6 + ...38975,execs:124340,op:quick,pos:165,val:+3 | 198 ++++++++++++++++++ ...,time:1046996,execs:19259,op:flip32,pos:13 | 6 + ...60362,execs:124411,op:quick,pos:223,val:+3 | 198 ++++++++++++++++++ ...106817,execs:19778,op:arith8,pos:31,val:+5 | 6 + ...80548,execs:124482,op:quick,pos:281,val:+3 | 198 ++++++++++++++++++ ...16204,execs:19905,op:arith8,pos:32,val:+26 | 5 + ...99147,execs:124542,op:quick,pos:340,val:+3 | 198 ++++++++++++++++++ ...37862,execs:20767,op:arith8,pos:142,val:+5 | 6 + ...32156,execs:124652,op:quick,pos:413,val:+3 | 198 ++++++++++++++++++ ...13,time:2034525,execs:25498,op:havoc,rep:4 | 8 + ...49328,execs:124710,op:quick,pos:470,val:+3 | 198 ++++++++++++++++++ ...13,time:2092469,execs:25900,op:havoc,rep:1 | 6 + ...66350,execs:124771,op:quick,pos:518,val:+3 | 198 ++++++++++++++++++ ...13,time:2172493,execs:26420,op:havoc,rep:2 | 6 + ...85044,execs:124841,op:quick,pos:575,val:+3 | 198 ++++++++++++++++++ ...2538361,execs:28186,op:quick,pos:56,val:+1 | 28 +++ ...01799,execs:124902,op:quick,pos:623,val:+3 | 198 ++++++++++++++++++ ...2566540,execs:28302,op:quick,pos:81,val:+1 | 29 +++ ...28586,execs:124990,op:quick,pos:698,val:+3 | 198 ++++++++++++++++++ ...614555,execs:28454,op:quick,pos:113,val:+1 | 29 +++ ...50392,execs:125070,op:quick,pos:765,val:+3 | 198 ++++++++++++++++++ ...08,time:3510036,execs:31594,op:havoc,rep:8 | 32 +++ ...69125,execs:125130,op:quick,pos:824,val:+3 | 198 ++++++++++++++++++ ...08,time:3606862,execs:31986,op:havoc,rep:7 | 29 +++ ...97575,execs:125220,op:quick,pos:889,val:+3 | 198 ++++++++++++++++++ ...08,time:4056407,execs:33850,op:havoc,rep:3 | 29 +++ ...5312,execs:125414,op:quick,pos:1058,val:+3 | 198 ++++++++++++++++++ ...08,time:4061094,execs:33873,op:havoc,rep:4 | 29 +++ ...5803,execs:125519,op:quick,pos:1162,val:+3 | 198 ++++++++++++++++++ ...08,time:4177920,execs:34344,op:havoc,rep:5 | Bin 0 -> 582 bytes ...,time:27343581,execs:126803,op:havoc,rep:1 | 198 ++++++++++++++++++ ...08,time:4631215,execs:36218,op:havoc,rep:3 | 29 +++ ...,time:27428500,execs:127060,op:havoc,rep:2 | 198 ++++++++++++++++++ ...5407943,execs:39064,op:quick,pos:26,val:+1 | 16 ++ ...,time:27508860,execs:127320,op:havoc,rep:1 | 198 ++++++++++++++++++ ...5426024,execs:39154,op:quick,pos:44,val:+1 | 16 ++ ...,time:28280222,execs:129828,op:havoc,rep:2 | 198 ++++++++++++++++++ ...5433289,execs:39190,op:quick,pos:56,val:+1 | 16 ++ ...20594,execs:130825,op:quick,pos:320,val:+1 | 26 +++ ...459686,execs:39316,op:quick,pos:122,val:+1 | 16 ++ ...46037,execs:133312,op:quick,pos:326,val:+3 | 32 +++ ...478330,execs:39405,op:quick,pos:151,val:+1 | 16 ++ ...40727,execs:133730,op:quick,pos:712,val:+3 | 32 +++ ...520960,execs:39604,op:quick,pos:230,val:+1 | 16 ++ ...58481,execs:148166,op:quick,pos:273,val:+1 | 69 ++++++ ...521136,execs:39605,op:quick,pos:231,val:+1 | 16 ++ ...84031,execs:148255,op:quick,pos:361,val:+1 | 69 ++++++ ...536649,execs:39679,op:quick,pos:245,val:+1 | 16 ++ ...09291,execs:148343,op:quick,pos:436,val:+1 | 69 ++++++ ...552734,execs:39749,op:quick,pos:314,val:+1 | 16 ++ ...55833,execs:148502,op:quick,pos:582,val:+1 | 69 ++++++ ...5,time:5604619,execs:39983,op:flip1,pos:60 | 16 ++ ...78751,execs:148584,op:quick,pos:651,val:+1 | 69 ++++++ ...,time:5630503,execs:40108,op:flip1,pos:186 | 16 ++ ...28467,execs:148754,op:quick,pos:796,val:+1 | 69 ++++++ ...,time:5700746,execs:40445,op:flip2,pos:186 | 16 ++ ...55954,execs:148843,op:quick,pos:872,val:+1 | 69 ++++++ ...,time:5713841,execs:40506,op:flip2,pos:239 | 16 ++ ...98019,execs:148990,op:quick,pos:982,val:+1 | 69 ++++++ ...,time:5790667,execs:40876,op:flip4,pos:239 | 16 ++ ...,time:31699360,execs:151545,op:havoc,rep:1 | 68 ++++++ ...,time:5793602,execs:40890,op:flip4,pos:243 | 16 ++ ...ime:32133122,execs:152343,op:quick,pos:102 | 22 ++ ...time:5842975,execs:41125,op:flip32,pos:317 | 16 ++ ...333046,execs:158378,op:quick,pos:73,val:+2 | 27 +++ ...20917,execs:41990,op:arith8,pos:112,val:-3 | 16 ++ ...26521,execs:162046,op:quick,pos:175,val:+2 | 78 +++++++ ...9262,execs:42028,op:arith8,pos:112,val:+27 | 16 ++ ...42131,execs:162494,op:quick,pos:610,val:+2 | 78 +++++++ ...2394,execs:42043,op:arith8,pos:112,val:-35 | 16 ++ ...00862,execs:162728,op:quick,pos:819,val:+2 | 78 +++++++ ...7419,execs:42208,op:arith8,pos:127,val:+34 | 16 ++ ...2844,execs:163118,op:quick,pos:1172,val:+2 | 78 +++++++ ...0725,execs:42654,op:arith8,pos:186,val:-34 | 16 ++ ...28286,execs:169847,op:quick,pos:409,val:+2 | 50 +++++ ...55,time:6505974,execs:44419,op:havoc,rep:3 | 16 ++ ...88218,execs:170086,op:quick,pos:635,val:+2 | 50 +++++ ...55,time:6555894,execs:44698,op:havoc,rep:1 | 16 ++ ...14550,execs:170187,op:quick,pos:735,val:+2 | 50 +++++ ...55,time:6580144,execs:44831,op:havoc,rep:7 | 16 ++ ...37561,execs:170274,op:quick,pos:821,val:+2 | 50 +++++ ...55,time:6597156,execs:44919,op:havoc,rep:5 | 15 ++ ...68876,execs:173461,op:quick,pos:103,val:+1 | 15 ++ ...55,time:6648180,execs:45187,op:havoc,rep:8 | Bin 0 -> 433 bytes ...2006,execs:208056,op:quick,pos:1162,val:+2 | 136 ++++++++++++ ...55,time:6696301,execs:45445,op:havoc,rep:6 | Bin 0 -> 425 bytes ...80496,execs:212283,op:quick,pos:294,val:+1 | 40 ++++ ...55,time:6992140,execs:47011,op:havoc,rep:2 | 16 ++ ...93260,execs:226508,op:quick,pos:273,val:+2 | 69 ++++++ ...55,time:7265946,execs:48467,op:havoc,rep:5 | 16 ++ ...7851,execs:227633,op:quick,pos:1277,val:+2 | 69 ++++++ ...55,time:7281766,execs:48549,op:havoc,rep:4 | 16 ++ ...54723,execs:230519,op:quick,pos:269,val:+6 | 69 ++++++ ...459796,execs:49596,op:quick,pos:122,val:+3 | Bin 0 -> 378 bytes ...3199,execs:231555,op:quick,pos:1280,val:+6 | 69 ++++++ ...462843,execs:49625,op:quick,pos:151,val:+3 | Bin 0 -> 378 bytes ...62737,execs:243769,op:quick,pos:192,val:+3 | 40 ++++ ...474202,execs:49705,op:quick,pos:231,val:+3 | Bin 0 -> 378 bytes ...03088,execs:248698,op:quick,pos:489,val:+2 | 29 +++ ...3,time:7674377,execs:51835,op:havoc,rep:14 | Bin 0 -> 412 bytes ...09166,execs:251158,op:quick,pos:453,val:+5 | 77 +++++++ ...93,time:7678243,execs:51883,op:havoc,rep:4 | Bin 0 -> 397 bytes ...62230,execs:251363,op:quick,pos:633,val:+5 | 77 +++++++ ...93,time:7769850,execs:52921,op:havoc,rep:5 | Bin 0 -> 387 bytes ...10553,execs:251551,op:quick,pos:796,val:+5 | 77 +++++++ ...93,time:7815337,execs:53475,op:havoc,rep:3 | Bin 0 -> 379 bytes ...6622,execs:251899,op:quick,pos:1035,val:+5 | 77 +++++++ ...93,time:7830891,execs:53673,op:havoc,rep:7 | Bin 0 -> 381 bytes ...5815,execs:252532,op:quick,pos:1583,val:+5 | 77 +++++++ ...3,time:8013157,execs:55794,op:havoc,rep:15 | Bin 0 -> 411 bytes ...,time:58557878,execs:254103,op:havoc,rep:3 | 77 +++++++ ...8037100,execs:56052,op:quick,pos:23,val:+7 | Bin 0 -> 378 bytes ...,time:58726876,execs:254838,op:havoc,rep:2 | 79 +++++++ ...048681,execs:56176,op:quick,pos:123,val:+7 | Bin 0 -> 378 bytes ...25154,execs:266652,op:quick,pos:963,val:+7 | 78 +++++++ ...25,time:9269834,execs:61432,op:havoc,rep:1 | 47 +++++ ...36588,execs:269873,op:quick,pos:93,val:+11 | 65 ++++++ ...25,time:9918752,execs:64030,op:havoc,rep:2 | 47 +++++ ...time:63625401,execs:275620,op:quick,pos:82 | 65 ++++++ ...25,time:9949208,execs:64155,op:havoc,rep:1 | 46 ++++ ...ime:63664836,execs:275795,op:quick,pos:256 | 65 ++++++ ...,time:10618133,execs:65391,op:quick,pos:34 | 39 ++++ ...ime:63692320,execs:275913,op:quick,pos:373 | 65 ++++++ ...time:10729928,execs:65545,op:quick,pos:125 | 39 ++++ ...ime:63795623,execs:276360,op:quick,pos:807 | 65 ++++++ ...time:10730659,execs:65546,op:quick,pos:126 | 39 ++++ ...me:63896430,execs:276799,op:quick,pos:1161 | 65 ++++++ ...time:10733578,execs:65550,op:quick,pos:130 | 39 ++++ ...ime:66971371,execs:290741,op:quick,pos:239 | 25 +++ ...time:10771649,execs:65599,op:quick,pos:167 | 39 ++++ ...ime:66996461,execs:290854,op:quick,pos:339 | 25 +++ ...time:10878938,execs:65728,op:quick,pos:200 | 39 ++++ ...ime:68732463,execs:299979,op:quick,pos:199 | 71 +++++++ ...time:10930657,execs:65798,op:quick,pos:234 | 39 ++++ ...ime:68819907,execs:300356,op:quick,pos:575 | 71 +++++++ ...time:11132540,execs:66081,op:flip1,pos:105 | 39 ++++ ...ime:68869489,execs:300560,op:quick,pos:778 | 71 +++++++ ...042,time:12674554,execs:68759,op:inf,rep:2 | 75 +++++++ ...ime:68913805,execs:300733,op:quick,pos:938 | 71 +++++++ ...042,time:12674783,execs:68760,op:inf,rep:2 | 76 +++++++ ...me:69011117,execs:301126,op:quick,pos:1318 | 71 +++++++ ...042,time:12675014,execs:68761,op:inf,rep:2 | 77 +++++++ ...ime:72625976,execs:316629,op:quick,pos:187 | 11 + ...042,time:12691268,execs:68827,op:inf,rep:2 | 74 +++++++ ...,time:72856961,execs:317728,op:havoc,rep:9 | Bin 0 -> 370 bytes ...time:12838977,execs:69470,op:quick,pos:224 | 79 +++++++ ...ime:74481265,execs:324476,op:quick,pos:139 | 14 ++ ...time:12877414,execs:69638,op:quick,pos:289 | 79 +++++++ ...ime:74505122,execs:324579,op:quick,pos:241 | 14 ++ ...time:13102189,execs:70564,op:quick,pos:986 | 79 +++++++ ...ime:75747279,execs:329773,op:quick,pos:272 | 69 ++++++ ...ime:13150009,execs:70758,op:quick,pos:1084 | 79 +++++++ ...me:76064205,execs:330797,op:quick,pos:1283 | 69 ++++++ ...ime:13234094,execs:71080,op:quick,pos:1309 | 79 +++++++ ...ime:84717279,execs:364061,op:quick,pos:179 | 10 + ...ime:13422798,execs:71869,op:flip1,pos:1110 | 79 +++++++ ...ime:84933133,execs:364998,op:quick,pos:335 | 47 +++++ ...ime:13424527,execs:71876,op:flip1,pos:1112 | 79 +++++++ ...ime:89300118,execs:384604,op:quick,pos:148 | 19 ++ ...2,time:13700952,execs:73041,op:havoc,rep:2 | 78 +++++++ ...ime:89357369,execs:384854,op:quick,pos:385 | 19 ++ ...2,time:13733874,execs:73181,op:havoc,rep:1 | 79 +++++++ ...ime:92042894,execs:396343,op:quick,pos:271 | 69 ++++++ ...2,time:13837821,execs:73611,op:havoc,rep:2 | Bin 0 -> 1638 bytes ...ime:93070185,execs:400582,op:quick,pos:188 | 40 ++++ ...2,time:13838964,execs:73616,op:havoc,rep:1 | 79 +++++++ ...ime:94883913,execs:411509,op:quick,pos:275 | 68 ++++++ ...2,time:13845124,execs:73643,op:havoc,rep:2 | 79 +++++++ ...ime:98888502,execs:427842,op:quick,pos:486 | 29 +++ ...2,time:14025464,execs:74393,op:havoc,rep:2 | 79 +++++++ ...me:103858379,execs:448821,op:quick,pos:424 | 80 +++++++ ...2,time:14121826,execs:74794,op:havoc,rep:1 | 82 ++++++++ ...me:104657823,execs:451929,op:quick,pos:213 | 10 + ...2,time:14463265,execs:76249,op:havoc,rep:2 | 80 +++++++ ...me:112146080,execs:481926,op:quick,pos:276 | 69 ++++++ ...60059,execs:81806,op:quick,pos:1085,val:+1 | 79 +++++++ ...me:113015992,execs:485048,op:quick,pos:269 | 69 ++++++ ...60548,execs:81808,op:quick,pos:1087,val:+1 | 79 +++++++ ...e:114577936,execs:491508,op:quick,pos:1564 | 77 +++++++ ...182551,execs:87620,op:quick,pos:123,val:+1 | 107 ++++++++++ ...me:120573893,execs:513984,op:quick,pos:242 | 11 + ...217299,execs:87755,op:quick,pos:209,val:+1 | 107 ++++++++++ ...me:120642287,execs:514287,op:quick,pos:520 | 11 + ...229285,execs:87812,op:quick,pos:230,val:+1 | 107 ++++++++++ ...time:120901995,execs:515417,op:havoc,rep:2 | 11 + ...325009,execs:88181,op:quick,pos:478,val:+1 | 107 ++++++++++ ...me:121738515,execs:518760,op:quick,pos:995 | 80 +++++++ ...386339,execs:88410,op:quick,pos:659,val:+1 | 107 ++++++++++ ...ime:124016451,execs:527534,op:quick,pos:98 | 66 ++++++ ...416405,execs:88510,op:quick,pos:758,val:+1 | 107 ++++++++++ ...me:124150367,execs:528099,op:quick,pos:650 | 66 ++++++ ...34453,execs:88939,op:quick,pos:1103,val:+1 | 107 ++++++++++ ...me:126120097,execs:536761,op:quick,pos:330 | 66 ++++++ ...50174,execs:89002,op:quick,pos:1118,val:+1 | 107 ++++++++++ ...me:126273407,execs:537385,op:quick,pos:917 | 66 ++++++ ...58416,execs:89034,op:quick,pos:1150,val:+1 | 107 ++++++++++ ...me:132646048,execs:564729,op:quick,pos:144 | 28 +++ ...60428,execs:89042,op:quick,pos:1158,val:+1 | 107 ++++++++++ ...time:147926702,execs:620168,op:quick,pos:8 | 198 ++++++++++++++++++ ...20059,execs:89256,op:quick,pos:1348,val:+1 | 107 ++++++++++ ...me:151166653,execs:631064,op:quick,pos:200 | 39 ++++ ...time:17808080,execs:89986,op:flip2,pos:367 | 107 ++++++++++ ...me:151195334,execs:631178,op:quick,pos:289 | 39 ++++ ...ime:17849378,execs:90143,op:flip2,pos:1105 | 107 ++++++++++ ...me:151298817,execs:631609,op:quick,pos:671 | 39 ++++ ...time:18752646,execs:93847,op:quick,pos:597 | 80 +++++++ ...520,execs:633310,op:arith8,pos:439,val:+20 | 39 ++++ ...ime:19062258,execs:94996,op:quick,pos:1624 | 80 +++++++ ...78,execs:633895,op:arith8,pos:1177,val:+27 | 39 ++++ ...ime:19095426,execs:95116,op:quick,pos:1732 | 80 +++++++ ...me:154919895,execs:647201,op:quick,pos:145 | 107 ++++++++++ ...9996347,execs:98774,op:quick,pos:42,val:+4 | 43 ++++ ...e:155188552,execs:648170,op:quick,pos:1113 | 107 ++++++++++ ...0004883,execs:98814,op:quick,pos:82,val:+4 | 43 ++++ ...e:155429965,execs:648988,op:quick,pos:1906 | 107 ++++++++++ ...032108,execs:98934,op:quick,pos:178,val:+4 | 43 ++++ ...me:167303517,execs:690662,op:quick,pos:488 | 29 +++ ...130305,execs:99336,op:quick,pos:543,val:+4 | 43 ++++ ...me:169552579,execs:700399,op:quick,pos:361 | 69 ++++++ ...140911,execs:99379,op:quick,pos:574,val:+4 | 43 ++++ ...time:172114514,execs:710320,op:havoc,rep:4 | 14 ++ ...87093,execs:99951,op:quick,pos:1097,val:+4 | 43 ++++ ...me:172859960,execs:712036,op:quick,pos:545 | 22 ++ ...93,execs:101095,op:arith8,pos:1177,val:-14 | 43 ++++ ...me:180281587,execs:738632,op:quick,pos:111 | 41 ++++ ...43,time:21391248,execs:104731,op:inf,rep:3 | 134 ++++++++++++ ...me:180306068,execs:738725,op:quick,pos:179 | 41 ++++ ...86281,execs:105821,op:quick,pos:763,val:+3 | 136 ++++++++++++ ...e:181655026,execs:744458,op:quick,pos:1146 | 41 ++++ ...92063,execs:105842,op:quick,pos:772,val:+3 | 136 ++++++++++++ ...me:182673300,execs:748408,op:quick,pos:793 | 68 ++++++ ...4292,execs:106146,op:quick,pos:1039,val:+3 | 136 ++++++++++++ ...me:187493256,execs:772257,op:quick,pos:192 | 41 ++++ ...3689,execs:106523,op:quick,pos:1379,val:+3 | 136 ++++++++++++ ...ime:189032794,execs:779095,op:quick,pos:96 | 23 ++ ...0753,execs:106794,op:quick,pos:1638,val:+3 | 136 ++++++++++++ ...me:189421710,execs:779774,op:quick,pos:774 | 22 ++ ...5617,execs:106813,op:quick,pos:1645,val:+3 | 136 ++++++++++++ ...e:195697600,execs:801006,op:quick,pos:1056 | 198 ++++++++++++++++++ ...3559,execs:106843,op:quick,pos:1675,val:+3 | 136 ++++++++++++ ...me:198594135,execs:814057,op:quick,pos:422 | 80 +++++++ ...ime:22085529,execs:107218,op:flip2,pos:166 | 136 ++++++++++++ ...e:199075942,execs:815845,op:quick,pos:2197 | 80 +++++++ ...,time:22793575,execs:109779,op:havoc,rep:2 | Bin 0 -> 2864 bytes ...me:202248786,execs:827898,op:quick,pos:489 | 29 +++ ...,time:23096210,execs:110896,op:havoc,rep:2 | 136 ++++++++++++ ...me:202691712,execs:829235,op:quick,pos:275 | 29 +++ ...0687,execs:116699,op:quick,pos:1732,val:+2 | 80 +++++++ ...time:203941473,execs:834350,op:quick,pos:8 | 198 ++++++++++++++++++ ...6807,execs:116894,op:quick,pos:1903,val:+2 | 80 +++++++ ...e:204389712,execs:835926,op:quick,pos:1523 | 198 ++++++++++++++++++ ...3896,execs:116921,op:quick,pos:1930,val:+2 | 80 +++++++ ...me:205435280,execs:839748,op:quick,pos:270 | 69 ++++++ ...9023,execs:116978,op:quick,pos:1975,val:+2 | 80 +++++++ ...me:210967608,execs:860605,op:quick,pos:214 | 20 ++ ...62,time:26456345,execs:123726,op:inf,rep:3 | 195 +++++++++++++++++ ...me:214211283,execs:873047,op:quick,pos:164 | 96 +++++++++ ...62,time:26522012,execs:123960,op:inf,rep:3 | 195 +++++++++++++++++ ...me:214275257,execs:873288,op:quick,pos:380 | 96 +++++++++ ...,time:27533658,execs:127407,op:havoc,rep:2 | 198 ++++++++++++++++++ ...me:214362282,execs:873607,op:quick,pos:650 | 96 +++++++++ ...,time:27575102,execs:127519,op:havoc,rep:2 | 198 ++++++++++++++++++ ...e:214471338,execs:874019,op:quick,pos:1037 | 96 +++++++++ ...,time:27601964,execs:127607,op:havoc,rep:2 | 197 +++++++++++++++++ ...e:214562447,execs:874357,op:quick,pos:1350 | 96 +++++++++ ...,time:27613589,execs:127646,op:havoc,rep:2 | 198 ++++++++++++++++++ ...ime:216472182,execs:880398,op:quick,pos:95 | 22 ++ ...,time:27670992,execs:127846,op:havoc,rep:1 | 198 ++++++++++++++++++ ...,time:27946896,execs:128742,op:havoc,rep:1 | 198 ++++++++++++++++++ ...,time:28222078,execs:129633,op:havoc,rep:2 | 198 ++++++++++++++++++ ...08916,execs:130776,op:quick,pos:272,val:+1 | Bin 0 -> 621 bytes ...87620,execs:131137,op:quick,pos:620,val:+1 | 26 +++ ...77210,execs:133450,op:quick,pos:452,val:+3 | 32 +++ ...7323,execs:135059,op:arith8,pos:13,val:+26 | 4 + ...time:29407430,execs:135235,op:havoc,rep:13 | Bin 0 -> 66 bytes ...time:29420002,execs:135521,op:havoc,rep:15 | Bin 0 -> 99 bytes ...time:29420590,execs:135536,op:havoc,rep:13 | 4 + ...,time:29450311,execs:136209,op:havoc,rep:9 | Bin 0 -> 72 bytes ...time:29492045,execs:137161,op:havoc,rep:10 | Bin 0 -> 68 bytes ...time:29503454,execs:137426,op:havoc,rep:12 | 5 + ...time:29522839,execs:137871,op:havoc,rep:14 | Bin 0 -> 82 bytes ...time:29549985,execs:138505,op:havoc,rep:10 | 6 + ...6,time:29630501,execs:139797,op:inf,rep:12 | 50 +++++ ...6,time:29630595,execs:139798,op:inf,rep:12 | 50 +++++ ...time:29775683,execs:141256,op:flip1,pos:69 | 56 +++++ ...611700,execs:147988,op:quick,pos:96,val:+1 | 69 ++++++ ...39923,execs:148098,op:quick,pos:206,val:+1 | 69 ++++++ ...06654,execs:148338,op:quick,pos:432,val:+1 | 69 ++++++ ...29033,execs:148412,op:quick,pos:505,val:+1 | 69 ++++++ ...75865,execs:148578,op:quick,pos:646,val:+1 | 69 ++++++ ...80180,execs:148928,op:quick,pos:945,val:+1 | 69 ++++++ ...93991,execs:148980,op:quick,pos:973,val:+1 | 69 ++++++ ...8067,execs:149571,op:quick,pos:1167,val:+1 | 69 ++++++ ...7331,execs:149663,op:quick,pos:1187,val:+1 | 69 ++++++ ...3468,execs:149681,op:quick,pos:1193,val:+1 | 69 ++++++ ...4081,execs:149683,op:quick,pos:1195,val:+1 | 69 ++++++ ...,time:33486227,execs:154769,op:havoc,rep:1 | 22 ++ ...,time:33501291,execs:154794,op:havoc,rep:2 | 22 ++ ...,time:33514023,execs:154818,op:havoc,rep:1 | 22 ++ ...14892,execs:158766,op:quick,pos:413,val:+2 | 27 +++ ...427,execs:159728,op:arith8,pos:420,val:+13 | 27 +++ ...21548,execs:162414,op:quick,pos:543,val:+2 | 78 +++++++ ...8948,execs:163029,op:quick,pos:1084,val:+2 | 78 +++++++ ...me:36540958,execs:163656,op:flip16,pos:955 | 78 +++++++ ...63,time:37170525,execs:166260,op:inf,rep:2 | 74 +++++++ ...63086,execs:169564,op:quick,pos:151,val:+2 | 50 +++++ ...68237,execs:169589,op:quick,pos:176,val:+2 | 50 +++++ ...81668,execs:169650,op:quick,pos:237,val:+2 | 50 +++++ ...83850,execs:169661,op:quick,pos:248,val:+2 | 50 +++++ ...85373,execs:169668,op:quick,pos:255,val:+2 | 50 +++++ ...42666,execs:177607,op:quick,pos:410,val:+4 | 15 ++ ...,time:39870522,execs:179236,op:havoc,rep:4 | Bin 0 -> 172 bytes ...6704,execs:182234,op:quick,pos:1361,val:+4 | 68 ++++++ ...10,time:45661354,execs:195188,op:inf,rep:7 | 103 +++++++++ ...32030,execs:198251,op:quick,pos:106,val:+6 | 12 ++ ...2938,execs:213759,op:arith8,pos:362,val:+5 | 40 ++++ ...879,execs:214311,op:arith8,pos:683,val:+26 | 39 ++++ ...095,execs:214478,op:arith8,pos:781,val:+26 | 39 ++++ ...59348,execs:222520,op:quick,pos:198,val:+2 | 198 ++++++++++++++++++ ...8593,execs:227532,op:quick,pos:1189,val:+2 | 69 ++++++ ...2507,execs:227545,op:quick,pos:1202,val:+2 | 68 ++++++ ...me:52882604,execs:228188,op:flip1,pos:1167 | 69 ++++++ ...me:52922773,execs:228312,op:flip2,pos:1187 | 69 ++++++ ...me:52953605,execs:228408,op:flip4,pos:1167 | 69 ++++++ ...99,execs:229022,op:arith8,pos:1187,val:-10 | 69 ++++++ ...6593,execs:231465,op:quick,pos:1191,val:+6 | 68 ++++++ ...9997,execs:231476,op:quick,pos:1202,val:+6 | 68 ++++++ ...,time:54426132,execs:233561,op:havoc,rep:1 | 69 ++++++ ...10724,execs:235381,op:quick,pos:122,val:+4 | 12 ++ ...time:54885789,execs:235917,op:flip32,pos:3 | Bin 0 -> 48 bytes ...time:54897658,execs:236191,op:havoc,rep:15 | 1 + ...time:54915177,execs:236611,op:havoc,rep:14 | 1 + ...time:54918057,execs:236681,op:havoc,rep:16 | 1 + ...time:54926618,execs:236882,op:havoc,rep:14 | 1 + ...time:54942338,execs:237257,op:havoc,rep:15 | 3 + ...time:54965944,execs:237841,op:havoc,rep:15 | Bin 0 -> 55 bytes ...,time:55034933,execs:239470,op:havoc,rep:5 | 1 + ...time:55084384,execs:240661,op:havoc,rep:10 | Bin 0 -> 33 bytes ...time:55102023,execs:241087,op:havoc,rep:12 | Bin 0 -> 68 bytes ...097,execs:244791,op:arith8,pos:468,val:+26 | 39 ++++ ...32300,execs:248805,op:quick,pos:596,val:+2 | 29 +++ ...32,time:57646435,execs:250539,op:inf,rep:5 | 76 +++++++ ...00615,execs:251516,op:quick,pos:762,val:+5 | 77 +++++++ ...0994,execs:252235,op:quick,pos:1347,val:+5 | 77 +++++++ ...,time:58572284,execs:254163,op:havoc,rep:3 | Bin 0 -> 2346 bytes ...,time:58585555,execs:254223,op:havoc,rep:2 | 77 +++++++ ...,time:58663945,execs:254571,op:havoc,rep:2 | 77 +++++++ ...,time:58681715,execs:254650,op:havoc,rep:4 | Bin 0 -> 2346 bytes ...,time:58977780,execs:255922,op:havoc,rep:4 | Bin 0 -> 2346 bytes ...,time:59042763,execs:256202,op:havoc,rep:4 | 77 +++++++ ...,time:59124537,execs:256553,op:havoc,rep:2 | 77 +++++++ ...,time:59235059,execs:257029,op:havoc,rep:1 | 77 +++++++ ...,time:59358971,execs:257542,op:havoc,rep:1 | 75 +++++++ ...,time:59479191,execs:258032,op:havoc,rep:2 | Bin 0 -> 2352 bytes ...90,time:60321735,execs:261733,op:inf,rep:1 | 77 +++++++ ...,time:61063439,execs:264478,op:havoc,rep:7 | Bin 0 -> 2362 bytes ...4115,execs:267045,op:quick,pos:1356,val:+7 | 77 +++++++ ...9041,execs:270064,op:quick,pos:265,val:+11 | 65 ++++++ ...8218,execs:270152,op:quick,pos:341,val:+11 | 65 ++++++ ...89,execs:277373,op:arith8,pos:1097,val:+28 | 64 ++++++ ...,time:64274306,execs:278459,op:havoc,rep:2 | 65 ++++++ ...ime:66983681,execs:290801,op:quick,pos:299 | 25 +++ ...ime:67514570,execs:293548,op:quick,pos:111 | 24 +++ ...ime:68762636,execs:300111,op:quick,pos:331 | 71 +++++++ ...ime:68893120,execs:300650,op:quick,pos:868 | 71 +++++++ ...me:68994477,execs:301064,op:quick,pos:1257 | 71 +++++++ ...time:71705596,execs:312341,op:quick,pos:62 | Bin 0 -> 948 bytes ...382,execs:315245,op:arith8,pos:458,val:+28 | 25 +++ ...ime:72638050,execs:316690,op:quick,pos:248 | 11 + ...4520,execs:317104,op:arith8,pos:137,val:+5 | 11 + ...81,time:73193810,execs:319768,op:inf,rep:4 | 72 +++++++ ...me:74415488,execs:324164,op:quick,pos:1683 | 107 ++++++++++ ...time:74464538,execs:324402,op:quick,pos:78 | 14 ++ ...me:76032260,execs:330699,op:quick,pos:1186 | 69 ++++++ ...me:76033152,execs:330702,op:quick,pos:1189 | 69 ++++++ ...me:76033415,execs:330703,op:quick,pos:1190 | 69 ++++++ ...me:76038104,execs:330717,op:quick,pos:1204 | 69 ++++++ ...1093,execs:331567,op:arith8,pos:827,val:+5 | 69 ++++++ ...ime:79400261,execs:342468,op:quick,pos:232 | 79 +++++++ ...me:83462475,execs:359210,op:quick,pos:1361 | 69 ++++++ ...time:84869130,execs:364710,op:quick,pos:60 | 47 +++++ ...ime:84908720,execs:364893,op:quick,pos:231 | 47 +++++ ...ime:84983967,execs:365215,op:quick,pos:552 | 46 ++++ ...,time:86923124,execs:373881,op:havoc,rep:2 | 17 ++ ...ime:87910948,execs:378156,op:quick,pos:290 | 79 +++++++ ...me:88382776,execs:380377,op:flip32,pos:291 | 18 ++ ...762,execs:380418,op:arith8,pos:291,val:-27 | 18 ++ ...ime:89328446,execs:384726,op:quick,pos:270 | 19 ++ ...me:90703853,execs:390606,op:quick,pos:1260 | 69 ++++++ ...,time:90997899,execs:391555,op:havoc,rep:5 | 69 ++++++ ...me:92303472,execs:397259,op:quick,pos:1187 | 69 ++++++ ...094,execs:401419,op:arith8,pos:464,val:+26 | 39 ++++ ...time:94833516,execs:411321,op:quick,pos:88 | 68 ++++++ ...,time:95632731,execs:413985,op:havoc,rep:3 | 73 +++++++ ...me:97688567,execs:423495,op:quick,pos:1361 | 69 ++++++ ...ime:98745206,execs:427456,op:quick,pos:113 | 29 +++ ...ime:99732791,execs:431227,op:quick,pos:510 | 45 ++++ ...ime:99796047,execs:431508,op:quick,pos:779 | 45 ++++ ...e:100748507,execs:435529,op:quick,pos:1115 | 79 +++++++ ...e:100811010,execs:435723,op:quick,pos:1309 | 79 +++++++ ...me:104654402,execs:451921,op:quick,pos:206 | 10 + ...time:104943562,execs:452954,op:havoc,rep:1 | 10 + ...e:105717054,execs:455456,op:quick,pos:1260 | 69 ++++++ ...11,execs:477593,op:arith8,pos:1166,val:+14 | 68 ++++++ ...e:111703982,execs:480343,op:quick,pos:1362 | 68 ++++++ ...e:111742104,execs:480469,op:quick,pos:1488 | 68 ++++++ ...me:112340414,execs:482618,op:quick,pos:956 | 69 ++++++ ...e:112413712,execs:482862,op:quick,pos:1188 | 69 ++++++ ...me:113043394,execs:485148,op:quick,pos:357 | 69 ++++++ ...e:114693274,execs:491945,op:quick,pos:2001 | 77 +++++++ ...e:114757430,execs:492186,op:quick,pos:2242 | 77 +++++++ ...:114778052,execs:492262,op:flip32,pos:2243 | 77 +++++++ ...ime:114828037,execs:492473,op:havoc,rep:13 | Bin 0 -> 2333 bytes ...ime:114839245,execs:492527,op:havoc,rep:10 | 78 +++++++ ...e:116648763,execs:499499,op:quick,pos:1260 | 69 ++++++ ...e:119774513,execs:510315,op:quick,pos:1274 | 66 ++++++ ...,time:120510785,execs:513697,op:inf,rep:11 | 10 + ...,time:120513847,execs:513711,op:inf,rep:11 | 10 + ...me:121066290,execs:516173,op:quick,pos:187 | 16 ++ ...e:122760443,execs:522183,op:quick,pos:1361 | 68 ++++++ ...e:123625396,execs:525714,op:quick,pos:1415 | 61 ++++++ ...9386,execs:526124,op:arith8,pos:414,val:+5 | 61 ++++++ ...ime:124013546,execs:527527,op:quick,pos:92 | 66 ++++++ ...me:124136371,execs:528043,op:quick,pos:595 | 66 ++++++ ...me:124145431,execs:528083,op:quick,pos:635 | 66 ++++++ ...me:124161290,execs:528144,op:quick,pos:695 | 66 ++++++ ...me:124192242,execs:528270,op:quick,pos:821 | 66 ++++++ ...e:124237297,execs:528463,op:quick,pos:1002 | 66 ++++++ ...e:124279900,execs:528642,op:quick,pos:1169 | 66 ++++++ ...me:124784112,execs:530854,op:quick,pos:395 | 66 ++++++ ...ime:126023882,execs:536351,op:quick,pos:53 | 66 ++++++ ...me:126078535,execs:536579,op:quick,pos:221 | 66 ++++++ ...me:126145735,execs:536866,op:quick,pos:435 | 66 ++++++ ...me:126220134,execs:537174,op:quick,pos:731 | 66 ++++++ ...e:126297966,execs:537481,op:quick,pos:1013 | 66 ++++++ ...e:126378354,execs:537804,op:quick,pos:1324 | 66 ++++++ ...me:126459384,execs:538148,op:flip2,pos:633 | 66 ++++++ ...me:129546242,execs:551523,op:quick,pos:395 | 79 +++++++ ...time:130658572,execs:556311,op:havoc,rep:4 | 11 + ...e:131750132,execs:560931,op:quick,pos:1345 | 79 +++++++ ...me:132660299,execs:564792,op:quick,pos:207 | 28 +++ ...e:134817591,execs:570429,op:quick,pos:1260 | 69 ++++++ ...e:136486905,execs:576825,op:quick,pos:1260 | 69 ++++++ ...e:138068601,execs:583673,op:quick,pos:1856 | 77 +++++++ ...e:138112253,execs:583835,op:quick,pos:2018 | 77 +++++++ ...time:138188207,execs:584123,op:quick,pos:2 | 3 + ...e:138994940,execs:587182,op:quick,pos:1189 | 65 ++++++ ...e:139000332,execs:587197,op:quick,pos:1204 | 65 ++++++ ...me:140305450,execs:592573,op:quick,pos:856 | 66 ++++++ ...e:140402542,execs:592943,op:quick,pos:1226 | 66 ++++++ ...me:141285424,execs:596810,op:quick,pos:413 | 26 +++ ...me:141307178,execs:596896,op:quick,pos:499 | 26 +++ ...6,time:142070148,execs:600480,op:inf,rep:3 | 46 ++++ ...me:142136589,execs:600758,op:quick,pos:241 | 50 +++++ ...e:142357467,execs:601586,op:quick,pos:1045 | 50 +++++ ...ime:142624841,execs:602729,op:quick,pos:58 | 19 ++ ...me:143526968,execs:604368,op:quick,pos:542 | 39 ++++ ...1,time:144228542,execs:606645,op:inf,rep:2 | 135 ++++++++++++ ...e:144703637,execs:608378,op:quick,pos:1707 | 136 ++++++++++++ ...e:146592309,execs:616204,op:quick,pos:1378 | 136 ++++++++++++ ...e:150616543,execs:629065,op:quick,pos:1361 | 69 ++++++ ...me:151244497,execs:631388,op:quick,pos:487 | 39 ++++ ...me:151507726,execs:632383,op:flip1,pos:107 | 39 ++++ ...time:152669967,execs:637308,op:havoc,rep:1 | 39 ++++ ...me:153376684,execs:640072,op:quick,pos:292 | 15 ++ ...e:155189306,execs:648173,op:quick,pos:1116 | 107 ++++++++++ ...e:155207778,execs:648242,op:quick,pos:1173 | 107 ++++++++++ ...e:155257724,execs:648416,op:quick,pos:1347 | 107 ++++++++++ ...e:157391485,execs:657110,op:quick,pos:1260 | 69 ++++++ ...,time:158098880,execs:659084,op:inf,rep:14 | 77 +++++++ ...e:159900099,execs:665196,op:quick,pos:1330 | 68 ++++++ ...e:161148628,execs:669334,op:quick,pos:1266 | 66 ++++++ ...e:162701538,execs:674554,op:quick,pos:1361 | 69 ++++++ ...time:163620812,execs:677989,op:havoc,rep:2 | 39 ++++ ...e:164057626,execs:679854,op:quick,pos:1141 | 39 ++++ ...1427,execs:680152,op:arith8,pos:490,val:-3 | 39 ++++ ...2603,execs:680156,op:arith8,pos:490,val:-6 | 39 ++++ ...e:169803629,execs:701244,op:quick,pos:1206 | 69 ++++++ ...e:170873964,execs:705329,op:quick,pos:1260 | 69 ++++++ ...e:174459313,execs:716841,op:quick,pos:1292 | 66 ++++++ ...e:177187920,execs:729142,op:quick,pos:1393 | 65 ++++++ ...e:178244890,execs:732799,op:quick,pos:1260 | 69 ++++++ ...me:180296864,execs:738689,op:quick,pos:168 | 41 ++++ ...me:180342705,execs:738873,op:quick,pos:327 | 41 ++++ ...e:180550642,execs:739707,op:quick,pos:1077 | 41 ++++ ...e:180628496,execs:740022,op:flip1,pos:1076 | 41 ++++ ...me:181476520,execs:743732,op:quick,pos:445 | 41 ++++ ...e:181637390,execs:744389,op:quick,pos:1078 | 41 ++++ ...e:182796544,execs:748803,op:quick,pos:1188 | 68 ++++++ ...e:183943666,execs:753180,op:quick,pos:1474 | 107 ++++++++++ ...me:185380055,execs:759046,op:quick,pos:874 | 77 +++++++ ...time:185947638,execs:762936,op:havoc,rep:6 | 2 + ...time:185958855,execs:763200,op:havoc,rep:6 | 3 + ...time:185965568,execs:763363,op:havoc,rep:5 | 2 + ...e:186911538,execs:770090,op:quick,pos:1260 | 69 ++++++ ...491,execs:773131,op:arith8,pos:468,val:+26 | 39 ++++ ...time:190089968,execs:782430,op:havoc,rep:3 | Bin 0 -> 491 bytes ...me:190794291,execs:785175,op:quick,pos:479 | 39 ++++ ...e:191082029,execs:785861,op:quick,pos:1141 | 39 ++++ ...time:191163494,execs:786074,op:havoc,rep:2 | 1 + ...time:194971765,execs:798509,op:havoc,rep:8 | 6 + ...5,time:195386382,execs:799905,op:inf,rep:7 | 195 +++++++++++++++++ ...868,execs:802454,op:arith8,pos:1724,val:+5 | 198 ++++++++++++++++++ ...4718,execs:807322,op:quick,pos:1260,val:+5 | 69 ++++++ ...e:199030599,execs:815681,op:quick,pos:2046 | 80 +++++++ ...e:200437006,execs:821734,op:quick,pos:1361 | 69 ++++++ ...e:201357285,execs:824741,op:quick,pos:1391 | 73 +++++++ ...ime:201706085,execs:825883,op:quick,pos:25 | 26 +++ ...4530,execs:828228,op:arith8,pos:276,val:-1 | 29 +++ ...e:204369834,execs:835857,op:quick,pos:1455 | 198 ++++++++++++++++++ ...ime:204828758,execs:837480,op:quick,pos:24 | 16 ++ ...e:208242945,execs:849859,op:quick,pos:1289 | 73 +++++++ ...e:209225042,execs:854084,op:quick,pos:1203 | 69 ++++++ ...e:210343357,execs:857721,op:quick,pos:1260 | 68 ++++++ ...me:210997661,execs:860745,op:quick,pos:354 | 20 ++ ...e:213386640,execs:870338,op:quick,pos:1166 | 69 ++++++ ...e:213422391,execs:870432,op:quick,pos:1260 | 69 ++++++ ...e:214461874,execs:873986,op:quick,pos:1005 | 96 +++++++++ ...e:214570605,execs:874386,op:quick,pos:1379 | 96 +++++++++ ...1159,execs:879003,op:quick,pos:1804,val:+7 | 96 +++++++++ ...4009,execs:879173,op:quick,pos:1974,val:+7 | 96 +++++++++ ...e:215979354,execs:879333,op:flip32,pos:155 | 96 +++++++++ ...e:219216696,execs:890847,op:quick,pos:1260 | 68 ++++++ ...ime:220362784,execs:895852,op:quick,pos:47 | 27 +++ ...ime:220369367,execs:895883,op:quick,pos:54 | 27 +++ ...ime:220370374,execs:895888,op:quick,pos:59 | 27 +++ ...me:220494544,execs:896448,op:flip1,pos:132 | 27 +++ ...me:220510164,execs:896521,op:flip2,pos:347 | 27 +++ ...ime:221247072,execs:900392,op:quick,pos:60 | 27 +++ ...time:221475319,execs:901376,op:havoc,rep:1 | 27 +++ ...e:223576476,execs:909947,op:quick,pos:1260 | 69 ++++++ 652 files changed, 36254 insertions(+), 88 deletions(-) create mode 100644 tests/fuzzed/README.txt create mode 100644 tests/fuzzed/id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0 create mode 100644 tests/fuzzed/id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1 create mode 100644 tests/fuzzed/id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1 create mode 100644 tests/fuzzed/id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105 create mode 100644 tests/fuzzed/id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1 create mode 100644 tests/fuzzed/id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105 create mode 100644 tests/fuzzed/id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1 create mode 100644 tests/fuzzed/id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108 create mode 100644 tests/fuzzed/id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1 create mode 100644 tests/fuzzed/id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105 create mode 100644 tests/fuzzed/id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1 create mode 100644 tests/fuzzed/id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66 create mode 100644 tests/fuzzed/id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1 create mode 100644 tests/fuzzed/id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1 create mode 100644 tests/fuzzed/id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4 create mode 100644 tests/fuzzed/id:000009,src:000013,time:1937548,execs:24820,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000010,sig:06,src:000051,time:83385,execs:2556,op:flip4,pos:49 create mode 100644 tests/fuzzed/id:000010,src:000013,time:2225913,execs:26757,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000011,sig:06,src:000051,time:88769,execs:2664,op:flip32,pos:3 create mode 100644 tests/fuzzed/id:000011,src:000013,time:2297408,execs:27208,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000012,sig:06,src:000051,time:88966,execs:2669,op:flip32,pos:12 create mode 100644 tests/fuzzed/id:000012,src:000008,time:2817091,execs:29065,op:quick,pos:488,val:+1 create mode 100644 tests/fuzzed/id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5 create mode 100644 tests/fuzzed/id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1 create mode 100644 tests/fuzzed/id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23 create mode 100644 tests/fuzzed/id:000014,src:000008,time:3034101,execs:29776,op:flip1,pos:379 create mode 100644 tests/fuzzed/id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26 create mode 100644 tests/fuzzed/id:000015,src:000008,time:3036220,execs:29779,op:flip1,pos:379 create mode 100644 tests/fuzzed/id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23 create mode 100644 tests/fuzzed/id:000016,src:000008,time:3038341,execs:29782,op:flip1,pos:379 create mode 100644 tests/fuzzed/id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28 create mode 100644 tests/fuzzed/id:000017,src:000008,time:3155723,execs:30217,op:flip2,pos:379 create mode 100644 tests/fuzzed/id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30 create mode 100644 tests/fuzzed/id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35 create mode 100644 tests/fuzzed/id:000019,src:000008,time:3919860,execs:33298,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1 create mode 100644 tests/fuzzed/id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6 create mode 100644 tests/fuzzed/id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6 create mode 100644 tests/fuzzed/id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1 create mode 100644 tests/fuzzed/id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10 create mode 100644 tests/fuzzed/id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1 create mode 100644 tests/fuzzed/id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1 create mode 100644 tests/fuzzed/id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11 create mode 100644 tests/fuzzed/id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5 create mode 100644 tests/fuzzed/id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2 create mode 100644 tests/fuzzed/id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16 create mode 100644 tests/fuzzed/id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2 create mode 100644 tests/fuzzed/id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13 create mode 100644 tests/fuzzed/id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2 create mode 100644 tests/fuzzed/id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6 create mode 100644 tests/fuzzed/id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2 create mode 100644 tests/fuzzed/id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2 create mode 100644 tests/fuzzed/id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9 create mode 100644 tests/fuzzed/id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2 create mode 100644 tests/fuzzed/id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10 create mode 100644 tests/fuzzed/id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16 create mode 100644 tests/fuzzed/id:000034,src:000042,time:13064132,execs:70410,op:quick,pos:868 create mode 100644 tests/fuzzed/id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6 create mode 100644 tests/fuzzed/id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182 create mode 100644 tests/fuzzed/id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7 create mode 100644 tests/fuzzed/id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413 create mode 100644 tests/fuzzed/id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15 create mode 100644 tests/fuzzed/id:000037,src:000042,time:13686254,execs:72978,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13 create mode 100644 tests/fuzzed/id:000038,src:000042,time:14303774,execs:75567,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9 create mode 100644 tests/fuzzed/id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1 create mode 100644 tests/fuzzed/id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12 create mode 100644 tests/fuzzed/id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1 create mode 100644 tests/fuzzed/id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9 create mode 100644 tests/fuzzed/id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1 create mode 100644 tests/fuzzed/id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96 create mode 100644 tests/fuzzed/id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11 create mode 100644 tests/fuzzed/id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617 create mode 100644 tests/fuzzed/id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000044,src:000003,time:19033188,execs:94894,op:quick,pos:1522 create mode 100644 tests/fuzzed/id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6 create mode 100644 tests/fuzzed/id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774 create mode 100644 tests/fuzzed/id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15 create mode 100644 tests/fuzzed/id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4 create mode 100644 tests/fuzzed/id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4 create mode 100644 tests/fuzzed/id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16 create mode 100644 tests/fuzzed/id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4 create mode 100644 tests/fuzzed/id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16 create mode 100644 tests/fuzzed/id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3 create mode 100644 tests/fuzzed/id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6 create mode 100644 tests/fuzzed/id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3 create mode 100644 tests/fuzzed/id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16 create mode 100644 tests/fuzzed/id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3 create mode 100644 tests/fuzzed/id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13 create mode 100644 tests/fuzzed/id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3 create mode 100644 tests/fuzzed/id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3 create mode 100644 tests/fuzzed/id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13 create mode 100644 tests/fuzzed/id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8 create mode 100644 tests/fuzzed/id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2 create mode 100644 tests/fuzzed/id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2 create mode 100644 tests/fuzzed/id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12 create mode 100644 tests/fuzzed/id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3 create mode 100644 tests/fuzzed/id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11 create mode 100644 tests/fuzzed/id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3 create mode 100644 tests/fuzzed/id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7 create mode 100644 tests/fuzzed/id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3 create mode 100644 tests/fuzzed/id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13 create mode 100644 tests/fuzzed/id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3 create mode 100644 tests/fuzzed/id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5 create mode 100644 tests/fuzzed/id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3 create mode 100644 tests/fuzzed/id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26 create mode 100644 tests/fuzzed/id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3 create mode 100644 tests/fuzzed/id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5 create mode 100644 tests/fuzzed/id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3 create mode 100644 tests/fuzzed/id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3 create mode 100644 tests/fuzzed/id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3 create mode 100644 tests/fuzzed/id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3 create mode 100644 tests/fuzzed/id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1 create mode 100644 tests/fuzzed/id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3 create mode 100644 tests/fuzzed/id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1 create mode 100644 tests/fuzzed/id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3 create mode 100644 tests/fuzzed/id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1 create mode 100644 tests/fuzzed/id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3 create mode 100644 tests/fuzzed/id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8 create mode 100644 tests/fuzzed/id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3 create mode 100644 tests/fuzzed/id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7 create mode 100644 tests/fuzzed/id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3 create mode 100644 tests/fuzzed/id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3 create mode 100644 tests/fuzzed/id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3 create mode 100644 tests/fuzzed/id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5 create mode 100644 tests/fuzzed/id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1 create mode 100644 tests/fuzzed/id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1 create mode 100644 tests/fuzzed/id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1 create mode 100644 tests/fuzzed/id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1 create mode 100644 tests/fuzzed/id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1 create mode 100644 tests/fuzzed/id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3 create mode 100644 tests/fuzzed/id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1 create mode 100644 tests/fuzzed/id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3 create mode 100644 tests/fuzzed/id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1 create mode 100644 tests/fuzzed/id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1 create mode 100644 tests/fuzzed/id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1 create mode 100644 tests/fuzzed/id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1 create mode 100644 tests/fuzzed/id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1 create mode 100644 tests/fuzzed/id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1 create mode 100644 tests/fuzzed/id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1 create mode 100644 tests/fuzzed/id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1 create mode 100644 tests/fuzzed/id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60 create mode 100644 tests/fuzzed/id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1 create mode 100644 tests/fuzzed/id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186 create mode 100644 tests/fuzzed/id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1 create mode 100644 tests/fuzzed/id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186 create mode 100644 tests/fuzzed/id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1 create mode 100644 tests/fuzzed/id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239 create mode 100644 tests/fuzzed/id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1 create mode 100644 tests/fuzzed/id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239 create mode 100644 tests/fuzzed/id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243 create mode 100644 tests/fuzzed/id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102 create mode 100644 tests/fuzzed/id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317 create mode 100644 tests/fuzzed/id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2 create mode 100644 tests/fuzzed/id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3 create mode 100644 tests/fuzzed/id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2 create mode 100644 tests/fuzzed/id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27 create mode 100644 tests/fuzzed/id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2 create mode 100644 tests/fuzzed/id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35 create mode 100644 tests/fuzzed/id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2 create mode 100644 tests/fuzzed/id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34 create mode 100644 tests/fuzzed/id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2 create mode 100644 tests/fuzzed/id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34 create mode 100644 tests/fuzzed/id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2 create mode 100644 tests/fuzzed/id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2 create mode 100644 tests/fuzzed/id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2 create mode 100644 tests/fuzzed/id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7 create mode 100644 tests/fuzzed/id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2 create mode 100644 tests/fuzzed/id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5 create mode 100644 tests/fuzzed/id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1 create mode 100644 tests/fuzzed/id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8 create mode 100644 tests/fuzzed/id:000101,src:001614,time:48112006,execs:208056,op:quick,pos:1162,val:+2 create mode 100644 tests/fuzzed/id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6 create mode 100644 tests/fuzzed/id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1 create mode 100644 tests/fuzzed/id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2 create mode 100644 tests/fuzzed/id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5 create mode 100644 tests/fuzzed/id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2 create mode 100644 tests/fuzzed/id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6 create mode 100644 tests/fuzzed/id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3 create mode 100644 tests/fuzzed/id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6 create mode 100644 tests/fuzzed/id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3 create mode 100644 tests/fuzzed/id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3 create mode 100644 tests/fuzzed/id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3 create mode 100644 tests/fuzzed/id:000108,src:000737,time:57203088,execs:248698,op:quick,pos:489,val:+2 create mode 100644 tests/fuzzed/id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000109,src:000032,time:57809166,execs:251158,op:quick,pos:453,val:+5 create mode 100644 tests/fuzzed/id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5 create mode 100644 tests/fuzzed/id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5 create mode 100644 tests/fuzzed/id:000111,src:000032,time:57910553,execs:251551,op:quick,pos:796,val:+5 create mode 100644 tests/fuzzed/id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000112,src:000032,time:57996622,execs:251899,op:quick,pos:1035,val:+5 create mode 100644 tests/fuzzed/id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7 create mode 100644 tests/fuzzed/id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5 create mode 100644 tests/fuzzed/id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15 create mode 100644 tests/fuzzed/id:000114,src:000032,time:58557878,execs:254103,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7 create mode 100644 tests/fuzzed/id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7 create mode 100644 tests/fuzzed/id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7 create mode 100644 tests/fuzzed/id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11 create mode 100644 tests/fuzzed/id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82 create mode 100644 tests/fuzzed/id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256 create mode 100644 tests/fuzzed/id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34 create mode 100644 tests/fuzzed/id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373 create mode 100644 tests/fuzzed/id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125 create mode 100644 tests/fuzzed/id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807 create mode 100644 tests/fuzzed/id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126 create mode 100644 tests/fuzzed/id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161 create mode 100644 tests/fuzzed/id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130 create mode 100644 tests/fuzzed/id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239 create mode 100644 tests/fuzzed/id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167 create mode 100644 tests/fuzzed/id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339 create mode 100644 tests/fuzzed/id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200 create mode 100644 tests/fuzzed/id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199 create mode 100644 tests/fuzzed/id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234 create mode 100644 tests/fuzzed/id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575 create mode 100644 tests/fuzzed/id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105 create mode 100644 tests/fuzzed/id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778 create mode 100644 tests/fuzzed/id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2 create mode 100644 tests/fuzzed/id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938 create mode 100644 tests/fuzzed/id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2 create mode 100644 tests/fuzzed/id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318 create mode 100644 tests/fuzzed/id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2 create mode 100644 tests/fuzzed/id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187 create mode 100644 tests/fuzzed/id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2 create mode 100644 tests/fuzzed/id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9 create mode 100644 tests/fuzzed/id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224 create mode 100644 tests/fuzzed/id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139 create mode 100644 tests/fuzzed/id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289 create mode 100644 tests/fuzzed/id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241 create mode 100644 tests/fuzzed/id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986 create mode 100644 tests/fuzzed/id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272 create mode 100644 tests/fuzzed/id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084 create mode 100644 tests/fuzzed/id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283 create mode 100644 tests/fuzzed/id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309 create mode 100644 tests/fuzzed/id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179 create mode 100644 tests/fuzzed/id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110 create mode 100644 tests/fuzzed/id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335 create mode 100644 tests/fuzzed/id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112 create mode 100644 tests/fuzzed/id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148 create mode 100644 tests/fuzzed/id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385 create mode 100644 tests/fuzzed/id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271 create mode 100644 tests/fuzzed/id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188 create mode 100644 tests/fuzzed/id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275 create mode 100644 tests/fuzzed/id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486 create mode 100644 tests/fuzzed/id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424 create mode 100644 tests/fuzzed/id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213 create mode 100644 tests/fuzzed/id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276 create mode 100644 tests/fuzzed/id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1 create mode 100644 tests/fuzzed/id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269 create mode 100644 tests/fuzzed/id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1 create mode 100644 tests/fuzzed/id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564 create mode 100644 tests/fuzzed/id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1 create mode 100644 tests/fuzzed/id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242 create mode 100644 tests/fuzzed/id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1 create mode 100644 tests/fuzzed/id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520 create mode 100644 tests/fuzzed/id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1 create mode 100644 tests/fuzzed/id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1 create mode 100644 tests/fuzzed/id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995 create mode 100644 tests/fuzzed/id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1 create mode 100644 tests/fuzzed/id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98 create mode 100644 tests/fuzzed/id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1 create mode 100644 tests/fuzzed/id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650 create mode 100644 tests/fuzzed/id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1 create mode 100644 tests/fuzzed/id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330 create mode 100644 tests/fuzzed/id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1 create mode 100644 tests/fuzzed/id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917 create mode 100644 tests/fuzzed/id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1 create mode 100644 tests/fuzzed/id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144 create mode 100644 tests/fuzzed/id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1 create mode 100644 tests/fuzzed/id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8 create mode 100644 tests/fuzzed/id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1 create mode 100644 tests/fuzzed/id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200 create mode 100644 tests/fuzzed/id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367 create mode 100644 tests/fuzzed/id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289 create mode 100644 tests/fuzzed/id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105 create mode 100644 tests/fuzzed/id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671 create mode 100644 tests/fuzzed/id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597 create mode 100644 tests/fuzzed/id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20 create mode 100644 tests/fuzzed/id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624 create mode 100644 tests/fuzzed/id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27 create mode 100644 tests/fuzzed/id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732 create mode 100644 tests/fuzzed/id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145 create mode 100644 tests/fuzzed/id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4 create mode 100644 tests/fuzzed/id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113 create mode 100644 tests/fuzzed/id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4 create mode 100644 tests/fuzzed/id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906 create mode 100644 tests/fuzzed/id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4 create mode 100644 tests/fuzzed/id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488 create mode 100644 tests/fuzzed/id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4 create mode 100644 tests/fuzzed/id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361 create mode 100644 tests/fuzzed/id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4 create mode 100644 tests/fuzzed/id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4 create mode 100644 tests/fuzzed/id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545 create mode 100644 tests/fuzzed/id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14 create mode 100644 tests/fuzzed/id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111 create mode 100644 tests/fuzzed/id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3 create mode 100644 tests/fuzzed/id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179 create mode 100644 tests/fuzzed/id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3 create mode 100644 tests/fuzzed/id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146 create mode 100644 tests/fuzzed/id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3 create mode 100644 tests/fuzzed/id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793 create mode 100644 tests/fuzzed/id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3 create mode 100644 tests/fuzzed/id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192 create mode 100644 tests/fuzzed/id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3 create mode 100644 tests/fuzzed/id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96 create mode 100644 tests/fuzzed/id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3 create mode 100644 tests/fuzzed/id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774 create mode 100644 tests/fuzzed/id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3 create mode 100644 tests/fuzzed/id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056 create mode 100644 tests/fuzzed/id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3 create mode 100644 tests/fuzzed/id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422 create mode 100644 tests/fuzzed/id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166 create mode 100644 tests/fuzzed/id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197 create mode 100644 tests/fuzzed/id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489 create mode 100644 tests/fuzzed/id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275 create mode 100644 tests/fuzzed/id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2 create mode 100644 tests/fuzzed/id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8 create mode 100644 tests/fuzzed/id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2 create mode 100644 tests/fuzzed/id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523 create mode 100644 tests/fuzzed/id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2 create mode 100644 tests/fuzzed/id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270 create mode 100644 tests/fuzzed/id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2 create mode 100644 tests/fuzzed/id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214 create mode 100644 tests/fuzzed/id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3 create mode 100644 tests/fuzzed/id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164 create mode 100644 tests/fuzzed/id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3 create mode 100644 tests/fuzzed/id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380 create mode 100644 tests/fuzzed/id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650 create mode 100644 tests/fuzzed/id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037 create mode 100644 tests/fuzzed/id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350 create mode 100644 tests/fuzzed/id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95 create mode 100644 tests/fuzzed/id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1 create mode 100644 tests/fuzzed/id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1 create mode 100644 tests/fuzzed/id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3 create mode 100644 tests/fuzzed/id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26 create mode 100644 tests/fuzzed/id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13 create mode 100644 tests/fuzzed/id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15 create mode 100644 tests/fuzzed/id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13 create mode 100644 tests/fuzzed/id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9 create mode 100644 tests/fuzzed/id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10 create mode 100644 tests/fuzzed/id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12 create mode 100644 tests/fuzzed/id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000207,sig:06,src:000101,time:29549985,execs:138505,op:havoc,rep:10 create mode 100644 tests/fuzzed/id:000208,sig:06,src:000026,time:29630501,execs:139797,op:inf,rep:12 create mode 100644 tests/fuzzed/id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12 create mode 100644 tests/fuzzed/id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69 create mode 100644 tests/fuzzed/id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1 create mode 100644 tests/fuzzed/id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1 create mode 100644 tests/fuzzed/id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1 create mode 100644 tests/fuzzed/id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1 create mode 100644 tests/fuzzed/id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1 create mode 100644 tests/fuzzed/id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1 create mode 100644 tests/fuzzed/id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1 create mode 100644 tests/fuzzed/id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1 create mode 100644 tests/fuzzed/id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1 create mode 100644 tests/fuzzed/id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1 create mode 100644 tests/fuzzed/id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1 create mode 100644 tests/fuzzed/id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2 create mode 100644 tests/fuzzed/id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13 create mode 100644 tests/fuzzed/id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2 create mode 100644 tests/fuzzed/id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2 create mode 100644 tests/fuzzed/id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955 create mode 100644 tests/fuzzed/id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2 create mode 100644 tests/fuzzed/id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2 create mode 100644 tests/fuzzed/id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2 create mode 100644 tests/fuzzed/id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2 create mode 100644 tests/fuzzed/id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2 create mode 100644 tests/fuzzed/id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2 create mode 100644 tests/fuzzed/id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4 create mode 100644 tests/fuzzed/id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000238,sig:06,src:001952,time:40616704,execs:182234,op:quick,pos:1361,val:+4 create mode 100644 tests/fuzzed/id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7 create mode 100644 tests/fuzzed/id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6 create mode 100644 tests/fuzzed/id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5 create mode 100644 tests/fuzzed/id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26 create mode 100644 tests/fuzzed/id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26 create mode 100644 tests/fuzzed/id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2 create mode 100644 tests/fuzzed/id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2 create mode 100644 tests/fuzzed/id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2 create mode 100644 tests/fuzzed/id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167 create mode 100644 tests/fuzzed/id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187 create mode 100644 tests/fuzzed/id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167 create mode 100644 tests/fuzzed/id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10 create mode 100644 tests/fuzzed/id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6 create mode 100644 tests/fuzzed/id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6 create mode 100644 tests/fuzzed/id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4 create mode 100644 tests/fuzzed/id:000255,sig:06,src:002305,time:54885789,execs:235917,op:flip32,pos:3 create mode 100644 tests/fuzzed/id:000256,sig:06,src:002305,time:54897658,execs:236191,op:havoc,rep:15 create mode 100644 tests/fuzzed/id:000257,sig:06,src:002305,time:54915177,execs:236611,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000258,sig:06,src:002305,time:54918057,execs:236681,op:havoc,rep:16 create mode 100644 tests/fuzzed/id:000259,sig:06,src:002305,time:54926618,execs:236882,op:havoc,rep:14 create mode 100644 tests/fuzzed/id:000260,sig:06,src:002305,time:54942338,execs:237257,op:havoc,rep:15 create mode 100644 tests/fuzzed/id:000261,sig:06,src:002305,time:54965944,execs:237841,op:havoc,rep:15 create mode 100644 tests/fuzzed/id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5 create mode 100644 tests/fuzzed/id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10 create mode 100644 tests/fuzzed/id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12 create mode 100644 tests/fuzzed/id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26 create mode 100644 tests/fuzzed/id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2 create mode 100644 tests/fuzzed/id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5 create mode 100644 tests/fuzzed/id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5 create mode 100644 tests/fuzzed/id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5 create mode 100644 tests/fuzzed/id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000274,sig:06,src:000032,time:58977780,execs:255922,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1 create mode 100644 tests/fuzzed/id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7 create mode 100644 tests/fuzzed/id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7 create mode 100644 tests/fuzzed/id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11 create mode 100644 tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11 create mode 100644 tests/fuzzed/id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28 create mode 100644 tests/fuzzed/id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299 create mode 100644 tests/fuzzed/id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111 create mode 100644 tests/fuzzed/id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331 create mode 100644 tests/fuzzed/id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868 create mode 100644 tests/fuzzed/id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257 create mode 100644 tests/fuzzed/id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62 create mode 100644 tests/fuzzed/id:000293,sig:06,src:001816,time:72343382,execs:315245,op:arith8,pos:458,val:+28 create mode 100644 tests/fuzzed/id:000294,sig:06,src:000057,time:72638050,execs:316690,op:quick,pos:248 create mode 100644 tests/fuzzed/id:000295,sig:06,src:000057,time:72724520,execs:317104,op:arith8,pos:137,val:+5 create mode 100644 tests/fuzzed/id:000296,sig:06,src:001381,time:73193810,execs:319768,op:inf,rep:4 create mode 100644 tests/fuzzed/id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683 create mode 100644 tests/fuzzed/id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78 create mode 100644 tests/fuzzed/id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186 create mode 100644 tests/fuzzed/id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189 create mode 100644 tests/fuzzed/id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190 create mode 100644 tests/fuzzed/id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204 create mode 100644 tests/fuzzed/id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5 create mode 100644 tests/fuzzed/id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232 create mode 100644 tests/fuzzed/id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361 create mode 100644 tests/fuzzed/id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60 create mode 100644 tests/fuzzed/id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231 create mode 100644 tests/fuzzed/id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552 create mode 100644 tests/fuzzed/id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290 create mode 100644 tests/fuzzed/id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291 create mode 100644 tests/fuzzed/id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27 create mode 100644 tests/fuzzed/id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270 create mode 100644 tests/fuzzed/id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5 create mode 100644 tests/fuzzed/id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187 create mode 100644 tests/fuzzed/id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26 create mode 100644 tests/fuzzed/id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88 create mode 100644 tests/fuzzed/id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361 create mode 100644 tests/fuzzed/id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113 create mode 100644 tests/fuzzed/id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510 create mode 100644 tests/fuzzed/id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779 create mode 100644 tests/fuzzed/id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115 create mode 100644 tests/fuzzed/id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309 create mode 100644 tests/fuzzed/id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206 create mode 100644 tests/fuzzed/id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14 create mode 100644 tests/fuzzed/id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362 create mode 100644 tests/fuzzed/id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488 create mode 100644 tests/fuzzed/id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956 create mode 100644 tests/fuzzed/id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188 create mode 100644 tests/fuzzed/id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357 create mode 100644 tests/fuzzed/id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001 create mode 100644 tests/fuzzed/id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242 create mode 100644 tests/fuzzed/id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243 create mode 100644 tests/fuzzed/id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13 create mode 100644 tests/fuzzed/id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10 create mode 100644 tests/fuzzed/id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274 create mode 100644 tests/fuzzed/id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11 create mode 100644 tests/fuzzed/id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11 create mode 100644 tests/fuzzed/id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187 create mode 100644 tests/fuzzed/id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361 create mode 100644 tests/fuzzed/id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415 create mode 100644 tests/fuzzed/id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5 create mode 100644 tests/fuzzed/id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92 create mode 100644 tests/fuzzed/id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595 create mode 100644 tests/fuzzed/id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635 create mode 100644 tests/fuzzed/id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695 create mode 100644 tests/fuzzed/id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821 create mode 100644 tests/fuzzed/id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002 create mode 100644 tests/fuzzed/id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169 create mode 100644 tests/fuzzed/id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395 create mode 100644 tests/fuzzed/id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53 create mode 100644 tests/fuzzed/id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221 create mode 100644 tests/fuzzed/id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435 create mode 100644 tests/fuzzed/id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731 create mode 100644 tests/fuzzed/id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013 create mode 100644 tests/fuzzed/id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324 create mode 100644 tests/fuzzed/id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633 create mode 100644 tests/fuzzed/id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395 create mode 100644 tests/fuzzed/id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4 create mode 100644 tests/fuzzed/id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345 create mode 100644 tests/fuzzed/id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207 create mode 100644 tests/fuzzed/id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856 create mode 100644 tests/fuzzed/id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018 create mode 100644 tests/fuzzed/id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2 create mode 100644 tests/fuzzed/id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189 create mode 100644 tests/fuzzed/id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204 create mode 100644 tests/fuzzed/id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856 create mode 100644 tests/fuzzed/id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226 create mode 100644 tests/fuzzed/id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413 create mode 100644 tests/fuzzed/id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499 create mode 100644 tests/fuzzed/id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3 create mode 100644 tests/fuzzed/id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241 create mode 100644 tests/fuzzed/id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045 create mode 100644 tests/fuzzed/id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58 create mode 100644 tests/fuzzed/id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542 create mode 100644 tests/fuzzed/id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2 create mode 100644 tests/fuzzed/id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707 create mode 100644 tests/fuzzed/id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378 create mode 100644 tests/fuzzed/id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361 create mode 100644 tests/fuzzed/id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487 create mode 100644 tests/fuzzed/id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107 create mode 100644 tests/fuzzed/id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292 create mode 100644 tests/fuzzed/id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116 create mode 100644 tests/fuzzed/id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173 create mode 100644 tests/fuzzed/id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347 create mode 100644 tests/fuzzed/id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14 create mode 100644 tests/fuzzed/id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330 create mode 100644 tests/fuzzed/id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266 create mode 100644 tests/fuzzed/id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361 create mode 100644 tests/fuzzed/id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141 create mode 100644 tests/fuzzed/id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3 create mode 100644 tests/fuzzed/id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6 create mode 100644 tests/fuzzed/id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206 create mode 100644 tests/fuzzed/id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292 create mode 100644 tests/fuzzed/id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393 create mode 100644 tests/fuzzed/id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168 create mode 100644 tests/fuzzed/id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327 create mode 100644 tests/fuzzed/id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077 create mode 100644 tests/fuzzed/id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076 create mode 100644 tests/fuzzed/id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445 create mode 100644 tests/fuzzed/id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078 create mode 100644 tests/fuzzed/id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188 create mode 100644 tests/fuzzed/id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474 create mode 100644 tests/fuzzed/id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874 create mode 100644 tests/fuzzed/id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6 create mode 100644 tests/fuzzed/id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6 create mode 100644 tests/fuzzed/id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5 create mode 100644 tests/fuzzed/id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26 create mode 100644 tests/fuzzed/id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3 create mode 100644 tests/fuzzed/id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479 create mode 100644 tests/fuzzed/id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141 create mode 100644 tests/fuzzed/id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2 create mode 100644 tests/fuzzed/id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8 create mode 100644 tests/fuzzed/id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7 create mode 100644 tests/fuzzed/id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5 create mode 100644 tests/fuzzed/id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5 create mode 100644 tests/fuzzed/id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046 create mode 100644 tests/fuzzed/id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361 create mode 100644 tests/fuzzed/id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391 create mode 100644 tests/fuzzed/id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25 create mode 100644 tests/fuzzed/id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1 create mode 100644 tests/fuzzed/id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455 create mode 100644 tests/fuzzed/id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24 create mode 100644 tests/fuzzed/id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289 create mode 100644 tests/fuzzed/id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203 create mode 100644 tests/fuzzed/id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354 create mode 100644 tests/fuzzed/id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166 create mode 100644 tests/fuzzed/id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005 create mode 100644 tests/fuzzed/id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379 create mode 100644 tests/fuzzed/id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7 create mode 100644 tests/fuzzed/id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7 create mode 100644 tests/fuzzed/id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155 create mode 100644 tests/fuzzed/id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260 create mode 100644 tests/fuzzed/id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47 create mode 100644 tests/fuzzed/id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54 create mode 100644 tests/fuzzed/id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59 create mode 100644 tests/fuzzed/id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132 create mode 100644 tests/fuzzed/id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347 create mode 100644 tests/fuzzed/id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60 create mode 100644 tests/fuzzed/id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1 create mode 100644 tests/fuzzed/id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260 diff --git a/src/behavior.zig b/src/behavior.zig index 67b02cab..1baf29f0 100644 --- a/src/behavior.zig +++ b/src/behavior.zig @@ -1,3 +1,7 @@ +//! Because of https://github.com/ziglang/zig/issues/15091 test that write to stdout will hang +//! However I think its completely legitimate for a tested code to output to stdout and I +//! don't really get why zig test needs to use stdout anyway + const std = @import("std"); const Runner = @import("Runner.zig"); const io = @import("io.zig"); @@ -5,10 +9,6 @@ const Parser = @import("Parser.zig"); const BuildOptions = @import("build_options"); const clap = @import("clap"); -// Because of https://github.com/ziglang/zig/issues/15091 test that write to stdout will hang -// However I think its completely legitimate for a tested code to output to stdout and I -// don't really get why zig test needs to use stdout anyway - const black_listed_tests = std.StaticStringMap(void).initComptime( .{ .{ "tests/behavior/027-run-file.buzz", {} }, @@ -185,8 +185,6 @@ fn testCompileErrors(allocator: std.mem.Allocator, fail_fast: bool) !Result { return result; } -// FIXME: should run files in dist/default/hangs with a timeout -// is the only solution for to spawn the process in a thread? seems like we can't wait for spawned process with a timeout fn testFuzzCrashes(allocator: std.mem.Allocator, fail_fast: bool) !Result { var result = Result{}; @@ -225,101 +223,99 @@ fn testFuzzCrashes(allocator: std.mem.Allocator, fail_fast: bool) !Result { var resolved_writer = resolved_file.writer(&.{}); - for ([_][]const u8{ - "dist/default/crashes", - "dist/default/hangs", - }) |dir| { - var test_dir = try std.fs.cwd().openDir( - dir, - .{ - .iterate = true, - }, - ); - var it = test_dir.iterate(); - - while (try it.next()) |file| : (result.total += 1) { - if (file.kind == .file) { - // Was it resolved? - if (resolved.get(file.name) != null) { - continue; - } + const dir = "tests/fuzzed"; + var test_dir = try std.fs.cwd().openDir( + dir, + .{ + .iterate = true, + }, + ); + var it = test_dir.iterate(); - var file_name = std.Io.Writer.Allocating.init(allocator); - defer file_name.deinit(); - try file_name.writer.print("{s}/{s}", .{ dir, file.name }); + while (try it.next()) |file| : (result.total += 1) { + if (file.kind == .file) { + // Was it resolved? + if (resolved.get(file.name) != null) { + continue; + } - if (black_listed_tests.has(file_name.written())) { - result.skipped += 1; - continue; - } + var file_name = std.Io.Writer.Allocating.init(allocator); + defer file_name.deinit(); + try file_name.writer.print("{s}/{s}", .{ dir, file.name }); - const arg0 = std.fmt.allocPrint( - allocator, - "{s}/bin/buzz", - .{ - try Parser.buzzPrefix(allocator), - }, - ) catch unreachable; - defer allocator.free(arg0); + if (black_listed_tests.has(file_name.written())) { + result.skipped += 1; + continue; + } - var child = std.process.Child.init( - &.{ - arg0, - "-t", - file_name.written(), - }, - allocator, - ); + const arg0 = std.fmt.allocPrint( + allocator, + "{s}/bin/buzz", + .{ + try Parser.buzzPrefix(allocator), + }, + ) catch unreachable; + defer allocator.free(arg0); - try child.spawn(); + var child = std.process.Child.init( + &.{ + arg0, + "-t", + file_name.written(), + }, + allocator, + ); + child.stdout_behavior = .Ignore; + child.stderr_behavior = .Ignore; - // Run in a thread so we can abort hanging tests - var done = false; - const thread = try std.Thread.spawn( - .{ - .allocator = allocator, - }, - struct { - fn wait(process: *std.process.Child, over: *bool) void { - _ = process.wait() catch @panic("Could not wait for buzz process"); + try child.spawn(); - over.* = true; - } - }.wait, - .{ - &child, - &done, - }, - ); + // Run in a thread so we can abort hanging tests + var done = false; + const thread = try std.Thread.spawn( + .{ + .allocator = allocator, + }, + struct { + fn wait(process: *std.process.Child, over: *bool) void { + _ = process.wait() catch @panic("Could not wait for buzz process"); - var timer = try std.time.Timer.start(); - while (!done and timer.read() < 2 * std.time.ns_per_s) {} + over.* = true; + } + }.wait, + .{ + &child, + &done, + }, + ); - if (child.term) |term| { - thread.join(); + var timer = try std.time.Timer.start(); + while (!done and timer.read() < 2 * std.time.ns_per_s) {} - const uterm = term catch null; - if (uterm == null or uterm.? != .Exited) { - try result.failed.append(allocator, try file_name.toOwnedSlice()); + if (child.term) |term| { + thread.join(); - if (fail_fast) { - break; - } - } else { - try resolved_writer.interface.print("{s}\n", .{file.name}); - try resolved_writer.interface.flush(); - } - } else { - try result.hanged.append(allocator, try file_name.toOwnedSlice()); - std.posix.kill(child.id, std.posix.SIG.TERM) catch {}; - // FIXME: Not sure i understands this but it seems that child.kill() kills the process and then wait for the now - // non existing process? - // _ = child.kill() catch {}; - thread.join(); + const uterm = term catch null; + if (uterm == null or uterm.? != .Exited) { + try result.failed.append(allocator, try file_name.toOwnedSlice()); if (fail_fast) { break; } + } else { + try resolved_writer.interface.print("{s}\n", .{file.name}); + try resolved_writer.interface.flush(); + } + } else { + try result.hanged.append(allocator, try file_name.toOwnedSlice()); + std.posix.kill(child.id, std.posix.SIG.TERM) catch {}; + // FIXME: Not sure i understands this but it seems that child.kill() kills the process and then wait for the now + // non existing process? + // _ = child.kill() catch {}; + thread.join(); + + if (fail_fast) { + break; } } } @@ -422,14 +418,14 @@ pub fn main() !u8 { if (result.failed.items.len > 0) { io.print("Failed tests:\n", .{}); for (result.failed.items) |failed| { - io.print(" \u{001b}[31m{s}]\u{001b}[0m\n", .{failed}); + io.print(" \u{001b}[31m{s}\u{001b}[0m\n", .{failed}); } } if (result.hanged.items.len > 0) { io.print("Hanged tests:\n", .{}); for (result.hanged.items) |hanged| { - io.print(" \u{001b}[31m{s}]\u{001b}[0m\n", .{hanged}); + io.print(" \u{001b}[31m{s}\u{001b}[0m\n", .{hanged}); } } diff --git a/tests/fuzzed/README.txt b/tests/fuzzed/README.txt new file mode 100644 index 00000000..71526cf4 --- /dev/null +++ b/tests/fuzzed/README.txt @@ -0,0 +1,14 @@ +Command line used to find this crash: + +/opt/homebrew/Cellar/afl++/4.31/libexec/afl-fuzz -i tests/behavior -o dist zig-out/bin/fuzz_afl + +If you can't reproduce a bug outside of afl-fuzz, be sure to set the same +memory limit. The limit used for this fuzzing session was 0 B. + +Need a tool to minimize test cases before investigating the crashes or sending +them to a vendor? Check out the afl-tmin that comes with the fuzzer! + +Found any cool bugs in open-source tools using afl-fuzz? If yes, please post +to https://github.com/AFLplusplus/AFLplusplus/issues/286 once the issues + are fixed :) + diff --git a/tests/fuzzed/id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0 b/tests/fuzzed/id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0 new file mode 100644 index 00000000..82380545 --- /dev/null +++ b/tests/fuzzed/id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0 @@ -0,0 +1,5 @@ + = "unused"; + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1 b/tests/fuzzed/id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1 new file mode 100644 index 00000000..6ebff1da --- /dev/null +++ b/tests/fuzzed/id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, mnssage: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1 b/tests/fuzzed/id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1 new file mode 100644 index 00000000..5b2dd6f5 --- /dev/null +++ b/tests/fuzzed/id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1 @@ -0,0 +1,5 @@ +_ = "unused"; + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105 b/tests/fuzzed/id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105 new file mode 100644 index 00000000..f9ed1a76 --- /dev/null +++ b/tests/fuzzed/id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, me3sage: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1 b/tests/fuzzed/id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1 new file mode 100644 index 00000000..b35d6e68 --- /dev/null +++ b/tests/fuzzed/id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1 @@ -0,0 +1,5 @@ +_`= "unused"; + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105 b/tests/fuzzed/id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105 new file mode 100644 index 00000000..073b6539 --- /dev/null +++ b/tests/fuzzed/id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, meSsage: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1 b/tests/fuzzed/id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1 new file mode 100644 index 00000000..252aff0c --- /dev/null +++ b/tests/fuzzed/id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1 @@ -0,0 +1,5 @@ +_$= "unused"; + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108 b/tests/fuzzed/id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108 new file mode 100644 index 00000000..faf85b54 --- /dev/null +++ b/tests/fuzzed/id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, messafe: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1 b/tests/fuzzed/id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1 new file mode 100644 index 00000000..01f39128 --- /dev/null +++ b/tests/fuzzed/id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1 @@ -0,0 +1,5 @@ +_@= "unused"; + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105 b/tests/fuzzed/id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105 new file mode 100644 index 00000000..222d968b --- /dev/null +++ b/tests/fuzzed/id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, meCsage: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1 b/tests/fuzzed/id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1 new file mode 100644 index 00000000..edef192f --- /dev/null +++ b/tests/fuzzed/id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1 @@ -0,0 +1,5 @@ +_#= "unused"; + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4 b/tests/fuzzed/id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4 new file mode 100644 index 00000000..713f1224 --- /dev/null +++ b/tests/fuzzed/id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Usigg a fuŒction coming f„„„„„„„„„„„„„„„„„„„„„„„rom a library" { + std\assert(true, messagf: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66 b/tests/fuzzed/id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66 new file mode 100644 index 00000000..e8d15578 --- /dev/null +++ b/tests/fuzzed/id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66 @@ -0,0 +1,5 @@ +_ = "unused"; + +test "discarding value" { + _ = "i'm discarded"; +~ diff --git a/tests/fuzzed/id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2 b/tests/fuzzed/id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2 new file mode 100644 index 00000000..69d2dadf --- /dev/null +++ b/tests/fuzzed/id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from —————————————————————————————a library" { + std\assert(true, mesPage: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1 b/tests/fuzzed/id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1 new file mode 100644 index 00000000..ba1bc48c --- /dev/null +++ b/tests/fuzzed/id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1 @@ -0,0 +1,5 @@ +_'½ "unused"; + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4 b/tests/fuzzed/id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4 new file mode 100644 index 00000000..7ea33e14 --- /dev/null +++ b/tests/fuzzed/id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function ccccccccccccomiLgÿrom a library" { + std\assert(true, iessage: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1 b/tests/fuzzed/id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1 new file mode 100644 index 00000000..40fd2976 --- /dev/null +++ b/tests/fuzzed/id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1 @@ -0,0 +1,5 @@ +_#ý "unused"; + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1 b/tests/fuzzed/id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1 new file mode 100644 index 00000000..d9f32633 --- /dev/null +++ b/tests/fuzzed/id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, messssssssssssssssssssssssssssssssage: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4 b/tests/fuzzed/id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4 new file mode 100644 index 00000000..cd38dc98 --- /dev/null +++ b/tests/fuzzed/id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4 @@ -0,0 +1,5 @@ +_ = void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, mjssage: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5 b/tests/fuzzed/id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5 new file mode 100644 index 00000000..d2e10872 --- /dev/null +++ b/tests/fuzzed/id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5 @@ -0,0 +1,5 @@ +_ = "unused"@ + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1 b/tests/fuzzed/id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1 new file mode 100644 index 00000000..31850f87 --- /dev/null +++ b/tests/fuzzed/id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, messase: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23 b/tests/fuzzed/id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23 new file mode 100644 index 00000000..23030e3b --- /dev/null +++ b/tests/fuzzed/id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23 @@ -0,0 +1,5 @@ +_ = "unused"$ + +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000014,src:000008,time:3034101,execs:29776,op:flip1,pos:379 b/tests/fuzzed/id:000014,src:000008,time:3034101,execs:29776,op:flip1,pos:379 new file mode 100644 index 00000000..d7ff22a7 --- /dev/null +++ b/tests/fuzzed/id:000014,src:000008,time:3034101,execs:29776,op:flip1,pos:379 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i ; 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26 b/tests/fuzzed/id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26 new file mode 100644 index 00000000..92bf6158 --- /dev/null +++ b/tests/fuzzed/id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26 @@ -0,0 +1,4 @@ +_ = "unused";$ +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000015,src:000008,time:3036220,execs:29779,op:flip1,pos:379 b/tests/fuzzed/id:000015,src:000008,time:3036220,execs:29779,op:flip1,pos:379 new file mode 100644 index 00000000..62ce90f7 --- /dev/null +++ b/tests/fuzzed/id:000015,src:000008,time:3036220,execs:29779,op:flip1,pos:379 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i / 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23 b/tests/fuzzed/id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23 new file mode 100644 index 00000000..51f52292 --- /dev/null +++ b/tests/fuzzed/id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23 @@ -0,0 +1,5 @@ +_ = "unused"; + +test "discarding value" { + _ = "i'm discarded"; +}! \ No newline at end of file diff --git a/tests/fuzzed/id:000016,src:000008,time:3038341,execs:29782,op:flip1,pos:379 b/tests/fuzzed/id:000016,src:000008,time:3038341,execs:29782,op:flip1,pos:379 new file mode 100644 index 00000000..c603b6b8 --- /dev/null +++ b/tests/fuzzed/id:000016,src:000008,time:3038341,execs:29782,op:flip1,pos:379 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i * 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28 b/tests/fuzzed/id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28 new file mode 100644 index 00000000..3b54afb8 --- /dev/null +++ b/tests/fuzzed/id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28 @@ -0,0 +1,5 @@ +_ = "unused"; + +test "discarding value" { + _ = "i'm discarded"; +}& \ No newline at end of file diff --git a/tests/fuzzed/id:000017,src:000008,time:3155723,execs:30217,op:flip2,pos:379 b/tests/fuzzed/id:000017,src:000008,time:3155723,execs:30217,op:flip2,pos:379 new file mode 100644 index 00000000..fa381142 --- /dev/null +++ b/tests/fuzzed/id:000017,src:000008,time:3155723,execs:30217,op:flip2,pos:379 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i - 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30 b/tests/fuzzed/id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30 new file mode 100644 index 00000000..11465e64 --- /dev/null +++ b/tests/fuzzed/id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30 @@ -0,0 +1,5 @@ +_ = "unused"; + +test "discarding value" { + _ = "i'm discarded"; +}( \ No newline at end of file diff --git a/tests/fuzzed/id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2 b/tests/fuzzed/id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2 new file mode 100644 index 00000000..63a5f7d5 --- /dev/null +++ b/tests/fuzzed/id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objxcts" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, dessage: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35 b/tests/fuzzed/id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35 new file mode 100644 index 00000000..4942b794 --- /dev/null +++ b/tests/fuzzed/id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35 @@ -0,0 +1,5 @@ +_ = "unused"; + +test "discarding value" { + _ = "i'm discarded"; +}- \ No newline at end of file diff --git a/tests/fuzzed/id:000019,src:000008,time:3919860,execs:33298,op:havoc,rep:1 b/tests/fuzzed/id:000019,src:000008,time:3919860,execs:33298,op:havoc,rep:1 new file mode 100644 index 00000000..8be68a71 --- /dev/null +++ b/tests/fuzzed/id:000019,src:000008,time:3919860,execs:33298,op:havoc,rep:1 @@ -0,0 +1,27 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referencedssage: "Obj i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1 b/tests/fuzzed/id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1 new file mode 100644 index 0000000000000000000000000000000000000000..4fd3bf4dedeb7ccc07d533b2a77f3955d5063f5b GIT binary patch literal 68 zcma!NWKd8l%_}WVO;NJu;wnikE>TcQ$t+GzEK14DOIIjM%qdM(QmE!q0D^c0TLq;| N^;`w00B6 literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6 b/tests/fuzzed/id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6 new file mode 100644 index 00000000..62d5ef8f --- /dev/null +++ b/tests/fuzzed/id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun Tollect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, messa_e: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6 b/tests/fuzzed/id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6 new file mode 100644 index 00000000..fa5593a0 --- /dev/null +++ b/tests/fuzzed/id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6 @@ -0,0 +1,4 @@ +` ardicI v€ÿÿÿ" { + _ carding value" { + _ = "i'm dis; +} diff --git a/tests/fuzzed/id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1 b/tests/fuzzed/id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1 new file mode 100644 index 00000000..7dfd6bba --- /dev/null +++ b/tests/fuzzed/id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, mqssage: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10 b/tests/fuzzed/id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10 new file mode 100644 index 00000000..6f00d1e0 --- /dev/null +++ b/tests/fuzzed/id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10 @@ -0,0 +1,5 @@ +value& { + èèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèè_ = !i'm disng val_ = valužžžžžžžžžže& _ = !i'm disng vhlue" +{ + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1 b/tests/fuzzed/id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1 new file mode 100644 index 00000000..94f311e7 --- /dev/null +++ b/tests/fuzzed/id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2,Gmessage: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14 b/tests/fuzzed/id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14 new file mode 100644 index 0000000000000000000000000000000000000000..19ed9c8772d5b8c25b4e21ba51033b5154465371 GIT binary patch literal 124 zcma!7P}r-Wl&PMpkdj%P{3W%xgh9!gtCq`FK`AM(w74=wDZU&X0Od-7a;Ygmm0Tr2 uEed6c3@oWi3e{k7pdRaG5OJjxE(HYz1||id7NDXcg-jsJz&bS*YzF`oR3=0K literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1 b/tests/fuzzed/id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1 new file mode 100644 index 00000000..379c75f9 --- /dev/null +++ b/tests/fuzzed/id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, Vessage: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11 b/tests/fuzzed/id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11 new file mode 100644 index 00000000..5d71efba --- /dev/null +++ b/tests/fuzzed/id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11 @@ -0,0 +1,8 @@ +$"uaused; +test "discG =%"unused"; + +th = "unus d"; + +test "" { + _ =e"i.m discarded"; +|ü \ No newline at end of file diff --git a/tests/fuzzed/id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1 b/tests/fuzzed/id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1 new file mode 100644 index 00000000..8fe2887b --- /dev/null +++ b/tests/fuzzed/id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, messEge: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5 b/tests/fuzzed/id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5 new file mode 100644 index 00000000..3351dd9d --- /dev/null +++ b/tests/fuzzed/id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5 @@ -0,0 +1,6 @@ +_ = "unused"; + +tÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊest "discardiniscarding value" { + _ = "I'm g vapue" { + _ = "i'm discard_d"; +} diff --git a/tests/fuzzed/id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2 b/tests/fuzzed/id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2 new file mode 100644 index 00000000..5a412bdb --- /dev/null +++ b/tests/fuzzed/id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", mTssage: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16 b/tests/fuzzed/id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16 new file mode 100644 index 0000000000000000000000000000000000000000..ab288bd83f733da8daf308f80b5e4e008b62b5ea GIT binary patch literal 92 zcma!7fB^{@1576;7Nuk|FfcTn2LiZEPN|jxn}R~Tf>LQ-X>pa3LbaAc5S*WyqGZj* P<&awZRzWExvzQA2!@?In literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2 b/tests/fuzzed/id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2 new file mode 100644 index 00000000..de0c6b1c --- /dev/null +++ b/tests/fuzzed/id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, mQssage: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13 b/tests/fuzzed/id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13 new file mode 100644 index 00000000..5e46331e --- /dev/null +++ b/tests/fuzzed/id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13 @@ -0,0 +1,2 @@ + [ÿ[aluvalue"  _ = "i'm dr= "iscar; +} diff --git a/tests/fuzzed/id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2 b/tests/fuzzed/id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2 new file mode 100644 index 00000000..a1d3b36c --- /dev/null +++ b/tests/fuzzed/id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, ressage: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6 b/tests/fuzzed/id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6 new file mode 100644 index 0000000000000000000000000000000000000000..e1dda469383e4bb95326d465a219f4067ab75618 GIT binary patch literal 114 zcmd<$DoHIaQBX?BDo#!;O5w^&S13!&DNR*UsOE}SuvJhh%_}WVO;NJu!lO_D2*8Sc Zpn!pakpaR?RL@mN$po7XG9|N?3jnAMAw&QG literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2 b/tests/fuzzed/id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2 new file mode 100644 index 00000000..a636f7b0 --- /dev/null +++ b/tests/fuzzed/id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", mesvage: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14 b/tests/fuzzed/id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14 new file mode 100644 index 0000000000000000000000000000000000000000..dd7c7a2bcb84aea3fe1c27946863aeef9b2fa24a GIT binary patch literal 88 zcma!7Xi!a2isTY6Ni8l>P)f-xPEIUJ$;?YvC{wcLs!hx(O;u8;=2B2dQHWQtRZz-Q a&jE@9RreyPR%l=Vf)s^RkQpf;eOv&8VHpVk literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2 b/tests/fuzzed/id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2 new file mode 100644 index 00000000..51f107dd --- /dev/null +++ b/tests/fuzzed/id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", messYge: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9 b/tests/fuzzed/id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9 new file mode 100644 index 00000000..f92e590d --- /dev/null +++ b/tests/fuzzed/id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9 @@ -0,0 +1,6 @@ +_\iscarding value { + _ = "ivalue" { + =‘" discarded"; +} +ed"; +} diff --git a/tests/fuzzed/id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2 b/tests/fuzzed/id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2 new file mode 100644 index 00000000..d546dfbc --- /dev/null +++ b/tests/fuzzed/id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b",ymessage: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14 b/tests/fuzzed/id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14 new file mode 100644 index 00000000..aec4ca59 --- /dev/null +++ b/tests/fuzzed/id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14 @@ -0,0 +1,3 @@ +` =   "u "un"unused"@ + +tesg vaergstHscardˆngmap mscage"alue} diff --git a/tests/fuzzed/id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3 b/tests/fuzzed/id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3 new file mode 100644 index 00000000..9923cdd7 --- /dev/null +++ b/tests/fuzzed/id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("orld".sub(0, len: 5) == "helHellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hexšbin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", messUge: "could trim str"); +} diff --git a/tests/fuzzed/id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10 b/tests/fuzzed/id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10 new file mode 100644 index 00000000..7f6bffc8 --- /dev/null +++ b/tests/fuzzed/id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10 @@ -0,0 +1,7 @@ +_ß] +"unuseD"; +•est "discarding value" { + _ =•est "std\assert(MyObj{}.bound is fdiscardin"; += +Uest "discarding value" { + \ No newline at end of file diff --git a/tests/fuzzed/id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3 b/tests/fuzzed/id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3 new file mode 100644 index 00000000..01b5ba25 --- /dev/null +++ b/tests/fuzzed/id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3 @@ -0,0 +1,46 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", mvssage: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hdllo world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); } + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4 b/tests/fuzzed/id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4 new file mode 100644 index 00000000..9b53f8f2 --- /dev/null +++ b/tests/fuzzed/id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4 @@ -0,0 +1,4 @@ +_#= "uscarding rding value" { + _ =t "discarding rding value" { + _ =:"i'm discarded"; +} diff --git a/tests/fuzzed/id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1 b/tests/fuzzed/id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1 new file mode 100644 index 00000000..27cf5577 --- /dev/null +++ b/tests/fuzzed/id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", messawe: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16 b/tests/fuzzed/id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16 new file mode 100644 index 0000000000000000000000000000000000000000..fd9b14b1620337104cbdcaaf8acf7a7d0f0488c5 GIT binary patch literal 98 zcmazSPy_-7CJ+e+0$=|BFHFhID@)8tR{#>FstF1Y733706qGX66_iTzN{drdl&pif gN>YnU6qHgjQ! bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), mesGage: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6 b/tests/fuzzed/id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6 new file mode 100644 index 00000000..8613cb35 --- /dev/null +++ b/tests/fuzzed/id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6 @@ -0,0 +1,3 @@ +_ = i'mscarding value{ + _ = " discari'mded"; +} diff --git a/tests/fuzzed/id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182 b/tests/fuzzed/id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182 new file mode 100644 index 00000000..9671cc80 --- /dev/null +++ b/tests/fuzzed/id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", messagm: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7 b/tests/fuzzed/id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7 new file mode 100644 index 00000000..16519a03 --- /dev/null +++ b/tests/fuzzed/id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7 @@ -0,0 +1,3 @@ +FFFFFFFFFFFFFFFFF_ = "uµµµµµµµnused"µ“µµµµµµµµµµµµµµµµÿ€µµµµµ" { + µµµµµµµnused_ = "i'm discardddddddddddddddded"; +} diff --git a/tests/fuzzed/id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413 b/tests/fuzzed/id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413 new file mode 100644 index 00000000..21931ef2 --- /dev/null +++ b/tests/fuzzed/id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, mqssage: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15 b/tests/fuzzed/id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15 new file mode 100644 index 0000000000000000000000000000000000000000..fabc3ec3f8ea846f0d294c4e173809074191d655 GIT binary patch literal 100 zcma!7u;rXKZJJVPUTLw0QgL!(QA%cBx bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, Ressage: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13 b/tests/fuzzed/id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13 new file mode 100644 index 0000000000000000000000000000000000000000..da11537d0025ff09500e58b9a5b3e66b0406fdfa GIT binary patch literal 55 zcma$5-=LsWnpaw!dX_ bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could imriplement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == false, + joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9 b/tests/fuzzed/id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9 new file mode 100644 index 00000000..87d8d057 --- /dev/null +++ b/tests/fuzzed/id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9 @@ -0,0 +1,5 @@ +_ = "Œnused"; + +test "due" {êêêêêþêêêêêêêêêi'm d +  _ = "i'm disca„ discarded"; +} diff --git a/tests/fuzzed/id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1 b/tests/fuzzed/id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1 new file mode 100644 index 00000000..8e223fa5 --- /dev/null +++ b/tests/fuzzed/id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, messag7: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12 b/tests/fuzzed/id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12 new file mode 100644 index 00000000..c1b3ff7d --- /dev/null +++ b/tests/fuzzed/id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12 @@ -0,0 +1,5 @@ +_1 "unqsed";dii'm dis]arded""discarding _ ="ydii'm lue" { +ÿ€ m + +test "discart ; +} \ No newline at end of file diff --git a/tests/fuzzed/id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1 b/tests/fuzzed/id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1 new file mode 100644 index 00000000..2cc863af --- /dev/null +++ b/tests/fuzzed/id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list,omessage: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9 b/tests/fuzzed/id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9 new file mode 100644 index 0000000000000000000000000000000000000000..0b235f776d6e2ffa050479d9a78d2ab3152e2733 GIT binary patch literal 87 zcmYdMuvJhh%_}WVO;NJu;wnk4Cjg2|$`W%*QgGmJ0x`{vR~} literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1 b/tests/fuzzed/id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1 new file mode 100644 index 00000000..2823f441 --- /dev/null +++ b/tests/fuzzed/id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3,qmessage: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4 b/tests/fuzzed/id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4 new file mode 100644 index 0000000000000000000000000000000000000000..c97c21aa3cd3cb5a5f001952f8317735dd6eb3f0 GIT binary patch literal 107 zcmY$Wzbp;>n3cDVcfc3T25o hrKw5^)z+M+Fy+98flbI{U|?YY>jIjRlA2P>1pun6A_)Kh literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96 b/tests/fuzzed/id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96 new file mode 100644 index 00000000..25c28bcf --- /dev/null +++ b/tests/fuzzed/id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, lessage: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ], [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11 b/tests/fuzzed/id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11 new file mode 100644 index 0000000000000000000000000000000000000000..7f4c43f292d7bcf625807d94a9242fbf49c8534a GIT binary patch literal 83 zcma!7uvJhh%_}WVO;HL_;o@4u1qQ{*iA5=ydFcvei8=pMl@zME6o4Qeq&QPOHzzlR UAr}D@QZm8nkEJLTan*7G0PndOvH$=8 literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617 b/tests/fuzzed/id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617 new file mode 100644 index 00000000..b5b1b9b0 --- /dev/null +++ b/tests/fuzzed/id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ], [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo",Hmessage: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14 b/tests/fuzzed/id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14 new file mode 100644 index 00000000..5294fea4 --- /dev/null +++ b/tests/fuzzed/id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14 @@ -0,0 +1,8 @@ +_/; +;); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6 b/tests/fuzzed/id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6 new file mode 100644 index 0000000000000000000000000000000000000000..113451c9f61385def7037f2cd9ac2174fdf0a7bd GIT binary patch literal 75 zcmazSuvJhh%_}WVO;NJuVqr+tgMi`^1*MeC;^f4ll+3(zg|ft)(o`jdQZ5A`h*z*x TxSOe-s{m9G0aO6iTFV6h9p@FW literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774 b/tests/fuzzed/id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774 new file mode 100644 index 00000000..d0fc7fcd --- /dev/null +++ b/tests/fuzzed/id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ], [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, mvssage: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15 b/tests/fuzzed/id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15 new file mode 100644 index 0000000000000000000000000000000000000000..e07a5303750ab7cb0c0cc39618b74cddf96ad275 GIT binary patch literal 49 wcma$5&yeE4AYPhMUYwj*lwzx(l&PMpkdj#(kyupl|9|~|uGtVy353H10NJV)82|tP literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4 b/tests/fuzzed/id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4 new file mode 100644 index 00000000..68a6c310 --- /dev/null +++ b/tests/fuzzed/id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, uessage: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, message: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14 b/tests/fuzzed/id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14 new file mode 100644 index 0000000000000000000000000000000000000000..73a9229ead78b6d618e7edfb615260f9a81726a8 GIT binary patch literal 64 zcma!-w^dLo%~Mb)ODs~!NX^N~uYRSVpp>GZVEckuS~@RXxhyfKG*wBVno9u)ycB@S RGu0W2`chMjtp3(=0RU|968QiC literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4 b/tests/fuzzed/id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4 new file mode 100644 index 00000000..ecf43564 --- /dev/null +++ b/tests/fuzzed/id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, mesQage: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, message: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16 b/tests/fuzzed/id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16 new file mode 100644 index 0000000000000000000000000000000000000000..6feb8d5b10b71f68959d89e2a679d1c3c2c8b7e0 GIT binary patch literal 137 zcma#&QZ~j4Y!#GB^Gb_TQ<$u|xJpusOB7NR6cQAG!kP6A3=9f9i8-aIN^oALdM*$t wFk}`d3vjii78@$10GWwJDVcfc3S|(r)j;*tTna!C4>kv=9;`^ok*k&q06+{Q{r~^~ literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4 b/tests/fuzzed/id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4 new file mode 100644 index 00000000..31344775 --- /dev/null +++ b/tests/fuzzed/id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, mesWage: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16 b/tests/fuzzed/id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16 new file mode 100644 index 0000000000000000000000000000000000000000..530b13202e9eb6e219db0e6172c8027b0c32a644 GIT binary patch literal 136 zcma!7P-tMVRZz-Q&s9jtEKW`=N>NY(Ga49}7}ASNpuD1#%)E4TNrke+oKhf4RZ^(t rQUHQ@1&~o7{Qv*|hRkAThBPGwu&Pv1bR}5~3{pTP$qWn(|7*Db8#O3i literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3 b/tests/fuzzed/id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3 new file mode 100644 index 00000000..cf485857 --- /dev/null +++ b/tests/fuzzed/id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, gessage: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6 b/tests/fuzzed/id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6 new file mode 100644 index 00000000..f1dbc1be --- /dev/null +++ b/tests/fuzzed/id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6 @@ -0,0 +1,4 @@ +_€ÿÿÿunused"; + +tdsded"; +} diff --git a/tests/fuzzed/id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3 b/tests/fuzzed/id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3 new file mode 100644 index 00000000..7bf66910 --- /dev/null +++ b/tests/fuzzed/id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", messa4e: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16 b/tests/fuzzed/id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16 new file mode 100644 index 00000000..0b73c15a --- /dev/null +++ b/tests/fuzzed/id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16 @@ -0,0 +1,2 @@ +_ý* "YYYYYYYYYYYYYYYYYYYY€YYYO"i'm discarrded"; +h* \ No newline at end of file diff --git a/tests/fuzzed/id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3 b/tests/fuzzed/id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3 new file mode 100644 index 00000000..7999c2f6 --- /dev/null +++ b/tests/fuzzed/id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", Bessage: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13 b/tests/fuzzed/id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13 new file mode 100644 index 00000000..78d743c7 --- /dev/null +++ b/tests/fuzzed/id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13 @@ -0,0 +1,5 @@ +_ " +iscardinK valu$* { + 5 _§§§§§§§§§ = ttttttösÿ "disbarding valu$* { + _ = "i'm"unscaryed"; +}d \ No newline at end of file diff --git a/tests/fuzzed/id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3 b/tests/fuzzed/id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3 new file mode 100644 index 00000000..ce80c7f5 --- /dev/null +++ b/tests/fuzzed/id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initiql: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14 b/tests/fuzzed/id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14 new file mode 100644 index 00000000..733a7c8d --- /dev/null +++ b/tests/fuzzed/id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14 @@ -0,0 +1,5 @@ +_ = "unuscd"; + +testÆÆ†ÆÆ "dƹÀ¬ÆÆÆÆÆÆÆiscarding  + _ = "i'm }iscareed"ng = 0i'm diŒcarded"; +} diff --git a/tests/fuzzed/id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3 b/tests/fuzzed/id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3 new file mode 100644 index 00000000..9e9cacff --- /dev/null +++ b/tests/fuzzed/id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value,nmessage: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13 b/tests/fuzzed/id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13 new file mode 100644 index 00000000..1d75c454 --- /dev/null +++ b/tests/fuzzed/id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13 @@ -0,0 +1,4 @@ +_// s‹d\asseme" { + // s‹d\asseme" { + ß_ = "M'm Wiscarded"; +} diff --git a/tests/fuzzed/id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2 b/tests/fuzzed/id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2 new file mode 100644 index 00000000..f3919d58 --- /dev/null +++ b/tests/fuzzed/id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + ! "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, mevsage: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8 b/tests/fuzzed/id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8 new file mode 100644 index 0000000000000000000000000000000000000000..644eb6995e1ef8cbbca752409c10be6e4142e6e4 GIT binary patch literal 115 zcma!7uvJjnj{}tE0c91TKt(Y%MM;;TyckGXb8(fV7MD~*Kpcq5OIIjM%qdM(QmE!q c0D^c0TOd+U%2dx)NXdMd%&;{Dtg)600D3ztNB{r; literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2 b/tests/fuzzed/id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2 new file mode 100644 index 00000000..ddb4c225 --- /dev/null +++ b/tests/fuzzed/id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]* [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello",Rmessage: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2 b/tests/fuzzed/id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2 new file mode 100644 index 0000000000000000000000000000000000000000..dd116305ce14ed42fdb08048e08913dbb9c81cd0 GIT binary patch literal 89 zcma!7u;$__Nv;3?|9?tmadKi&N@iZVLRn%?Xn~SKH8O|;aegr{`~nL$FaRko1t5r5 YuvJjXRL@la>1WuQlA5Aq%~i_<0Ax!clK=n! literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2 b/tests/fuzzed/id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2 new file mode 100644 index 00000000..aad02c5d --- /dev/null +++ b/tests/fuzzed/id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]* [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", essage: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12 b/tests/fuzzed/id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12 new file mode 100644 index 00000000..1d2212fe --- /dev/null +++ b/tests/fuzzed/id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12 @@ -0,0 +1 @@ +# &ÿé€c \ No newline at end of file diff --git a/tests/fuzzed/id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3 b/tests/fuzzed/id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3 new file mode 100644 index 00000000..ed10eff5 --- /dev/null +++ b/tests/fuzzed/id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3 @@ -0,0 +1,198 @@ +import "œtd"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11 b/tests/fuzzed/id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11 new file mode 100644 index 0000000000000000000000000000000000000000..3874cecb99e9dea0211c8e8365f45ecf8ebe704e GIT binary patch literal 79 jcmY#aQ&(4KVE_^!1|Gl;R-ph<0n=a()d11URm%kcz)K5u literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3 b/tests/fuzzed/id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3 new file mode 100644 index 00000000..e9cdd0c5 --- /dev/null +++ b/tests/fuzzed/id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, Fessage: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7 b/tests/fuzzed/id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7 new file mode 100644 index 00000000..47caadab --- /dev/null +++ b/tests/fuzzed/id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7 @@ -0,0 +1,6 @@ +import int, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, message: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3 b/tests/fuzzed/id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3 new file mode 100644 index 00000000..30345c29 --- /dev/null +++ b/tests/fuzzed/id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, mdssage: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13 b/tests/fuzzed/id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13 new file mode 100644 index 00000000..3cf67858 --- /dev/null +++ b/tests/fuzzed/id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13 @@ -0,0 +1,6 @@ +import print,ßžŒŒert from "std"; + +test "Using a function coming from a library" { + std\assert(true, message: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3 b/tests/fuzzed/id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3 new file mode 100644 index 00000000..364250c3 --- /dev/null +++ b/tests/fuzzed/id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, essage: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5 b/tests/fuzzed/id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5 new file mode 100644 index 00000000..ad771279 --- /dev/null +++ b/tests/fuzzed/id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5 @@ -0,0 +1,6 @@ +import print, assert from "std"@ + +test "Using a function coming from a library" { + std\assert(true, message: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3 b/tests/fuzzed/id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3 new file mode 100644 index 00000000..3e880985 --- /dev/null +++ b/tests/fuzzed/id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2,Nmessage: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26 b/tests/fuzzed/id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26 new file mode 100644 index 00000000..1d6fc68e --- /dev/null +++ b/tests/fuzzed/id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26 @@ -0,0 +1,5 @@ +import print, assert from "std";$ +test "Using a function coming from a library" { + std\assert(true, message: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3 b/tests/fuzzed/id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3 new file mode 100644 index 00000000..4a0332d1 --- /dev/null +++ b/tests/fuzzed/id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0,Hmessage: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5 b/tests/fuzzed/id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5 new file mode 100644 index 00000000..a061858c --- /dev/null +++ b/tests/fuzzed/id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, message: "yeah!"); + std\print("wat")@ +} diff --git a/tests/fuzzed/id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3 b/tests/fuzzed/id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3 new file mode 100644 index 00000000..2a0d5723 --- /dev/null +++ b/tests/fuzzed/id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, mVssage: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4 b/tests/fuzzed/id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4 new file mode 100644 index 00000000..48ad4c2b --- /dev/null +++ b/tests/fuzzed/id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4 @@ -0,0 +1,8 @@ +`mport print, assert from "std"; + +test "Using } function coming frluƒused"; + +test "est "discardom a library" { + std\assert(true, message: "yeah!"); + std\print("wat"); +} diff --git a/tests/fuzzed/id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3 b/tests/fuzzed/id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3 new file mode 100644 index 00000000..c4facf61 --- /dev/null +++ b/tests/fuzzed/id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, messPge: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1 b/tests/fuzzed/id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1 new file mode 100644 index 00000000..79242def --- /dev/null +++ b/tests/fuzzed/id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\assert(true, message: "yeah!")@ + std\print("wat"); +} diff --git a/tests/fuzzed/id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3 b/tests/fuzzed/id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3 new file mode 100644 index 00000000..2ec6a1cc --- /dev/null +++ b/tests/fuzzed/id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1,amessage: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2 b/tests/fuzzed/id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2 new file mode 100644 index 00000000..553a311f --- /dev/null +++ b/tests/fuzzed/id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2 @@ -0,0 +1,6 @@ +import print, assert from "std"; + +test "Using a function coming from a library" { + std\Ussert(true, message: "yeah!"); + std\print("wat"); +~ diff --git a/tests/fuzzed/id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3 b/tests/fuzzed/id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3 new file mode 100644 index 00000000..58cc06c7 --- /dev/null +++ b/tests/fuzzed/id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, messPge: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1 b/tests/fuzzed/id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1 new file mode 100644 index 00000000..d9ec27e5 --- /dev/null +++ b/tests/fuzzed/id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1 @@ -0,0 +1,28 @@ +import "std"; +import "gc"; + +var collectorCalled = false;@ +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3 b/tests/fuzzed/id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3 new file mode 100644 index 00000000..1ec2ed4d --- /dev/null +++ b/tests/fuzzed/id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, Nessage: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1 b/tests/fuzzed/id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1 new file mode 100644 index 00000000..7365c9a3 --- /dev/null +++ b/tests/fuzzed/id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: it = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3 b/tests/fuzzed/id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3 new file mode 100644 index 00000000..87af6be8 --- /dev/null +++ b/tests/fuzzed/id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, massage: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1 b/tests/fuzzed/id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1 new file mode 100644 index 00000000..ba619b7f --- /dev/null +++ b/tests/fuzzed/id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > vo…d { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3 b/tests/fuzzed/id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3 new file mode 100644 index 00000000..863903a3 --- /dev/null +++ b/tests/fuzzed/id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, messPge: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8 b/tests/fuzzed/id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8 new file mode 100644 index 00000000..a56b0523 --- /dev/null +++ b/tests/fuzzed/id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8 @@ -0,0 +1,32 @@ +import "std"; +import "gc"; + +var collectooCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + se; + +object Kill { + yo: int } +} + +test "GC, collecting unreferenced objectsE { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be co“lected since not referenced anywhere + + i = i + 1; + } + + f‚nal before = gc\allocated(); + +lle gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "as called"); +} diff --git a/tests/fuzzed/id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3 b/tests/fuzzed/id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3 new file mode 100644 index 00000000..f36804dc --- /dev/null +++ b/tests/fuzzed/id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4,Gmessage: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7 b/tests/fuzzed/id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7 new file mode 100644 index 00000000..06b54c1e --- /dev/null +++ b/tests/fuzzed/id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7 @@ -0,0 +1,29 @@ +import "= Kill{ yo = i }; // Sho}ldstd"; +import "gc"; + +var collectorCalled = false; + +object Kill { + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Sho}ld be colleuted since ]; + renced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was + _ = "i'm discardassert(collectorCalled, message: "Object collector was called")"discarding value" { + ded";; +} diff --git a/tests/fuzzed/id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3 b/tests/fuzzed/id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3 new file mode 100644 index 00000000..a9b75da9 --- /dev/null +++ b/tests/fuzzed/id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, Dessage: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3 b/tests/fuzzed/id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3 new file mode 100644 index 00000000..14a209d7 --- /dev/null +++ b/tests/fuzzed/id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun colleCt() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated()$ + + gc\collect(); + + std\assert(gc\allocccccccccccccccce, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3 b/tests/fuzzed/id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3 new file mode 100644 index 00000000..c80ebd4d --- /dev/null +++ b/tests/fuzzed/id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, mcssage: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4 b/tests/fuzzed/id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4 new file mode 100644 index 00000000..2e465b0a --- /dev/null +++ b/tests/fuzzed/id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + @ +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referezced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= befo„e, message: "Garbage was collected"); + std\assert(colleÿ€orCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3 b/tests/fuzzed/id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3 new file mode 100644 index 00000000..8c03678d --- /dev/null +++ b/tests/fuzzed/id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, kessage: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5 b/tests/fuzzed/id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5 new file mode 100644 index 0000000000000000000000000000000000000000..8135bccbab3c5a43e1cffcb1b0624f6921a7a374 GIT binary patch literal 582 zcmZ9KJ#WG=5QdraD_&&^DivYnqpH-QLx&Dsk&tmN!PMBuc8Cz-x3}kfAQVq$-}!mp z^I4tF)&-plbr1vV&!_QYAcKXL+JN^9H_@VeS1lnGq( zx|k*HQCXV-kxlW2i&X{Q+f=+Urbj7dD%8eNNsf$U$xg_py-IYYSR-Gxm>q}F!|lGp ze2$-kt#yGt;g`+<+M0@7Ti6_wCS(e0Eb=^`_PA){!Qd7cr!Z#qKG}>{>IYE})^M9g1wqPa1Dlax4EPlZgzEBc9D@ZH4#b zLdL~B7Ar*{CSbkk;WM1bdr{F6>8Egej?f4{yf+mo%SAOt53JEFo)O>Os2>#_tNjoW HbWi>Pjgzo0 literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1 b/tests/fuzzed/id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1 new file mode 100644 index 00000000..b44a50a4 --- /dev/null +++ b/tests/fuzzed/id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, messNge: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3 b/tests/fuzzed/id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3 new file mode 100644 index 00000000..a98aae4e --- /dev/null +++ b/tests/fuzzed/id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3 @@ -0,0 +1,29 @@ +import "std"; +import "Oc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1$ + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object cooooooooooooooooooooooooooooooooollector was called"); +} diff --git a/tests/fuzzed/id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2 b/tests/fuzzed/id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2 new file mode 100644 index 00000000..bd514aa3 --- /dev/null +++ b/tests/fuzzed/id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, mtesage: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinesger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floatian == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1 b/tests/fuzzed/id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1 new file mode 100644 index 00000000..1d7bd7b6 --- /dev/null +++ b/tests/fuzzed/id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Paylfad:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1 b/tests/fuzzed/id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1 new file mode 100644 index 00000000..a512287b --- /dev/null +++ b/tests/fuzzed/id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteKer: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1 b/tests/fuzzed/id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1 new file mode 100644 index 00000000..6b310d5d --- /dev/null +++ b/tests/fuzzed/id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + lata: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2 b/tests/fuzzed/id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2 new file mode 100644 index 00000000..f480d738 --- /dev/null +++ b/tests/fuzzed/id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + inteder: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sf instloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1 b/tests/fuzzed/id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1 new file mode 100644 index 00000000..2142bd91 --- /dev/null +++ b/tests/fuzzed/id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K­ V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1 b/tests/fuzzed/id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1 new file mode 100644 index 00000000..b1519261 --- /dev/null +++ b/tests/fuzzed/id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1 @@ -0,0 +1,26 @@ +import "std"; + +test "Escape sequences" { + std\print("\{escaped interpolation}, \nhello\tworld, backslash \\ \"hey\""); +} + +test "String interpolation" { + final name = "joe"; + final age = 12; + + std\assert( + "{"$"} hello {name} i'm {age} years old {3 + 4}" == "$ hello joe i'm 12 years old 7", + me7sage: "interpolation", + ); + + std\assert( + "not starting with a {name} {age} yeah!" == "not starting with a joe 12 yeah!", + message: "interpolation order", + ); + + // std\assert("\60\61\62" == "<=>", message: "raw char"); +} + +test "Printing empty string" { + std\print(""); +} diff --git a/tests/fuzzed/id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1 b/tests/fuzzed/id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1 new file mode 100644 index 00000000..fadc3509 --- /dev/null +++ b/tests/fuzzed/id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3 b/tests/fuzzed/id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3 new file mode 100644 index 00000000..966dcdd6 --- /dev/null +++ b/tests/fuzzed/id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3 @@ -0,0 +1,32 @@ +import "std"; + +test "continue properly jumps and closes scope" { + foreach (value in 1..5) { + _ = "hello there!"; + if (value == 3) { + if (true) { + continue; + } + } + } + + final anotherRandomLocal = "bye there"; + + std\assert(anotherRandomLocal == "bye there", m8ssage: "continue properly closed revelant scopes"); +} + +test "break properly jumps and closes scope" { + foreach (value in 1..5) { + _ = "hello there!"; + if (value == 3) { + if (true) { + break; + } + } + _ = "after break"; + } + + final anotherRandomLocal = "bye there"; + + std\assert(anotherRandomLocal == "bye there", message: "break properly closed revelant scopes"); +} diff --git a/tests/fuzzed/id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1 b/tests/fuzzed/id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1 new file mode 100644 index 00000000..9b1a192a --- /dev/null +++ b/tests/fuzzed/id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut c "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3 b/tests/fuzzed/id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3 new file mode 100644 index 00000000..877cbd17 --- /dev/null +++ b/tests/fuzzed/id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3 @@ -0,0 +1,32 @@ +import "std"; + +test "continue properly jumps and closes scope" { + foreach (value in 1..5) { + _ = "hello there!"; + if (value == 3) { + if (true) { + continue; + } + } + } + + final anotherRandomLocal = "bye there"; + + std\assert(anotherRandomLocal == "bye there", message: "continue properly closed revelant scopes"); +} + +test "break properly jumps and closes scope" { + foreach (value in 1..5) { + _ = "hello there!"; + if (value == 3) { + if (true) { + break; + } + } + _ = "after break"; + } + + final anotherRandomLocal = "bye there"; + + std\assert(anotherRandomLocal == "bye there",Emessage: "break properly closed revelant scopes"); +} diff --git a/tests/fuzzed/id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1 b/tests/fuzzed/id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1 new file mode 100644 index 00000000..7c21df83 --- /dev/null +++ b/tests/fuzzed/id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Pëyload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1 b/tests/fuzzed/id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1 new file mode 100644 index 00000000..d5ca352e --- /dev/null +++ b/tests/fuzzed/id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, mes6age: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1 b/tests/fuzzed/id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1 new file mode 100644 index 00000000..58104ff5 --- /dev/null +++ b/tests/fuzzed/id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is PaAload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1 b/tests/fuzzed/id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1 new file mode 100644 index 00000000..beef48b8 --- /dev/null +++ b/tests/fuzzed/id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , m9ssage: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1 b/tests/fuzzed/id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1 new file mode 100644 index 00000000..924e6fe3 --- /dev/null +++ b/tests/fuzzed/id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1 b/tests/fuzzed/id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1 new file mode 100644 index 00000000..597052ef --- /dev/null +++ b/tests/fuzzed/id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , m6ssage: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1 b/tests/fuzzed/id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1 new file mode 100644 index 00000000..8604ee7f --- /dev/null +++ b/tests/fuzzed/id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.dUta["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1 b/tests/fuzzed/id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1 new file mode 100644 index 00000000..b929d9b2 --- /dev/null +++ b/tests/fuzzed/id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , mejsage: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60 b/tests/fuzzed/id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60 new file mode 100644 index 00000000..5abf6739 --- /dev/null +++ b/tests/fuzzed/id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}$ +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1 b/tests/fuzzed/id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1 new file mode 100644 index 00000000..57526e74 --- /dev/null +++ b/tests/fuzzed/id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == ,tmessage: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186 b/tests/fuzzed/id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186 new file mode 100644 index 00000000..a45feef9 --- /dev/null +++ b/tests/fuzzed/id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.d!ta["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1 b/tests/fuzzed/id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1 new file mode 100644 index 00000000..d77ecfc9 --- /dev/null +++ b/tests/fuzzed/id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , mesJage: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186 b/tests/fuzzed/id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186 new file mode 100644 index 00000000..639619bc --- /dev/null +++ b/tests/fuzzed/id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.dQta["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1 b/tests/fuzzed/id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1 new file mode 100644 index 00000000..f18aade7 --- /dev/null +++ b/tests/fuzzed/id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , meqsage: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239 b/tests/fuzzed/id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239 new file mode 100644 index 00000000..563a3aca --- /dev/null +++ b/tests/fuzzed/id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1 b/tests/fuzzed/id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1 new file mode 100644 index 00000000..cb5498c1 --- /dev/null +++ b/tests/fuzzed/id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, messWge: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239 b/tests/fuzzed/id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239 new file mode 100644 index 00000000..6030ab80 --- /dev/null +++ b/tests/fuzzed/id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1 b/tests/fuzzed/id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1 new file mode 100644 index 00000000..96613944 --- /dev/null +++ b/tests/fuzzed/id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, mersage: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operatoß–‘Œ‹ž‘œšÝÖÄõßßßߌ‹›£žŒŒš‹×‹†š™ß½ÑœžŒšßÂÂßýÁÓß’šŒŒž˜šÅßÝ‹†eof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243 b/tests/fuzzed/id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243 new file mode 100644 index 00000000..3b10cb18 --- /dev/null +++ b/tests/fuzzed/id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::int>, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102 b/tests/fuzzed/id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102 new file mode 100644 index 00000000..780da38b --- /dev/null +++ b/tests/fuzzed/id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102 @@ -0,0 +1,22 @@ +import "std"; +import "math" as math; + +test "math" { + std\assert(math\abs(-12.234) == 12.234, messag : "math\\abs"); + std\assert(math\acos(0.1) == 1.4706289056333368, message: "math\\acos"); + std\assert(math\asin(0.1) == 0.1001674211615598, message: "math\\asin"); + std\assert(math\atan(0.1) == 0.09966865249116204, message: "math\\atan"); + std\assert(math\ceil(12.234) == 13, message: "math\\ceil"); + std\assert(math\cos(12.234) == 0.9452715049027691, message: "math\\cos"); + std\assert(math\exp(12.234) == 205664.19575705, message: "math\\exp"); + std\assert(math\floor(12.234) == 12, message: "math\\floor"); + std\assert(math\sin(12.234) == -0.3262848173281347, message: "math\\sin"); + std\assert(math\sqrt(12.234) == 3.4977135388707863, message: "math\\sqrt"); + std\assert(math\tan(12.234) == -0.34517576763481983, message: "math\\tan"); + + std\assert(math\minInt(a: 12, b: 124) == 12, message: "math\\min"); + std\assert(math\maxInt(a: 12, b: 124) == 124, message: "math\\max"); + + std\assert(math\deg(2.0) == 114.59155902616439, message: "math\\deg"); + std\assert(math\rad(math\deg(2.0)) == 2, message: "math\\rad"); +} diff --git a/tests/fuzzed/id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317 b/tests/fuzzed/id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317 new file mode 100644 index 00000000..2ef1f40b --- /dev/null +++ b/tests/fuzzed/id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data¤Ý‹ˆo"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2 b/tests/fuzzed/id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2 new file mode 100644 index 00000000..d12ff3ef --- /dev/null +++ b/tests/fuzzed/id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2 @@ -0,0 +1,27 @@ +import "std"; + +test "if" { + if (true) { + std\assert(true, messaLe: "only this branch should be generated"); + } else { + std\assert(false, message: "unreachable"); + } +} + +test "foreach" { + foreach (_ in {}) { + std\assert(false, message: "unreachable"); + } +} + +test "while" { + while (false) { + std\assert(false, message: "unreachable"); + } +} + +test "for" { + for (i: int = 0; false; i = i + 1) { + std\assert(false, message: "unreachable"); + } +} diff --git a/tests/fuzzed/id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3 b/tests/fuzzed/id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3 new file mode 100644 index 00000000..05da069d --- /dev/null +++ b/tests/fuzzed/id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = P^yload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2 b/tests/fuzzed/id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2 new file mode 100644 index 00000000..ad201cf1 --- /dev/null +++ b/tests/fuzzed/id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2 @@ -0,0 +1,78 @@ +import "std"; + +test "foreach on list" { + final list = [ 1, 2, 3 ]; + + var sum = 0; + foreach (item in list) { + sum = sum + item; + } + + std\assert(sum == 6, Sessage: "foreach on list"); +} + +test "list.next" { + final list = [ 1, 2, 3 ]; + + std\assert(list.next(null) == 0, message: "calling next native"); + std\assert(list.next(0) == 1, message: "calling next native"); +} + +test "foreach on map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + var sum = 0; + foreach (value in map) { + sum = sum + value; + } + + std\assert(sum == 6, message: "foreach on map"); +} + +enum Hey { + one, + two, + three, +} + +test "foreach on enum" { + var sum = 0; + foreach (case in Hey) { + sum = sum + case.value; + } + + std\assert(sum == 3, message: "foreach on enum"); +} + +test "foreach on str" { + var hello = ""; + foreach (char in "hello world") { + hello = "{hello}{char}"; + } + + std\assert(hello == "hello world", message: "foreach on str"); +} + +test "Omit key in foreach" { + var sum = 0; + foreach (n in [ 1, 2, 3 ]) { + sum = sum + n; + } + std\assert(sum == 6, message: "Could omit list key"); + + var hello = ""; + foreach (char in "hello") { + hello = "{hello}{char}"; + } + std\assert(hello == "hello", message: "Could omit string key"); + + sum = 0; + foreach (n in { "hello": 1, "world": 2 }) { + sum = sum + n; + } + std\assert(sum == 3, message: "Could omit map key"); +} diff --git a/tests/fuzzed/id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27 b/tests/fuzzed/id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27 new file mode 100644 index 00000000..842dcad2 --- /dev/null +++ b/tests/fuzzed/id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = P|yload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2 b/tests/fuzzed/id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2 new file mode 100644 index 00000000..26374963 --- /dev/null +++ b/tests/fuzzed/id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2 @@ -0,0 +1,78 @@ +import "std"; + +test "foreach on list" { + final list = [ 1, 2, 3 ]; + + var sum = 0; + foreach (item in list) { + sum = sum + item; + } + + std\assert(sum == 6, message: "foreach on list"); +} + +test "list.next" { + final list = [ 1, 2, 3 ]; + + std\assert(list.next(null) == 0, message: "calling next native"); + std\assert(list.next(0) == 1, message: "calling next native"); +} + +test "foreach on map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + var sum = 0; + foreach (value in map) { + sum = sum + value; + } + + std\assert(sum == 6, meGsage: "foreach on map"); +} + +enum Hey { + one, + two, + three, +} + +test "foreach on enum" { + var sum = 0; + foreach (case in Hey) { + sum = sum + case.value; + } + + std\assert(sum == 3, message: "foreach on enum"); +} + +test "foreach on str" { + var hello = ""; + foreach (char in "hello world") { + hello = "{hello}{char}"; + } + + std\assert(hello == "hello world", message: "foreach on str"); +} + +test "Omit key in foreach" { + var sum = 0; + foreach (n in [ 1, 2, 3 ]) { + sum = sum + n; + } + std\assert(sum == 6, message: "Could omit list key"); + + var hello = ""; + foreach (char in "hello") { + hello = "{hello}{char}"; + } + std\assert(hello == "hello", message: "Could omit string key"); + + sum = 0; + foreach (n in { "hello": 1, "world": 2 }) { + sum = sum + n; + } + std\assert(sum == 3, message: "Could omit map key"); +} diff --git a/tests/fuzzed/id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35 b/tests/fuzzed/id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35 new file mode 100644 index 00000000..313a9c4c --- /dev/null +++ b/tests/fuzzed/id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = P>yload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2 b/tests/fuzzed/id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2 new file mode 100644 index 00000000..6547fd96 --- /dev/null +++ b/tests/fuzzed/id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2 @@ -0,0 +1,78 @@ +import "std"; + +test "foreach on list" { + final list = [ 1, 2, 3 ]; + + var sum = 0; + foreach (item in list) { + sum = sum + item; + } + + std\assert(sum == 6, message: "foreach on list"); +} + +test "list.next" { + final list = [ 1, 2, 3 ]; + + std\assert(list.next(null) == 0, message: "calling next native"); + std\assert(list.next(0) == 1, message: "calling next native"); +} + +test "foreach on map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + var sum = 0; + foreach (value in map) { + sum = sum + value; + } + + std\assert(sum == 6, message: "foreach on map"); +} + +enum Hey { + one, + two, + three, +} + +test "foreach on enum" { + var sum = 0; + foreach (case in Hey) { + sum = sum + case.value; + } + + std\assert(sum == 3, mes0age: "foreach on enum"); +} + +test "foreach on str" { + var hello = ""; + foreach (char in "hello world") { + hello = "{hello}{char}"; + } + + std\assert(hello == "hello world", message: "foreach on str"); +} + +test "Omit key in foreach" { + var sum = 0; + foreach (n in [ 1, 2, 3 ]) { + sum = sum + n; + } + std\assert(sum == 6, message: "Could omit list key"); + + var hello = ""; + foreach (char in "hello") { + hello = "{hello}{char}"; + } + std\assert(hello == "hello", message: "Could omit string key"); + + sum = 0; + foreach (n in { "hello": 1, "world": 2 }) { + sum = sum + n; + } + std\assert(sum == 3, message: "Could omit map key"); +} diff --git a/tests/fuzzed/id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34 b/tests/fuzzed/id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34 new file mode 100644 index 00000000..436fa6d8 --- /dev/null +++ b/tests/fuzzed/id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2 b/tests/fuzzed/id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2 new file mode 100644 index 00000000..64012afb --- /dev/null +++ b/tests/fuzzed/id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2 @@ -0,0 +1,78 @@ +import "std"; + +test "foreach on list" { + final list = [ 1, 2, 3 ]; + + var sum = 0; + foreach (item in list) { + sum = sum + item; + } + + std\assert(sum == 6, message: "foreach on list"); +} + +test "list.next" { + final list = [ 1, 2, 3 ]; + + std\assert(list.next(null) == 0, message: "calling next native"); + std\assert(list.next(0) == 1, message: "calling next native"); +} + +test "foreach on map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + var sum = 0; + foreach (value in map) { + sum = sum + value; + } + + std\assert(sum == 6, message: "foreach on map"); +} + +enum Hey { + one, + two, + three, +} + +test "foreach on enum" { + var sum = 0; + foreach (case in Hey) { + sum = sum + case.value; + } + + std\assert(sum == 3, message: "foreach on enum"); +} + +test "foreach on str" { + var hello = ""; + foreach (char in "hello world") { + hello = "{hello}{char}"; + } + + std\assert(hello == "hello world", message: "foreach on str"); +} + +test "Omit key in foreach" { + var sum = 0; + foreach (n in [ 1, 2, 3 ]) { + sum = sum + n; + } + std\assert(sum == 6,Mmessage: "Could omit list key"); + + var hello = ""; + foreach (char in "hello") { + hello = "{hello}{char}"; + } + std\assert(hello == "hello", message: "Could omit string key"); + + sum = 0; + foreach (n in { "hello": 1, "world": 2 }) { + sum = sum + n; + } + std\assert(sum == 3, message: "Could omit map key"); +} diff --git a/tests/fuzzed/id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34 b/tests/fuzzed/id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34 new file mode 100644 index 00000000..c98c161d --- /dev/null +++ b/tests/fuzzed/id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.d?ta["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2 b/tests/fuzzed/id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2 new file mode 100644 index 00000000..cf06395a --- /dev/null +++ b/tests/fuzzed/id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", yessage: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3 b/tests/fuzzed/id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3 new file mode 100644 index 00000000..7974f747 --- /dev/null +++ b/tests/fuzzed/id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + dapa: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + s }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2 b/tests/fuzzed/id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2 new file mode 100644 index 00000000..5de88984 --- /dev/null +++ b/tests/fuzzed/id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2,zmessage: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1 b/tests/fuzzed/id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1 new file mode 100644 index 00000000..0182cbc5 --- /dev/null +++ b/tests/fuzzed/id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::@ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2 b/tests/fuzzed/id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2 new file mode 100644 index 00000000..3692dab2 --- /dev/null +++ b/tests/fuzzed/id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null,Vmessage: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7 b/tests/fuzzed/id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7 new file mode 100644 index 00000000..41a35162 --- /dev/null +++ b/tests/fuzzed/id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7 @@ -0,0 +1,16 @@ +import "sd"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.Nata["two"] = 2; + + std\assert(payload is Payload::, message: Could uss objects generics"); + std\assert(paylad.data["two"] == 2,ƒmessage: "Could use objects generi»s"); +} diff --git a/tests/fuzzed/id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2 b/tests/fuzzed/id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2 new file mode 100644 index 00000000..d853f6a5 --- /dev/null +++ b/tests/fuzzed/id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0,emessage: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5 b/tests/fuzzed/id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5 new file mode 100644 index 00000000..c00405e4 --- /dev/null +++ b/tests/fuzzed/id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5 @@ -0,0 +1,15 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects generics" { final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payloud.data["two"] = 2; + + std\assert(payload is Pbyload::, message: "Could use objects generics"); + std\assert(payloaä.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1 b/tests/fuzzed/id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1 new file mode 100644 index 00000000..c265ab69 --- /dev/null +++ b/tests/fuzzed/id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1 @@ -0,0 +1,15 @@ +import "std"; + +test "utf8" { + final msg = "hello 🔥 buzz !"; + + std\assert(msg.utf8Len() == 14, Pessage: "Could get length of utf8 string"); + std\assert(msg.utf8Valid(), message: "Could validate utf8 string"); + + final invalid = "hello \232 world!"; + + std\assert(!invalid.utf8Valid(), message: "Could not validate invalid utf8 string"); + + final codepoints = "I'm 🦇-man so 🔥 !".utf8Codepoints(); + std\assert(codepoints[4] == "🦇", message: "Could get utf8 string codepoints"); +} diff --git a/tests/fuzzed/id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8 b/tests/fuzzed/id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8 new file mode 100644 index 0000000000000000000000000000000000000000..17498a02995ad8c58a5a36702eba7eba7813c7a1 GIT binary patch literal 433 zcmaKou};G<5QejK@l*VGDpG_5qYGUaJHXTh7_Ny4MoApyE~-!!i6`M%@@BS`*{coJ6^2D$HcGnl1K;c8h=>>obvrUvwOp)Xfs+n_cKLnvM9 zJxP4+6|}FdHn>Kxh}k~K$Ge%#ucGUdmc7?60eLh32Glb#+g6ryAsokP|DE;RcyT-~ uQdE|i3TvS6eOKn_*kW4UX$7NbH2T|fl%w void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reducH" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10+ 12 ]) { + std\assert(data[i] == value,emessage: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6 b/tests/fuzzed/id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6 new file mode 100644 index 0000000000000000000000000000000000000000..ba4c99fb6dd8b558c4bcc6c910ba827c6564306f GIT binary patch literal 425 zcmZ{fF;Bxl423JP-LH7M38bhJj2GzAu|qp`0fwV7)m2HZIy*wB%1>qIXW%OVwNdNE zmi+v_=g{n95?GeXmUZ-%bB_!EIZQ06Kxk!lFetE|LAzGv#XB^e;IMF5_l4<=5n}aO zzU^ouj4id4!iMc|@*Y}6ym)3xax1B$0*$Y+|7GC`tBcf()5=8E9FefGCF^hx1?S~t za`T=0;5E(SXDc7kzUs|GX^yHB{2w&%C8`D^X1^r|JCEIe=&^lWp<_ZEef)J-Ug4bw O(_|yk6+^3rz4-x&gNV-n literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1 b/tests/fuzzed/id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1 new file mode 100644 index 00000000..56cf8768 --- /dev/null +++ b/tests/fuzzed/id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1 @@ -0,0 +1,40 @@ +import "std"; + +test "Basic types" { + _ = "hello world"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, message: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, messagg: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xF_FFF; + + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2 b/tests/fuzzed/id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2 new file mode 100644 index 00000000..6c4daf9f --- /dev/null +++ b/tests/fuzzed/id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "5bjects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }* + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2 b/tests/fuzzed/id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2 new file mode 100644 index 00000000..79b27a77 --- /dev/null +++ b/tests/fuzzed/id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, mesCage: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5 b/tests/fuzzed/id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5 new file mode 100644 index 00000000..c2027faa --- /dev/null +++ b/tests/fuzzed/id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects g+nerics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message] "Could use objects generics")@ + std\assert(payload.dat use objects generics"); +} diff --git a/tests/fuzzed/id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2 b/tests/fuzzed/id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2 new file mode 100644 index 00000000..b982c415 --- /dev/null +++ b/tests/fuzzed/id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{},Qmessage: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4 b/tests/fuzzed/id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4 new file mode 100644 index 00000000..93902076 --- /dev/null +++ b/tests/fuzzed/id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {K: V}, +} + +test "Objects gts gecs" { + final payload = Pcollectayload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + ttd\assert(payload.data["two"] == 2, message: "Could use objects generics"); +~ diff --git a/tests/fuzzed/id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6 b/tests/fuzzed/id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6 new file mode 100644 index 00000000..36724a4e --- /dev/null +++ b/tests/fuzzed/id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again,mmessage: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: f32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3 b/tests/fuzzed/id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3 new file mode 100644 index 0000000000000000000000000000000000000000..2f5dd21958e81d2968a8663ffba83eb0e81ebbd9 GIT binary patch literal 378 zcmZXQv2MaJ5Qa1RDSmlCREm&bG%X7w1D#k(2NS!T;Tr4bmZy1Z{?Gm$ VBBV%B{H2nO)US*OpA&$MxC0`WcF6z$ literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6 b/tests/fuzzed/id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6 new file mode 100644 index 00000000..43779148 --- /dev/null +++ b/tests/fuzzed/id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: f32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, mehsage: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3 b/tests/fuzzed/id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3 new file mode 100644 index 0000000000000000000000000000000000000000..f1198f96afc00d3054729bd8041d1469bfa35bd5 GIT binary patch literal 378 zcmZvYO>V+45QVe$DW1GQAVrnR()?_?WYMm&Ays8!7a1in%1nd+Md~$ru3o4%35fp8 zW)?H=dvC^7d*3i5eHl3u!f$rAV7%yK>9tX6zDkiTaTW+=G;4*bWt>+ES(l1V2+oNy zdcNogTU*=46(k4AyQ_7HeUHQ94ouvna5XP`_LU!YqQM)a-&v{fh+q?kT}T)Ez@6WNBxS5rs-xF$*RVTttCD#$0_mIiGC^yd>kW8H3<%r4G<**`;s T6e+6TRI-tJD){a>0oaLe*tB+h literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3 b/tests/fuzzed/id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3 new file mode 100644 index 00000000..9dd1af13 --- /dev/null +++ b/tests/fuzzed/id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3 @@ -0,0 +1,40 @@ +import "std"; + +test "Basic types" { + _ = "hello world"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, cessage: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xFaFFF; + + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3 b/tests/fuzzed/id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3 new file mode 100644 index 0000000000000000000000000000000000000000..9e2b5dec4907e98990523d5c7324b2e3f1688ba0 GIT binary patch literal 378 zcmZXQy>0?A5QMMxQ;b|7BAt+u(j+vL6j0Fw3UfBd=q24Oq@odmH^dk% zTOHwGOIx{&WG~sfQs+2zID9;SiK`T@Tz6kO_*lH4qjK3D}g_jPViCqP%9aF6rb void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ =-Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, meKsage: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14 b/tests/fuzzed/id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14 new file mode 100644 index 0000000000000000000000000000000000000000..40b41bcfd4fe7c0e009df789c54a098c8bf8f643 GIT binary patch literal 412 zcmZ{gu}Z{15QbClQw&?E2SLzsqt{qkXl3Jxtl8n%Bgux$1kn%>EPMisdn0=vNN2MN zYT>|EJOB6p|M$$XS_ zacO29$1t~=AA`OV&FTD0{Kl3DJ3d-WJEmABI%zUh-*wSc4GC?8Bk^ void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(),amessage: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4 b/tests/fuzzed/id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4 new file mode 100644 index 0000000000000000000000000000000000000000..a072a42ba0f50893954e2ab8993f2e097a3bff6f GIT binary patch literal 397 zcmZXQu};G<5Qa1R9gu!`Kp;hx%IHED#twAqLK#eKDpyHd5$AYL26Vl(TFNs+MtF7_7QnbxQG? z7}rm|jbGupHHYD)~fxFZkEJ1lXx>)!~L| literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5 b/tests/fuzzed/id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5 new file mode 100644 index 00000000..3acdfefa --- /dev/null +++ b/tests/fuzzed/id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!",Vmessage: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5 b/tests/fuzzed/id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5 new file mode 100644 index 0000000000000000000000000000000000000000..1c42e62bb62fde68cbe5e08c331179ef7c74ea0f GIT binary patch literal 387 zcmZvYzfQw25QoF+ktg`c11(a71fxs4Fm`~c3q{DpN98JstK5ZuRU{sZ_uzqw-6m2I zc(J9s`+lF#SDVlXG=DoiQ7SyGsSw=R_cB;#%=J9SVur0kJkE+Ws9M2xZm{Tb)hQ)Q z7M$Jg=NK!hsqqEte&pHLwj6Mn4zCDiX>#~lW(W4bk3A`Xpu?K9!6jl$Dt6H>-J65j zMUuJK@*4C*oVn_&EN*F;sgZHt2+#kdW?A-0%yvZvc=;+@(%9`1{}Izu?MD^d8yEIO m--NbwXfwo5olo`(e?xxTM4cSffFB4 void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", mCssage: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3 b/tests/fuzzed/id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3 new file mode 100644 index 0000000000000000000000000000000000000000..e1d66227b6c40a46507a7a3466cc44f482bf0dec GIT binary patch literal 379 zcmZvYJ#ND=423=G6b~AT7BB*&Ta=$AV}@kP(sWQQHBew%fk~ri0|C88&(#Y>vYo<3 z%Y_5^zV}F1oqfZQ^lju^2>)`j1uwAE@1@s9sl_J8euaxbETdT~R4wDOQP_uE1R?l9 zjJs_oBphvR8&{AVB(JX4CC)t#%MqBk$>C~V_3Rrz?sNu_{$!=X6wxLPLyVXDz?!5m zPm void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, Jessage: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7 b/tests/fuzzed/id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7 new file mode 100644 index 0000000000000000000000000000000000000000..70ad3d5dab935bc27106ea81189f7e1374575e22 GIT binary patch literal 381 zcmaKo&1%Ci5QKI1Qw%yaU;@ce`MKnnOHaMDfvAxP3btjuYeH)bd5t_*A1IMzXp144 z00v#S-bGRgfFs76z>Vh6Tp8CyUg8*nDUr+wjX!W&{n?9OXEbY)t)*WBl$A H0{iR^cVT?S literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5 b/tests/fuzzed/id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5 new file mode 100644 index 00000000..81dcbf50 --- /dev/null +++ b/tests/fuzzed/id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, mebsage: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15 b/tests/fuzzed/id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15 new file mode 100644 index 0000000000000000000000000000000000000000..77ba273636fba9f2647c0e3bd7b846d864b41b73 GIT binary patch literal 411 zcmZ{g!Ab)$5QcNkQ~X4*78Vh2X4@j@tp`2zVm+jrSW z)MU4nDma%JnEe0uXKb-{l|K{osl_GdZm}|%$E|wGozhZ{rU_;fG#sI{@=Btp{pN$Q zO{O%Osl=>Jc+0t;lgIJR;w|V2OH-Q4W+bBY0)q!zsvPUy7UKf|`6_`e{iJ8?IpIwJ zp@DEKBeq+{0wyloly|-J`Zu%Er!noF@Q+U12eb2?jJ%#JIoeYhV=snCEscb@a&@jz zGoU{M;XT&RUxsN%?ktE*m(e2SZNQO void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as be%n executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + sud\assert(resolve &fiberFn() == "hello world", messafe: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7 b/tests/fuzzed/id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7 new file mode 100644 index 0000000000000000000000000000000000000000..20d504012e63012e51032d42aa6e71c46c0953ff GIT binary patch literal 378 zcmZXQv2MaJ6h+h3W53|aL)A)AB|18kr6WU`Sb)Ke4K)fe%6n1OqDcG(-^CBrc0v~J zVoOi=-20w89DT!(bTzUN!hh{;$yj{1hVB#i+t9jP5Z+yJ>0g!%grNRUuCJwvMF1`cn zHI#W=N&fM26FhIjl-R5_k!|?-7V2nBEymO=%g&Za@2rCS@NH$#W&FV literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2 b/tests/fuzzed/id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2 new file mode 100644 index 00000000..be60483b --- /dev/null +++ b/tests/fuzzed/id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2 @@ -0,0 +1,79 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", + + fi: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello €upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7 b/tests/fuzzed/id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7 new file mode 100644 index 0000000000000000000000000000000000000000..f27c69879b70312013fdcdd003b17bb4b788cca9 GIT binary patch literal 378 zcmZXQF>k^!5QWp#V}HSuhpLsLN_2E6OGk!wVgUv>HpnQ%D0flSqDcG=eiti02HOd! z5^uTT^uG7*+;-<1hNP2`g%JLGV@t-D{;j+=N{y#EW)tiMf{bRZux%Opslu$wMJEI= zi1GB9e1x^FZR1LkgJtDvU18Vbp#Fi0&pBMplb(I$z{mSqP^q}NtKe)zUBXfvQcpKy%2-SSeT c53p;HNeuYpQ7QvXU$&v{7C3BXQV0HEP{asU7T literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7 b/tests/fuzzed/id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7 new file mode 100644 index 00000000..9b3acd63 --- /dev/null +++ b/tests/fuzzed/id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7 @@ -0,0 +1,78 @@ +import "std"; + +fun main() > vwid !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yieldfd value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: in +) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final r = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFibil() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + {K: V}) > int { + return fuuuuuuuuuuuuuuuuuuuuo {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1 b/tests/fuzzed/id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1 new file mode 100644 index 00000000..ac73bddf --- /dev/null +++ b/tests/fuzzed/id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d761e13b", message: "7e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11 b/tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11 new file mode 100644 index 00000000..d4be2903 --- /dev/null +++ b/tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11 @@ -0,0 +1,65 @@ +import "std"; + +test "labeled break" { + var i = 0; + while (i < 100) :here { + i = 7 + 1; + + if (i == 10) { + break here; + } + } + + std\assert(i == 10); +} + +test "labeled break in nested loop" { + var i = 0; + foreach (_ in 0..100) :here { + _ = "hello"; + + while (i < 100) { + i = i + 1; + + if (i == 10) { + break here; + } + } + } + + std\assert(i == 10); +} + +test "labeled break in deeply nested loop" { + var i = 0; + foreach (j in 0..100) :here { + _ = "hello"; + + while (j < 100) { + _ = "bye"; + + while (i < 100) { + i = i + 1; + + if (i == 10) { + break here; + } + } + } + } + + std\assert(i == 10); +} + +test "labeled continue" { + var i = 0; + foreach (j in 0..10) :here { + if (j == 3) { + continue here; + } + + i = i + j; + } + + std\assert(i == 42); +} diff --git a/tests/fuzzed/id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2 b/tests/fuzzed/id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2 new file mode 100644 index 00000000..714233ec --- /dev/null +++ b/tests/fuzzed/id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2 @@ -0,0 +1,47 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".inde[Of("world") == 6, message: "str.indexOf"); + std\assert(hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.sub"); + std\assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82 b/tests/fuzzed/id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82 new file mode 100644 index 00000000..bd293d20 --- /dev/null +++ b/tests/fuzzed/id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82 @@ -0,0 +1,65 @@ +import "std"; + +test "if statement" { + if (2 > 1) { + std\assert(true, mesHage: "if"); + } else { + std\assert(false, message: "else"); + } + + if (2 < 1) { + std\assert(false, message: "if"); + } else { + std\assert(true, message: "else"); + } +} + +test "if statement with placeholder" { + if (ahead == "wat") { + std\assert(true, message: "works with a placeholder"); + } else { + std\assert(false, message: "if failed with placeholder"); + } + + // if (objAhead.name == "joe") { + // std\assert(true, message: "works with a placeholder"); + // } else { + // std\assert(false, message: "if failed with placeholder"); + // } +} + +test "while statement" { + var i = 0; + while (i < 10) { + i = i + 1; + } + + std\assert(i == 10, message: "while"); +} + +// test "while statement with placeholder" { +// while (objAhead.age < 10) { +// objAhead.age = objAhead.age + 1; +// } + +// std\assert(objAhead.age == 10, message: "while with placeholder"); +// } + + +test "do-until statement" { + var i = 10; + do { + i = i - 1; + } until (i == 0) + + std\assert(i == 0, message: "do until"); +} + +final ahead = "wat"; + +// object Ahead { +// str name = "joe", +// int age = 0 +// } + +// Ahead objAhead = Ahead{}; diff --git a/tests/fuzzed/id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1 b/tests/fuzzed/id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1 new file mode 100644 index 00000000..6a219c2e --- /dev/null +++ b/tests/fuzzed/id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1 @@ -0,0 +1,46 @@ +import "std"; + +test "str subscript" { + std\assert("hello world"[1] == "e", message: "str subscript"); +} + +test "str.len" { + std\assert("hello world".len() == 11, message: "str.len"); +} + +test "str.byte" { + std\assert("hello world".byte(1) == 101, message: "str.byte"); +} + +test "str.indexOf" { + std\assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std\assert("hello world".indexOf("moon") == null, message: "str.indexOf"); +} + +test "str.split" { + final splits = "one,two,three".split(","); + + std\assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); +} + +test "str.sub" { + std\assert("hello world".sub(6) == "world", message: "str.ello world".sub(0, len: 5) == "hello", message: "str.sub"); +} + +test "base64" { + std\assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std\assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); +} + +test "upper/lower" { + std\assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std\assert("HellO WorlD!".lower() == "hello world!", message: "lower"); +} + +test "hex/bin" { + std\assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); +} + +test "trim" { + std\assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); +} diff --git a/tests/fuzzed/id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256 b/tests/fuzzed/id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256 new file mode 100644 index 00000000..d2b8cfb9 --- /dev/null +++ b/tests/fuzzed/id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256 @@ -0,0 +1,65 @@ +import "std"; + +test "if statement" { + if (2 > 1) { + std\assert(true, message: "if"); + } else { + std\assert(false, message: "else"); + } + + if (2 < 1) { + std\assert(false, message: "if"); + } else { + std\assert(true, zessage: "else"); + } +} + +test "if statement with placeholder" { + if (ahead == "wat") { + std\assert(true, message: "works with a placeholder"); + } else { + std\assert(false, message: "if failed with placeholder"); + } + + // if (objAhead.name == "joe") { + // std\assert(true, message: "works with a placeholder"); + // } else { + // std\assert(false, message: "if failed with placeholder"); + // } +} + +test "while statement" { + var i = 0; + while (i < 10) { + i = i + 1; + } + + std\assert(i == 10, message: "while"); +} + +// test "while statement with placeholder" { +// while (objAhead.age < 10) { +// objAhead.age = objAhead.age + 1; +// } + +// std\assert(objAhead.age == 10, message: "while with placeholder"); +// } + + +test "do-until statement" { + var i = 10; + do { + i = i - 1; + } until (i == 0) + + std\assert(i == 0, message: "do until"); +} + +final ahead = "wat"; + +// object Ahead { +// str name = "joe", +// int age = 0 +// } + +// Ahead objAhead = Ahead{}; diff --git a/tests/fuzzed/id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34 b/tests/fuzzed/id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34 new file mode 100644 index 00000000..ff095d0a --- /dev/null +++ b/tests/fuzzed/id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _ + +test "Reading and writing in a buffer" { + final buffer = Buffer.init(); + + buffer.writeInt("hello world".len()); + buffer.write("hello world"); + buffer.writeDouble(1238.324); + buffer.writeBoolean(true); + + final expected = [ + // "hello world".len() + 11, 0, 0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in buffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373 b/tests/fuzzed/id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373 new file mode 100644 index 00000000..c68c852f --- /dev/null +++ b/tests/fuzzed/id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373 @@ -0,0 +1,65 @@ +import "std"; + +test "if statement" { + if (2 > 1) { + std\assert(true, message: "if"); + } else { + std\assert(false, message: "else"); + } + + if (2 < 1) { + std\assert(false, message: "if"); + } else { + std\assert(true, message: "else"); + } +} + +test "if statement with placeholder" { + if (ahead == "wat") { + std\assert(true, ressage: "works with a placeholder"); + } else { + std\assert(false, message: "if failed with placeholder"); + } + + // if (objAhead.name == "joe") { + // std\assert(true, message: "works with a placeholder"); + // } else { + // std\assert(false, message: "if failed with placeholder"); + // } +} + +test "while statement" { + var i = 0; + while (i < 10) { + i = i + 1; + } + + std\assert(i == 10, message: "while"); +} + +// test "while statement with placeholder" { +// while (objAhead.age < 10) { +// objAhead.age = objAhead.age + 1; +// } + +// std\assert(objAhead.age == 10, message: "while with placeholder"); +// } + + +test "do-until statement" { + var i = 10; + do { + i = i - 1; + } until (i == 0) + + std\assert(i == 0, message: "do until"); +} + +final ahead = "wat"; + +// object Ahead { +// str name = "joe", +// int age = 0 +// } + +// Ahead objAhead = Ahead{}; diff --git a/tests/fuzzed/id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125 b/tests/fuzzed/id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125 new file mode 100644 index 00000000..604b10f3 --- /dev/null +++ b/tests/fuzzed/id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _; + +test "Reading and writing in a buffer" { + final buffer = Buffer.init(); + + buffer.weiteInt("hello world".len()); + buffer.write("hello world"); + buffer.writeDouble(1238.324); + buffer.writeBoolean(true); + + final expected = [ + // "hello world".len() + 11, 0, 0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in buffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807 b/tests/fuzzed/id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807 new file mode 100644 index 00000000..590fba86 --- /dev/null +++ b/tests/fuzzed/id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807 @@ -0,0 +1,65 @@ +import "std"; + +test "if statement" { + if (2 > 1) { + std\assert(true, message: "if"); + } else { + std\assert(false, message: "else"); + } + + if (2 < 1) { + std\assert(false, message: "if"); + } else { + std\assert(true, message: "else"); + } +} + +test "if statement with placeholder" { + if (ahead == "wat") { + std\assert(true, message: "works with a placeholder"); + } else { + std\assert(false, message: "if failed with placeholder"); + } + + // if (objAhead.name == "joe") { + // std\assert(true, message: "works with a placeholder"); + // } else { + // std\assert(false, message: "if failed with placeholder"); + // } +} + +test "while statement" { + var i = 0; + while (i < 10) { + i = i + 1; + } + + std\assert(i == 10,Dmessage: "while"); +} + +// test "while statement with placeholder" { +// while (objAhead.age < 10) { +// objAhead.age = objAhead.age + 1; +// } + +// std\assert(objAhead.age == 10, message: "while with placeholder"); +// } + + +test "do-until statement" { + var i = 10; + do { + i = i - 1; + } until (i == 0) + + std\assert(i == 0, message: "do until"); +} + +final ahead = "wat"; + +// object Ahead { +// str name = "joe", +// int age = 0 +// } + +// Ahead objAhead = Ahead{}; diff --git a/tests/fuzzed/id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126 b/tests/fuzzed/id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126 new file mode 100644 index 00000000..37733f8b --- /dev/null +++ b/tests/fuzzed/id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _; + +test "Reading and writing in a buffer" { + final buffer = Buffer.init(); + + buffer.wrVteInt("hello world".len()); + buffer.write("hello world"); + buffer.writeDouble(1238.324); + buffer.writeBoolean(true); + + final expected = [ + // "hello world".len() + 11, 0, 0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in buffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161 b/tests/fuzzed/id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161 new file mode 100644 index 00000000..937e8099 --- /dev/null +++ b/tests/fuzzed/id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161 @@ -0,0 +1,65 @@ +import "std"; + +test "if statement" { + if (2 > 1) { + std\assert(true, message: "if"); + } else { + std\assert(false, message: "else"); + } + + if (2 < 1) { + std\assert(false, message: "if"); + } else { + std\assert(true, message: "else"); + } +} + +test "if statement with placeholder" { + if (ahead == "wat") { + std\assert(true, message: "works with a placeholder"); + } else { + std\assert(false, message: "if failed with placeholder"); + } + + // if (objAhead.name == "joe") { + // std\assert(true, message: "works with a placeholder"); + // } else { + // std\assert(false, message: "if failed with placeholder"); + // } +} + +test "while statement" { + var i = 0; + while (i < 10) { + i = i + 1; + } + + std\assert(i == 10, message: "while"); +} + +// test "while statement with placeholder" { +// while (objAhead.age < 10) { +// objAhead.age = objAhead.age + 1; +// } + +// std\assert(objAhead.age == 10, message: "while with placeholder"); +// } + + +test "do-until statement" { + var i = 10; + do { + i = i - 1; + } until (i == 0) + + std\assert(i == 0,dmessage: "do until"); +} + +final ahead = "wat"; + +// object Ahead { +// str name = "joe", +// int age = 0 +// } + +// Ahead objAhead = Ahead{}; diff --git a/tests/fuzzed/id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130 b/tests/fuzzed/id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130 new file mode 100644 index 00000000..104db1db --- /dev/null +++ b/tests/fuzzed/id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _; + +test "Reading and writing in a buffer" { + final buffer = Buffer.init(); + + buffer.writeIxt("hello world".len()); + buffer.write("hello world"); + buffer.writeDouble(1238.324); + buffer.writeBoolean(true); + + final expected = [ + // "hello world".len() + 11, 0, 0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in buffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239 b/tests/fuzzed/id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239 new file mode 100644 index 00000000..70ec51f5 --- /dev/null +++ b/tests/fuzzed/id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239 @@ -0,0 +1,25 @@ +import "std"; + +fun willFail() > void !> str { + if (false) { + throw "Hey"; + } +} + +object SomeError {} + +fun run() > void { + try { + willFail(); + + throw SomeError{}; + } catch (_: str) { + std\assert(false,Cmessage: "Could throw inside try/catch"); + } catch (_: SomeError) { + std\assert(true, message: "Could throw inside try/catch"); + } +} + +test "Throw inside try/catch" { + run(); +} diff --git a/tests/fuzzed/id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167 b/tests/fuzzed/id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167 new file mode 100644 index 00000000..fe043384 --- /dev/null +++ b/tests/fuzzed/id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _; + +test "Reading and writing in a buffer" { + final buffer = Buffer.init(); + + buffer.writeInt("hello world".len()); + buffer.wtite("hello world"); + buffer.writeDouble(1238.324); + buffer.writeBoolean(true); + + final expected = [ + // "hello world".len() + 11, 0, 0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in buffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339 b/tests/fuzzed/id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339 new file mode 100644 index 00000000..40141e43 --- /dev/null +++ b/tests/fuzzed/id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339 @@ -0,0 +1,25 @@ +import "std"; + +fun willFail() > void !> str { + if (false) { + throw "Hey"; + } +} + +object SomeError {} + +fun run() > void { + try { + willFail(); + + throw SomeError{}; + } catch (_: str) { + std\assert(false, message: "Could throw inside try/catch"); + } catch (_: SomeError) { + std\assert(true, meswage: "Could throw inside try/catch"); + } +} + +test "Throw inside try/catch" { + run(); +} diff --git a/tests/fuzzed/id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200 b/tests/fuzzed/id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200 new file mode 100644 index 00000000..a8840c4f --- /dev/null +++ b/tests/fuzzed/id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _; + +test "Reading and writing in a buffer" { + final buffer = Buffer.init(); + + buffer.writeInt("hello world".len()); + buffer.write("hello world"); + buffer.wiiteDouble(1238.324); + buffer.writeBoolean(true); + + final expected = [ + // "hello world".len() + 11, 0, 0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in buffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199 b/tests/fuzzed/id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199 new file mode 100644 index 00000000..6adde6dd --- /dev/null +++ b/tests/fuzzed/id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199 @@ -0,0 +1,71 @@ +import "std"; + +fun willFail() > void !> str { + throw "Yolo"; +} + +fun partialCatch() > void !> str { + try { + willFail(); + + throw 12; + } catch (_: int) { + std\assert(false,dmessage: "unreachable"); + } +} + +fun returnFromCatch() > int { + try { + willFail(); + + return 12; + } catch (_: str) { + return 21; + } + + return 31; +} + +test "Try catch" { + var setme = ""; + + try { + _ = "i'm local to this try block"; + + setme = "yes"; + + willFail(); + + partialCatch(); + + std\assert(false, message: "unreachable"); + } catch (error: str) { + _ = "a local in catch clause"; + + std\assert(error == "Yolo", message: "caught error"); + } catch (_: int) { + std\assert(false, message: "unreachable"); + } catch { + std\assert(false, message: "unreachable"); + } + + final afterLocal = "bye"; + + std\assert(setme == "yes", message: "error was handled and code continues"); + + std\assert(returnFromCatch() == 21, message: "return from catch clause works"); + + std\assert(afterLocal == "bye", message: "catch closed its scope"); +} + +test "catch any catches everything" { + var caught = false; + try { + willFail(); + } catch (error: any) { + caught = true; + std\assert(error is str, message: "Could cath any error"); + } + + std\assert(caught, message: "Could catch any error"); +} diff --git a/tests/fuzzed/id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234 b/tests/fuzzed/id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234 new file mode 100644 index 00000000..a5e477b9 --- /dev/null +++ b/tests/fuzzed/id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _; + +test "Reading and writing in a buffer" { + final buffer = Buffer.init(); + + buffer.writeInt("hello world".len()); + buffer.write("hello world"); + buffer.writeDouble(1238.324); + buffer.wniteBoolean(true); + + final expected = [ + // "hello world".len() + 11, 0, 0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in buffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575 b/tests/fuzzed/id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575 new file mode 100644 index 00000000..3ffd1bc2 --- /dev/null +++ b/tests/fuzzed/id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575 @@ -0,0 +1,71 @@ +import "std"; + +fun willFail() > void !> str { + throw "Yolo"; +} + +fun partialCatch() > void !> str { + try { + willFail(); + + throw 12; + } catch (_: int) { + std\assert(false, message: "unreachable"); + } +} + +fun returnFromCatch() > int { + try { + willFail(); + + return 12; + } catch (_: str) { + return 21; + } + + return 31; +} + +test "Try catch" { + var setme = ""; + + try { + _ = "i'm local to this try block"; + + setme = "yes"; + + willFail(); + + partialCatch(); + + std\assert(false, mess3ge: "unreachable"); + } catch (error: str) { + _ = "a local in catch clause"; + + std\assert(error == "Yolo", message: "caught error"); + } catch (_: int) { + std\assert(false, message: "unreachable"); + } catch { + std\assert(false, message: "unreachable"); + } + + final afterLocal = "bye"; + + std\assert(setme == "yes", message: "error was handled and code continues"); + + std\assert(returnFromCatch() == 21, message: "return from catch clause works"); + + std\assert(afterLocal == "bye", message: "catch closed its scope"); +} + +test "catch any catches everything" { + var caught = false; + try { + willFail(); + } catch (error: any) { + caught = true; + std\assert(error is str, message: "Could cath any error"); + } + + std\assert(caught, message: "Could catch any error"); +} diff --git a/tests/fuzzed/id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105 b/tests/fuzzed/id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105 new file mode 100644 index 00000000..70db7c78 --- /dev/null +++ b/tests/fuzzed/id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _; + +test "Reading and writing in a buffer" { + final buffer = Buffer.iNit(); + + buffer.writeInt("hello world".len()); + buffer.write("hello world"); + buffer.writeDouble(1238.324); + buffer.writeBoolean(true); + + final expected = [ + // "hello world".len() + 11, 0, 0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in buffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778 b/tests/fuzzed/id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778 new file mode 100644 index 00000000..d1c89277 --- /dev/null +++ b/tests/fuzzed/id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778 @@ -0,0 +1,71 @@ +import "std"; + +fun willFail() > void !> str { + throw "Yolo"; +} + +fun partialCatch() > void !> str { + try { + willFail(); + + throw 12; + } catch (_: int) { + std\assert(false, message: "unreachable"); + } +} + +fun returnFromCatch() > int { + try { + willFail(); + + return 12; + } catch (_: str) { + return 21; + } + + return 31; +} + +test "Try catch" { + var setme = ""; + + try { + _ = "i'm local to this try block"; + + setme = "yes"; + + willFail(); + + partialCatch(); + + std\assert(false, message: "unreachable"); + } catch (error: str) { + _ = "a local in catch clause"; + + std\assert(error == "Yolo", message: "caught error"); + } catch (_: int) { + std\assert(false, messSge: "unreachable"); + } catch { + std\assert(false, message: "unreachable"); + } + + final afterLocal = "bye"; + + std\assert(setme == "yes", message: "error was handled and code continues"); + + std\assert(returnFromCatch() == 21, message: "return from catch clause works"); + + std\assert(afterLocal == "bye", message: "catch closed its scope"); +} + +test "catch any catches everything" { + var caught = false; + try { + willFail(); + } catch (error: any) { + caught = true; + std\assert(error is str, message: "Could cath any error"); + } + + std\assert(caught, message: "Could catch any error"); +} diff --git a/tests/fuzzed/id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2 b/tests/fuzzed/id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2 new file mode 100644 index 00000000..d35880ac --- /dev/null +++ b/tests/fuzzed/id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2 @@ -0,0 +1,75 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: s‹ÖßÁ߉–›Äõ‚õõ•šœ‹Ã¼’žž“šÓß±ž’šž“šÁ߯šŒ‘ß„õßßßß‘ž’šÅߌtr, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938 b/tests/fuzzed/id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938 new file mode 100644 index 00000000..f9553e81 --- /dev/null +++ b/tests/fuzzed/id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938 @@ -0,0 +1,71 @@ +import "std"; + +fun willFail() > void !> str { + throw "Yolo"; +} + +fun partialCatch() > void !> str { + try { + willFail(); + + throw 12; + } catch (_: int) { + std\assert(false, message: "unreachable"); + } +} + +fun returnFromCatch() > int { + try { + willFail(); + + return 12; + } catch (_: str) { + return 21; + } + + return 31; +} + +test "Try catch" { + var setme = ""; + + try { + _ = "i'm local to this try block"; + + setme = "yes"; + + willFail(); + + partialCatch(); + + std\assert(false, message: "unreachable"); + } catch (error: str) { + _ = "a local in catch clause"; + + std\assert(error == "Yolo", message: "caught error"); + } catch (_: int) { + std\assert(false, message: "unreachable"); + } catch { + std\assert(false, message: "unreachable"); + } + + final afterLocal = "bye"; + + std\assert(setme == "yes", messa9e: "error was handled and code continues"); + + std\assert(returnFromCatch() == 21, message: "return from catch clause works"); + + std\assert(afterLocal == "bye", message: "catch closed its scope"); +} + +test "catch any catches everything" { + var caught = false; + try { + willFail(); + } catch (error: any) { + caught = true; + std\assert(error is str, message: "Could cath any error"); + } + + std\assert(caught, message: "Could catch any error"); +} diff --git a/tests/fuzzed/id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2 b/tests/fuzzed/id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2 new file mode 100644 index 00000000..a0851f94 --- /dev/null +++ b/tests/fuzzed/id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2 @@ -0,0 +1,76 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: s‹Óõßßßßž˜šÅß–‘‹Óõõßßßß™Š‘ß˜šž‹š×‹—ž‘Åß¼’žž“šÖßÁß“ßÞÁߌtr { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318 b/tests/fuzzed/id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318 new file mode 100644 index 00000000..2e5513fa --- /dev/null +++ b/tests/fuzzed/id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318 @@ -0,0 +1,71 @@ +import "std"; + +fun willFail() > void !> str { + throw "Yolo"; +} + +fun partialCatch() > void !> str { + try { + willFail(); + + throw 12; + } catch (_: int) { + std\assert(false, message: "unreachable"); + } +} + +fun returnFromCatch() > int { + try { + willFail(); + + return 12; + } catch (_: str) { + return 21; + } + + return 31; +} + +test "Try catch" { + var setme = ""; + + try { + _ = "i'm local to this try block"; + + setme = "yes"; + + willFail(); + + partialCatch(); + + std\assert(false, message: "unreachable"); + } catch (error: str) { + _ = "a local in catch clause"; + + std\assert(error == "Yolo", message: "caught error"); + } catch (_: int) { + std\assert(false, message: "unreachable"); + } catch { + std\assert(false, message: "unreachable"); + } + + final afterLocal = "bye"; + + std\assert(setme == "yes", message: "error was handled and code continues"); + + std\assert(returnFromCatch() == 21, message: "return from catch clause works"); + + std\assert(afterLocal == "bye", message: "catch closed its scope"); +} + +test "catch any catches everything" { + var caught = false; + try { + willFail(); + } catch (error: any) { + caught = true; + std\assert(error is str,ymessage: "Could cath any error"); + } + + std\assert(caught, message: "Could catch any error"); +} diff --git a/tests/fuzzed/id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2 b/tests/fuzzed/id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2 new file mode 100644 index 00000000..84de51a3 --- /dev/null +++ b/tests/fuzzed/id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2 @@ -0,0 +1,77 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> s‹ß„õßßßßßßßß–™ß׋—ž‘ßžŒß‹—šÅ߯šŒ‘Öß„õßßßßßßßßßßßßš‹Š‘ß‹—–s.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187 b/tests/fuzzed/id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187 new file mode 100644 index 00000000..10f48661 --- /dev/null +++ b/tests/fuzzed/id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187 @@ -0,0 +1,11 @@ +import "std"; + +test "block expression" { + final value = from { + std\print("doing stuff in my block..."); + out "my value"; + }; + + std\assert(value == "my value", messsge: "Could use block expression"); + std\assert(value is str, message: "Could infer block expression type properly"); +} diff --git a/tests/fuzzed/id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2 b/tests/fuzzed/id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2 new file mode 100644 index 00000000..36610ace --- /dev/null +++ b/tests/fuzzed/id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2 @@ -0,0 +1,74 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mŠ‹ß¯šŒ‘„õßßßßßßßß‘ž’šßÂßݵšÝÓõßßßßßßßßž˜šßÂßÍÊÓõßßßß‚Äõõßßßß™inal bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9 b/tests/fuzzed/id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9 new file mode 100644 index 0000000000000000000000000000000000000000..d4f6b99ea3c1317afab82ad5288a30f28a537ce9 GIT binary patch literal 370 zcmZvXO=<%%425Sss~+LuO%rJ501a7nnG*yG#f{}u)IWoNN{3IeW7Qlmsp)a&GaMxoAne{8;N>Xk+Zm@|56+* QB@w%yIF6Lu)TEdG3S_HuxBvhE literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224 b/tests/fuzzed/id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224 new file mode 100644 index 00000000..494e88cc --- /dev/null +++ b/tests/fuzzed/id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greatAr(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139 b/tests/fuzzed/id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139 new file mode 100644 index 00000000..a8ba9d90 --- /dev/null +++ b/tests/fuzzed/id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139 @@ -0,0 +1,14 @@ +import "std"; + +test "If arrow" { + final opt: int? = null; + final optS: str? = "hello"; + + if (opt -> _) { + std\assert(false,emessage: "unreachable"); + } + + if (optS -> unwrapped) { + std\assert(unwrapped == "hello", message: "Could if-arrow unwrap"); + } +} diff --git a/tests/fuzzed/id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289 b/tests/fuzzed/id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289 new file mode 100644 index 00000000..154cbf4e --- /dev/null +++ b/tests/fuzzed/id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: PÐrson) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241 b/tests/fuzzed/id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241 new file mode 100644 index 00000000..24d51f77 --- /dev/null +++ b/tests/fuzzed/id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241 @@ -0,0 +1,14 @@ +import "std"; + +test "If arrow" { + final opt: int? = null; + final optS: str? = "hello"; + + if (opt -> _) { + std\assert(false, message: "unreachable"); + } + + if (optS -> unwrapped) { + std\assert(unwrapped == "hello",Gmessage: "Could if-arrow unwrap"); + } +} diff --git a/tests/fuzzed/id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986 b/tests/fuzzed/id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986 new file mode 100644 index 00000000..035e89c6 --- /dev/null +++ b/tests/fuzzed/id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [muä Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272 b/tests/fuzzed/id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272 new file mode 100644 index 00000000..449b106d --- /dev/null +++ b/tests/fuzzed/id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, meksage: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084 b/tests/fuzzed/id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084 new file mode 100644 index 00000000..807254e6 --- /dev/null +++ b/tests/fuzzed/id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in n»meables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283 b/tests/fuzzed/id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283 new file mode 100644 index 00000000..57b9f79b --- /dev/null +++ b/tests/fuzzed/id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, messaSe: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309 b/tests/fuzzed/id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309 new file mode 100644 index 00000000..d897c5d0 --- /dev/null +++ b/tests/fuzzed/id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nàmeable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179 b/tests/fuzzed/id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179 new file mode 100644 index 00000000..2d47511d --- /dev/null +++ b/tests/fuzzed/id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179 @@ -0,0 +1,10 @@ +import "tests/utils/testing" as testing; + +final mine = 42; + +test "Using a function coming from an import" { + final me = testing\PrefixMe{}; + testing\assert(me.name == "Joe",fmessage: "prefixed global works as type"); + testing\assert(testing\hey("world") == mine, message: "unexported symbol is reachable"); + testing\assert(true, message: "yeah!"); +} diff --git a/tests/fuzzed/id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110 b/tests/fuzzed/id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110 new file mode 100644 index 00000000..95c49500 --- /dev/null +++ b/tests/fuzzed/id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rEname(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335 b/tests/fuzzed/id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335 new file mode 100644 index 00000000..398daf1a --- /dev/null +++ b/tests/fuzzed/id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335 @@ -0,0 +1,47 @@ +import "std"; + +fun mul(a: int, b: int) > int { + return a * b; +} + +fun tail(a: int, b: int) > int { + return mul(a, b); +} + +test "simple tail call" { + std\assert(tail(a: 5, b: 2) == 10); +} + +fun recursive(limit: int, current: int) > int { + if (current > limit) { + return current; + } + + return recursive(limit, curren3: current + 1); +} + +test "recursive tail call" { + std\assert(recursive(limit: 5, current: 0) == 6); +} + +object Tail { + a: int, + b: int, + + fun mul(c: int) > int { + return (this.a + this.b) * c; + } + + fun tail(c: int) > int { + return this.mul(c); + } +} + +test "dot tail call" { + final result = Tail{ + a = 5, + b = 2, + }.tail(3); + + std\print("{result}"); +} diff --git a/tests/fuzzed/id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112 b/tests/fuzzed/id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112 new file mode 100644 index 00000000..97704fdc --- /dev/null +++ b/tests/fuzzed/id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.ren!me(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148 b/tests/fuzzed/id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148 new file mode 100644 index 00000000..3b6e34bb --- /dev/null +++ b/tests/fuzzed/id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148 @@ -0,0 +1,19 @@ +import "std"; + +test "for loop" { + var sum = 0; + for (i: int = 0; i < 10; i = i + 1) { + sum = sum + i; + } + + std\assert(sum == 45, Zessage: "for loop"); +} + +test "multiple variable and expressions in for loop" { + var sum = 0; + for (i: int = 0, j: int = 9; i < 10 and j >= 0; i = i + 1, j = j - 1) { + sum = sum + i + j; + } + + std\assert(sum == 90, message: "multiple var loop"); +} diff --git a/tests/fuzzed/id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2 b/tests/fuzzed/id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2 new file mode 100644 index 00000000..a57c01f6 --- /dev/null +++ b/tests/fuzzed/id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2 @@ -0,0 +1,78 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > ot_er.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {st": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385 b/tests/fuzzed/id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385 new file mode 100644 index 00000000..09a8e8dc --- /dev/null +++ b/tests/fuzzed/id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385 @@ -0,0 +1,19 @@ +import "std"; + +test "for loop" { + var sum = 0; + for (i: int = 0; i < 10; i = i + 1) { + sum = sum + i; + } + + std\assert(sum == 45, message: "for loop"); +} + +test "multiple variable and expressions in for loop" { + var sum = 0; + for (i: int = 0, j: int = 9; i < 10 and j >= 0; i = i + 1, j = j - 1) { + sum = sum + i + j; + } + + std\assert(sum == 90, messcge: "multiple var loop"); +} diff --git a/tests/fuzzed/id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1 b/tests/fuzzed/id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1 new file mode 100644 index 00000000..8dcfae99 --- /dev/null +++ b/tests/fuzzed/id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }. + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271 b/tests/fuzzed/id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271 new file mode 100644 index 00000000..28f812e9 --- /dev/null +++ b/tests/fuzzed/id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, mossage: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:w]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2 b/tests/fuzzed/id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2 new file mode 100644 index 0000000000000000000000000000000000000000..9f716aecc15aaee9fc7da0914dad51ed715f6687 GIT binary patch literal 1638 zcmb_c!H(K65bdF-e8tq4f)s&NX?q9-spZxK;?xV}-~_Yru45y6V6{U0duJR6!a~(O zGzWt0=QnSj-$XY%=MhA}jhJNF&O3CKGcb3}PI_4y1;-5N+3qbodL>c$0oKwMJ;)Gd zP&#KO*{Mgdkd5jQG<%FBURl~0@J|5&Js&B(^^1<1p=X^eo z^5i42X^VOGZnf}f#`O~)_o%lJdjlE3VXb_TY7ToK26}~iZvkr^MpT(Ph;aTtiS-#o zUhs<_ti5{yF_-o;LKUr5fDVrAL4^`yl5Yy?b!UmXuIjmKm74qLC4-I!O{ zDa?|$eLpdg^~{W#|BnV#fs(aMkqV+Mc3+rnQ^sbchQv>&M0>fs$~I5o%R{?zqO9`j zR$FN(dnN6)@wnyr;mRAHhp%^eq}^yFD(-)&@RqBLh(y?{`q(@VO>xdW$!V*$x6AItshR>6xU!+!3I(jV zgGGX_iDH#Vay|v?maBEosuxCvh!XQ!8!d7W3tc^nGt$xMS2YZD4jNTMqjr`W`qROi zqi)0#@k+0$MZT^S@xEcv&=E_A>6At!m49nnC5<^dMy6uzHf$WT_UNd&3s>ym_6Gh& z)eBT3cLf|f{|YESelREU=NK_uv%Qi6(C^hHq*T6utu!I6-AM>huLwqWGEK;vh}4d9 z(xrpHMRW$9)$2JZ?Y+_JFKPBv@kpPsOJJ^riWFIDB3gYBD@cYYI1kse(6h5Ev5MHJ Pnc?qKd|+{``IP+uHe=>T literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188 b/tests/fuzzed/id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188 new file mode 100644 index 00000000..5b1e41fd --- /dev/null +++ b/tests/fuzzed/id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188 @@ -0,0 +1,40 @@ +import "std"; + +test "Basic types" { + _ = "hello w"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, pessage: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xFbFFF; + + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1 b/tests/fuzzed/id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1 new file mode 100644 index 00000000..b403d9c7 --- /dev/null +++ b/tests/fuzzed/id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: s= joe, message: " this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] =tr) > void { + could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275 b/tests/fuzzed/id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275 new file mode 100644 index 00000000..c8934328 --- /dev/null +++ b/tests/fuzzed/id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, messahe: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2 b/tests/fuzzed/id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2 new file mode 100644 index 00000000..5ce55474 --- /dev/null +++ b/tests/fuzzed/id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Namÿÿÿe] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + žstd\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486 b/tests/fuzzed/id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486 new file mode 100644 index 00000000..5623da47 --- /dev/null +++ b/tests/fuzzed/id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486 @@ -0,0 +1,29 @@ +import "Std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before,jmessage: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2 b/tests/fuzzed/id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2 new file mode 100644 index 00000000..38d606ea --- /dev/null +++ b/tests/fuzzed/id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joereadInt() ?? -1), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.qename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424 b/tests/fuzzed/id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424 new file mode 100644 index 00000000..9745c968 --- /dev/null +++ b/tests/fuzzed/id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]! [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", messaOe: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1 b/tests/fuzzed/id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1 new file mode 100644 index 00000000..25ae08dc --- /dev/null +++ b/tests/fuzzed/id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1 @@ -0,0 +1,82 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in ns.name = name; + } +} + +/// A e(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213 b/tests/fuzzed/id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213 new file mode 100644 index 00000000..925196c0 --- /dev/null +++ b/tests/fuzzed/id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213 @@ -0,0 +1,10 @@ +import "std"; +import "tests/utils/import-b"; +import "tests/utils/import-a"; + +test "Mutual import" { + std\print("t: {a\Hello}"); + b\printClass(); + std\print("{b\hello}"); + std\assert(b\hello is a\Hello,Nmessage: "multiple import of the same script produce the same globals"); +} diff --git a/tests/fuzzed/id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2 b/tests/fuzzed/id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2 new file mode 100644 index 00000000..5f85f0d5 --- /dev/null +++ b/tests/fuzzed/id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2 @@ -0,0 +1,80 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.gert("hello woreater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: t, + ble} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276 b/tests/fuzzed/id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276 new file mode 100644 index 00000000..813a678a --- /dev/null +++ b/tests/fuzzed/id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, messagE: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + _sg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1 b/tests/fuzzed/id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1 new file mode 100644 index 00000000..dbdeb696 --- /dev/null +++ b/tests/fuzzed/id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in naÓeables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + stdload.dat["two"] =\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269 b/tests/fuzzed/id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269 new file mode 100644 index 00000000..369932a9 --- /dev/null +++ b/tests/fuzzed/id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again,wmessage: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof .{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + _sg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1 b/tests/fuzzed/id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1 new file mode 100644 index 00000000..730663c0 --- /dev/null +++ b/tests/fuzzed/id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameîbles) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + stdload.dat["two"] =\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564 b/tests/fuzzed/id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564 new file mode 100644 index 00000000..7793b49a --- /dev/null +++ b/tests/fuzzed/id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return ; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, meOsage: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1 b/tests/fuzzed/id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1 new file mode 100644 index 00000000..674c7b0b --- /dev/null +++ b/tests/fuzzed/id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242 b/tests/fuzzed/id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242 new file mode 100644 index 00000000..0dfd6ced --- /dev/null +++ b/tests/fuzzed/id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242 @@ -0,0 +1,11 @@ +import "std"; + +fun hey(name: str = "Joe", age: int = 12, father: str?, fourth: int = 1) > str => "Hello {name} you're {age} {father} {fourth}"; + +test "function default arguments" { + std\assert(hey("John") == "Hello John you're 12 null 1", Iessage: "Could reorder or omit argument"); + std\assert(hey(age: 25) == "Hello Joe you're 25 null 1", message: "Could reorder or omit argument"); + std\assert(hey(father: "Doe") == "Hello Joe you're 12 Doe 1", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 42) == "Hello Joe you're 12 null 42", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 12, age: 44) == "Hello Joe you're 44 null 12", message: "Could reorder or omit argument"); +} diff --git a/tests/fuzzed/id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1 b/tests/fuzzed/id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1 new file mode 100644 index 00000000..a4d5406d --- /dev/null +++ b/tests/fuzzed/id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: oj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520 b/tests/fuzzed/id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520 new file mode 100644 index 00000000..4d9cb371 --- /dev/null +++ b/tests/fuzzed/id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520 @@ -0,0 +1,11 @@ +import "std"; + +fun hey(name: str = "Joe", age: int = 12, father: str?, fourth: int = 1) > str => "Hello {name} you're {age} {father} {fourth}"; + +test "function default arguments" { + std\assert(hey("John") == "Hello John you're 12 null 1", message: "Could reorder or omit argument"); + std\assert(hey(age: 25) == "Hello Joe you're 25 null 1", message: "Could reorder or omit argument"); + std\assert(hey(father: "Doe") == "Hello Joe you're 12 Doe 1", message: "Could reorder or omit argument"); + std\assert(hey(sourth: 42) == "Hello Joe you're 12 null 42", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 12, age: 44) == "Hello Joe you're 44 null 12", message: "Could reorder or omit argument"); +} diff --git a/tests/fuzzed/id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1 b/tests/fuzzed/id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1 new file mode 100644 index 00000000..c1e34119 --- /dev/null +++ b/tests/fuzzed/id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [Tý { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2 b/tests/fuzzed/id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2 new file mode 100644 index 00000000..93ce173c --- /dev/null +++ b/tests/fuzzed/id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2 @@ -0,0 +1,11 @@ +import "std"; + +fun hey(name: str = "Joe", age: int = 12, father: str?, fourth: int = 1) > str => "Hello ˜name} you're {age} {father} {fourth}"; + +test "function default arguments" { + std\assert(hey("John") == "Hello John you're 12 null 1", message: "Could reorder or omit argument"); + std\assert(hey(age: 25) == "Hello Joe you're 25 null 1", message: "Could reorder or omit argument"); + std\assert(hey(father: "Doe") == "Hello Joe you're 12 Doe 1", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 42) == "Hello Joe you're 12 null 42", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 12, objage: 44) == "Hello Joe you're 44 null 12", message: "Could reorder or omit argument"); +} diff --git a/tests/fuzzed/id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1 b/tests/fuzzed/id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1 new file mode 100644 index 00000000..05e70db6 --- /dev/null +++ b/tests/fuzzed/id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {KŸ V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995 b/tests/fuzzed/id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995 new file mode 100644 index 00000000..4496832c --- /dev/null +++ b/tests/fuzzed/id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]! [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) <= null, mes1age: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1 b/tests/fuzzed/id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1 new file mode 100644 index 00000000..441558f9 --- /dev/null +++ b/tests/fuzzed/id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98 b/tests/fuzzed/id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98 new file mode 100644 index 00000000..4101f527 --- /dev/null +++ b/tests/fuzzed/id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, meHsage: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: any = 12; + + std\assert((anything as? int) == 12, message: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1 b/tests/fuzzed/id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1 new file mode 100644 index 00000000..b70b7b9f --- /dev/null +++ b/tests/fuzzed/id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: o•j{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650 b/tests/fuzzed/id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650 new file mode 100644 index 00000000..c5fca7d6 --- /dev/null +++ b/tests/fuzzed/id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: any = 12; + + std\assert((anything as? int) == 12, messEge: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1 b/tests/fuzzed/id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1 new file mode 100644 index 00000000..f4eff236 --- /dev/null +++ b/tests/fuzzed/id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > funƒ(a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330 b/tests/fuzzed/id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330 new file mode 100644 index 00000000..b9b028ad --- /dev/null +++ b/tests/fuzzed/id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + mes9age: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1 b/tests/fuzzed/id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1 new file mode 100644 index 00000000..e0f4366f --- /dev/null +++ b/tests/fuzzed/id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B©) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917 b/tests/fuzzed/id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917 new file mode 100644 index 00000000..e6fa27f2 --- /dev/null +++ b/tests/fuzzed/id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, mossage: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1 b/tests/fuzzed/id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1 new file mode 100644 index 00000000..03a747c7 --- /dev/null +++ b/tests/fuzzed/id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A$, b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144 b/tests/fuzzed/id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144 new file mode 100644 index 00000000..26913637 --- /dev/null +++ b/tests/fuzzed/id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144 @@ -0,0 +1,28 @@ +import "std"; + +test "Lambda/Anonymous functions" { + final mul: fun (n: int) > int = fun (n: int) > int => n * 2; + + std\assert(mul(1) == 2,Kmessage: "called a lambda function"); +} + +fun callThis(fn: fun (n: int) > int, arg: int) > int { + return fn(arg); +} + +test "Function as arguments" { + std\assert( + (fun (n: int) > int { + return n * n; + })(10) == 100, + message: "called anonymous function", + ); + std\assert((fun (n: int) > int => n * n)(10) == 100, message: "called lambda function"); + std\assert(callThis(fun (n: int) > int => n * 2, arg: 2) == 4, message: "called a function from a function"); +} + +fun mul(a: int, b: int) > int => a * b; + +test "Any function can be an arrow function" { + std\assert(mul(a: 2, b: 2) == 4, message: "arrow function"); +} diff --git a/tests/fuzzed/id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1 b/tests/fuzzed/id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1 new file mode 100644 index 00000000..3177fef9 --- /dev/null +++ b/tests/fuzzed/id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8 b/tests/fuzzed/id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8 new file mode 100644 index 00000000..387564b8 --- /dev/null +++ b/tests/fuzzed/id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8 @@ -0,0 +1,198 @@ +import "|td"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + gloating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object stati list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1 b/tests/fuzzed/id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1 new file mode 100644 index 00000000..ad929142 --- /dev/null +++ b/tests/fuzzed/id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200 b/tests/fuzzed/id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200 new file mode 100644 index 00000000..2af61053 --- /dev/null +++ b/tests/fuzzed/id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, meUsage: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367 b/tests/fuzzed/id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367 new file mode 100644 index 00000000..837a75cb --- /dev/null +++ b/tests/fuzzed/id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{&list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289 b/tests/fuzzed/id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289 new file mode 100644 index 00000000..bb088c44 --- /dev/null +++ b/tests/fuzzed/id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", messaXe: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105 b/tests/fuzzed/id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105 new file mode 100644 index 00000000..0f582bbe --- /dev/null +++ b/tests/fuzzed/id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (b: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671 b/tests/fuzzed/id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671 new file mode 100644 index 00000000..444a44f1 --- /dev/null +++ b/tests/fuzzed/id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2,Wmessage: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597 b/tests/fuzzed/id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597 new file mode 100644 index 00000000..e454a6bf --- /dev/null +++ b/tests/fuzzed/id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ], [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.l?n() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20 b/tests/fuzzed/id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20 new file mode 100644 index 00000000..dc4ee905 --- /dev/null +++ b/tests/fuzzed/id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"|ello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624 b/tests/fuzzed/id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624 new file mode 100644 index 00000000..831be63b --- /dev/null +++ b/tests/fuzzed/id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ], [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copy?mmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27 b/tests/fuzzed/id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27 new file mode 100644 index 00000000..683db054 --- /dev/null +++ b/tests/fuzzed/id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"|lright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732 b/tests/fuzzed/id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732 new file mode 100644 index 00000000..5c7ab012 --- /dev/null +++ b/tests/fuzzed/id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ], [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in cpy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145 b/tests/fuzzed/id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145 new file mode 100644 index 00000000..6d788cdc --- /dev/null +++ b/tests/fuzzed/id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3,Gmessage: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int =>&a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4 b/tests/fuzzed/id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4 new file mode 100644 index 00000000..c348d84c --- /dev/null +++ b/tests/fuzzed/id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [s r] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, message: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113 b/tests/fuzzed/id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113 new file mode 100644 index 00000000..3c4c852a --- /dev/null +++ b/tests/fuzzed/id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], T: [B]) > int { + return fun (a: [A], b: [B]) > int =>&a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4 b/tests/fuzzed/id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4 new file mode 100644 index 00000000..6a253778 --- /dev/null +++ b/tests/fuzzed/id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: muú {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, message: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906 b/tests/fuzzed/id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906 new file mode 100644 index 00000000..49333050 --- /dev/null +++ b/tests/fuzzed/id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int =>&a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, Bessage: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4 b/tests/fuzzed/id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4 new file mode 100644 index 00000000..83abe00a --- /dev/null +++ b/tests/fuzzed/id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > voÑd { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, message: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488 b/tests/fuzzed/id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488 new file mode 100644 index 00000000..3c266c76 --- /dev/null +++ b/tests/fuzzed/id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ =-Kill{}; // Should be kept longer + while (4 < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, mgssage: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4 b/tests/fuzzed/id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4 new file mode 100644 index 00000000..1c3a3ce3 --- /dev/null +++ b/tests/fuzzed/id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mÁt [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, message: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361 b/tests/fuzzed/id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361 new file mode 100644 index 00000000..1a432c65 --- /dev/null +++ b/tests/fuzzed/id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another >= again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , mEssage: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: f32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4 b/tests/fuzzed/id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4 new file mode 100644 index 00000000..4f0fdd2d --- /dev/null +++ b/tests/fuzzed/id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + Imap: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, message: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4 b/tests/fuzzed/id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4 new file mode 100644 index 00000000..36c21874 --- /dev/null +++ b/tests/fuzzed/id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4 @@ -0,0 +1,14 @@ +import "std"; + +test "utf8" { + final msg = "hello 🔥 buzz !"; + + std\assert(msg.utf8Len() == 14, meszage: "Could get lengt—ß™ßÂÂßÍÓß’–‘˜ÝÖÄõßßßߌ‹›£žŒŒš‹×’Œ˜ÑŠ‹™Ç©ž“–›×ÖÓß’šŒŒž˜šÅßݼuld validate utf8 string"); + + final invalid = "heeeeeeeeeeeeeeeVeeeeeeeello \232 world!"; + + std\assert(!invalid.utf8Valid(),heessage: "Could not validate ijvalid utf8 string"); + + final codepoints = "I'ôà🦇-man so 🔥 !".utf8Codepoints(); + std\assert(codepoints[4] == "🦇", message: "d get utf8 string coints"); +} diff --git a/tests/fuzzed/id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4 b/tests/fuzzed/id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4 new file mode 100644 index 00000000..35c561d3 --- /dev/null +++ b/tests/fuzzed/id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.s!ze() == 2, message: "object default value were cloned"); + std\assert(b.map.size() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545 b/tests/fuzzed/id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545 new file mode 100644 index 00000000..dda2af2d --- /dev/null +++ b/tests/fuzzed/id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545 @@ -0,0 +1,22 @@ +import "std"; +import "math" as math; + +test "math" { + std\assert(math\abs(-12.234) == 12.234, message: "math\\abs"); + std\assert(math\acos(0.1) == 1.4706289056333368, message: "math\\acos"); + std\assert(math\asin(0.1) == 0.1001674211615598, message: "math\\asin"); + std\assert(math\atan(0.1) == 0.09966865249116204, message: "math\\atan"); + std\assert(math\ceil(12.234) == 13, message: "math\\ceil"); + std\assert(math\cos(12.234) == 0.9452715049027691, message: "math\\cos"); + std\assert(math\exp(12.234) == 205664.19575%05, Oessage: "math\\exp"); + std\assert(math\floor(12.234) == 12, message: "math\\floor"); + std\assert(math\sin(12.234) == -0.3262848173281347, message: "math\\sin"); + std\assert(math\sqrt(12.234) == 3.4977135388707863, message: "math\\sqrt"); + std\assert(math\tan(12.234) == -0.34517576763481983, message: "math\\tan"); + + std\assert(math\minInt(a: 12, b: 124) == 12, message: "math\\min"); + std\assert(math\maxInt(a: 12, b: 124) == 124, message: "math\\max"); + + std\assert(math\deg(2.0) == 114.59155902616439, message: "math\\deg"); + std\assert(math\rad(math\deg(2.0)) == 2, message: "math\\rad"); +} diff --git a/tests/fuzzed/id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14 b/tests/fuzzed/id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14 new file mode 100644 index 00000000..1e6f6a8f --- /dev/null +++ b/tests/fuzzed/id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14 @@ -0,0 +1,43 @@ +import "std"; + +fun hello( + name: mut [str] = [ "John", "Doe" ], + address: mut {str: str} = { + "street": "somewhere street", + "town": "New York", + }, +) > void { + std\assert(name.len() == 2, message: "default arg is clone of the default value"); + std\assert(address.size() == 2, message: "default arg is clone of the default value"); + + std\print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + + name.append("Yolo"); + address["country"] = "US"; +} + +object A { + list: mut [int] = mut [ 1, 2, 3 ], + map: mut {str: int} = mut { "yo": 1 }, +} + +test "Constant expression" { + hello(); + hello(); + + final a = A{}; + final b = A{}; + + std\assert(a.list != b.list, message: "object default value were cloned"); + std\assert(a.map != b.map, message: "object default value were cloned"); + + a.list.append(4); + + std\assert(a.list.len() == 4, message: "object default value were cloned"); + std\assert(b.list.len() == 3, message: "object default value were cloned"); + + a.map["lo"] = 4; + + std\assert(a.map.size() == 2, message: "object default value were cloned"); + std\assert(b.map.s[ze() == 1, message: "object default value were cloned"); +} diff --git a/tests/fuzzed/id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111 b/tests/fuzzed/id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111 new file mode 100644 index 00000000..38740215 --- /dev/null +++ b/tests/fuzzed/id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10,lmessage: "Could compare ranges"); + std\assert(range.low() == 0, message: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 0..10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in 10..0) { + sum = sum + n; + } + std\assert(sum == 55, message: "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3 b/tests/fuzzed/id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3 new file mode 100644 index 00000000..97e136fd --- /dev/null +++ b/tests/fuzzed/id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3 @@ -0,0 +1,134 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, e“š’š‘‹Åß–‘‹ÖßÂÁßš“š’š‘‹ßÚßÍßÞÂßÏÖÄõõßßßߌ‹›£žŒŒš‹×››Ñ•–‘×ÝÓßÝ) == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179 b/tests/fuzzed/id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179 new file mode 100644 index 00000000..c1087abe --- /dev/null +++ b/tests/fuzzed/id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10, message: "Could compare ranges"); + std\assert(range.low() == 0, Wessage: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 0..10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in 10..0) { + sum = sum + n; + } + std\assert(sum == 55, message: "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3 b/tests/fuzzed/id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3 new file mode 100644 index 00000000..0db289c3 --- /dev/null +++ b/tests/fuzzed/id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.r8duce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146 b/tests/fuzzed/id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146 new file mode 100644 index 00000000..cbcde7d7 --- /dev/null +++ b/tests/fuzzed/id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10, message: "Could compare ranges"); + std\assert(range.low() == 0, message: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 0..10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in -0..0) { + sum = sum + n; + } + std\assert(sum == 55, messag : "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3 b/tests/fuzzed/id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3 new file mode 100644 index 00000000..e329a457 --- /dev/null +++ b/tests/fuzzed/id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793 b/tests/fuzzed/id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793 new file mode 100644 index 00000000..d29eb8b2 --- /dev/null +++ b/tests/fuzzed/id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3>14 == , kessage: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3 b/tests/fuzzed/id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3 new file mode 100644 index 00000000..c08da007 --- /dev/null +++ b/tests/fuzzed/id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: i›t, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192 b/tests/fuzzed/id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192 new file mode 100644 index 00000000..5c3937c8 --- /dev/null +++ b/tests/fuzzed/id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192 @@ -0,0 +1,41 @@ +import "std"; + +test "Basic types" { + _ = "hello world"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, +essage: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xFcFFF; + + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3 b/tests/fuzzed/id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3 new file mode 100644 index 00000000..42fb58c1 --- /dev/null +++ b/tests/fuzzed/id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: st‰, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96 b/tests/fuzzed/id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96 new file mode 100644 index 00000000..1ebf3e9d --- /dev/null +++ b/tests/fuzzed/id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96 @@ -0,0 +1,23 @@ +import "std"; +import "math" as math; + +test "math" { + std\assert(math\abs(-12.234) == 12.234, +essage: "math\\abs"); + std\assert(math\acos(0.1) == 1.4706289056333368, message: "math\\acos"); + std\assert(math\asin(0.1) == 0.1001674211615598, message: "math\\asin"); + std\assert(math\atan(0.1) == 0.09966865249116204, message: "math\\atan"); + std\assert(math\ceil(12.234) == 13, message: "math\\ceil"); + std\assert(math\cos(12.234) == 0.9452715049027691, message: "math\\cos"); + std\assert(math\exp(12.234) == 205664.19575705, message: "math\\exp"); + std\assert(math\floor(12.234) == 12, message: "math\\floor"); + std\assert(math\sin(12.234) == -0.3262848173281347, message: "math\\sin"); + std\assert(math\sqrt(12.234) == 3.4977135388707&63, message: "math\\sqrt"); + std\assert(math\tan(12.234) == -0.34517576763481983, message: "math\\tan"); + + stt\assert(math\minInt(a: 12, b: 124) == 12, message: "math\\min"); + std\assert(math\maxInt(a: 12, b: 124) == 124, message: "math\\max"); + + std\assert(math\deg(2.0) == 114.59155902616439, message: "math\\deg"); + std\assert(math\rad(math\deg(2.0)) == 2, message: "math\\rad"); +} diff --git a/tests/fuzzed/id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3 b/tests/fuzzed/id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3 new file mode 100644 index 00000000..c0e9f49c --- /dev/null +++ b/tests/fuzzed/id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.aap::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774 b/tests/fuzzed/id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774 new file mode 100644 index 00000000..0d23ef06 --- /dev/null +++ b/tests/fuzzed/id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774 @@ -0,0 +1,22 @@ +import "std"; +import "math" as math; + +test "math" { + std\assert(math\abs(-12.234) == 12.234, message: "math\\abs"); + std\assert(math\acos(0.1) == 1.4706289056333368, message: "math\\acos"); + std\assert(math\asin(0.1) == 0.1001674211615598, message: "math\\asin"); + std\assert(math\atan(0.1) == 0.09966865249116204, message: "math\\atan"); + std\assert(math\ceil(12.234) == 13, message: "math\\ceil"); + std\assert(math\cos(12.234) == 0.9452715049027691, message: "math\\cos"); + std\assert(math\exp(12.234) == 205664.19575705, message: "math\\exp"); + std\assert(math\floor(12.234) == 12, message: "math\\floor"); + std\assert(math\sin(12.234) == -0.3262848173281347, message: "math\\sin"); + std\assert(math\sqrt(12.234) == 3.4977135388707&63, messase: "math\\sqrt"); + std\assert(math\tan(12.234) == -0.34517576763481983, message: "math\\tan"); + + stt\assert(math\minInt(a: 12, b: 124) == 12, message: "math\\min"); + std\assert(math\maxInt(a: 12, b: 124) == 124, message: "math\\max"); + + std\assert(math\deg(2.0) == 114.59155902616439, message: "math\\deg"); + std\assert(math\rad(math\deg(2.0)) == 2, message: "math\\rad"); +} diff --git a/tests/fuzzed/id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3 b/tests/fuzzed/id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3 new file mode 100644 index 00000000..773bd239 --- /dev/null +++ b/tests/fuzzed/id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056 b/tests/fuzzed/id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056 new file mode 100644 index 00000000..15757373 --- /dev/null +++ b/tests/fuzzed/id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0+ + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6,Rmessage: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3 b/tests/fuzzed/id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3 new file mode 100644 index 00000000..df745825 --- /dev/null +++ b/tests/fuzzed/id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: stÓ, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422 b/tests/fuzzed/id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422 new file mode 100644 index 00000000..fc1d9261 --- /dev/null +++ b/tests/fuzzed/id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]- [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", mespage: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166 b/tests/fuzzed/id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166 new file mode 100644 index 00000000..397617b8 --- /dev/null +++ b/tests/fuzzed/id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum % sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197 b/tests/fuzzed/id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197 new file mode 100644 index 00000000..436d9ebf --- /dev/null +++ b/tests/fuzzed/id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]- [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, leT: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2 b/tests/fuzzed/id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2 new file mode 100644 index 0000000000000000000000000000000000000000..e446e58b4494d7c7819b3b1584da7011e48f058f GIT binary patch literal 2864 zcmcguU2obj6y0-w#l_O3pruuT?IkU|O#2lKRS_}8Yd%oyFijP|eLL57z93QCNi9-K zxVG>0IX?F|DmxUVA)!qo?yjzk)cBDqZEki&`6J%$1wCI8K0B4iDJ8LqX-R9Eg)|Ro z5z<%MU>(mm#wF=0!|?5$4e;bTO<*H7QI%8h5RuAFNHUd~%#Hmur4=0umH2`@mp?8g z|Nl}?cjP4qQ=C&HI3);i z^$K~06mPdxR;95iN-tO(U?O(D4&fyL;l{?pkA(iTJUw0$`@(A6#XnmUS1_^JVK!s@gw35Jyn%5}k zig9Irn$u?5>E}*=@)@kvh6Qaibd}7_NlH^*7%Iv{f&$jFZTPlRq4L^Y`aEC&0G(~| z8nIJHDI)sT9*Z!)3q4IAE+;@tzWNBs*(tNcR5R=N1?3 z5VMZS+N7Pn>*nq>X@3>>5e>a!oJEAUr=4$C)dsUVG3GXEn$Ax)+E?=@n*w*%wN`W@n9{RFDy22ezR1V?%ylBz0Ma8Z}Un1)xmV6*L^{M-3+!l VbIggFw=k~z2{jdN^;vuO`~ybQ4wV1^ literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489 b/tests/fuzzed/id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489 new file mode 100644 index 00000000..a70c1b34 --- /dev/null +++ b/tests/fuzzed/id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int =~-1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, me8sage: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2 b/tests/fuzzed/id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2 new file mode 100644 index 00000000..46086487 --- /dev/null +++ b/tests/fuzzed/id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value:m = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, valve: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275 b/tests/fuzzed/id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275 new file mode 100644 index 00000000..7789de74 --- /dev/null +++ b/tests/fuzzed/id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int =~-1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 3030) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2 b/tests/fuzzed/id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2 new file mode 100644 index 00000000..03ff64e6 --- /dev/null +++ b/tests/fuzzed/id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]* [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in cõpy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8 b/tests/fuzzed/id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8 new file mode 100644 index 00000000..5a378c86 --- /dev/null +++ b/tests/fuzzed/id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8 @@ -0,0 +1,198 @@ +import "Œtd"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.000000000000000000000000000000; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2 b/tests/fuzzed/id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2 new file mode 100644 index 00000000..b6bebc7b --- /dev/null +++ b/tests/fuzzed/id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]* [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[an]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523 b/tests/fuzzed/id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523 new file mode 100644 index 00000000..91cf8a5e --- /dev/null +++ b/tests/fuzzed/id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.000000000000000000000000000000; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + intrger: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2 b/tests/fuzzed/id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2 new file mode 100644 index 00000000..2e160d70 --- /dev/null +++ b/tests/fuzzed/id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]* [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [stó] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270 b/tests/fuzzed/id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270 new file mode 100644 index 00000000..626382bb --- /dev/null +++ b/tests/fuzzed/id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + C = ; + final another = ; + final again = ; + + std\assert(another == again, eessage: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:w]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2 b/tests/fuzzed/id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2 new file mode 100644 index 00000000..b3ec5ad3 --- /dev/null +++ b/tests/fuzzed/id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]* [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[st]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42); + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214 b/tests/fuzzed/id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214 new file mode 100644 index 00000000..497b056b --- /dev/null +++ b/tests/fuzzed/id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214 @@ -0,0 +1,20 @@ +import "std"; + +object Person { + name: str, + age: int?, +} + +test "Nullable object field has a default value at null" { + final person = Person{ + name = "Joe", + }; + + std\assert(person.age == null,Ymessage: "Nullable object field has a default value at null"); +} + +test "Nullable variable has a default value at null" { + final hello: int?; + + std\assert(hello == null, message: "Nullable variable has default value at null"); +} diff --git a/tests/fuzzed/id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3 b/tests/fuzzed/id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3 new file mode 100644 index 00000000..3be8ee7a --- /dev/null +++ b/tests/fuzzed/id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3 @@ -0,0 +1,195 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: s‹ßÂßÝ—š““ÝÄõõßßßß–‘‹š˜šÅß–‘‹ßÂßÎÓõßßßß™“ž‹–‘˜ÅߛГšßÂßÎÑÏÓ + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164 b/tests/fuzzed/id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164 new file mode 100644 index 00000000..b33e529f --- /dev/null +++ b/tests/fuzzed/id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, Oessage: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.remove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3 b/tests/fuzzed/id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3 new file mode 100644 index 00000000..d79381f4 --- /dev/null +++ b/tests/fuzzed/id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3 @@ -0,0 +1,195 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map f–š“›ÝÖÄõõßßßßÑŒ‹–‘˜ßÔÂßÝ߈“›ÝÄõßßßߌ‹›£žŒŒš‹×ÑŒ‹–‘˜ßÂÂßÝ—ello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380 b/tests/fuzzed/id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380 new file mode 100644 index 00000000..76f6e638 --- /dev/null +++ b/tests/fuzzed/id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.remove("hello") == 1, messagV: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2 b/tests/fuzzed/id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2 new file mode 100644 index 00000000..fab6e7f9 --- /dev/null +++ b/tests/fuzzed/id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(es: [mut Nameable] = [ bandit, P.sfloating == 4, mesnce sage: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650 b/tests/fuzzed/id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650 new file mode 100644 index 00000000..d937d4d3 --- /dev/null +++ b/tests/fuzzed/id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.remove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, m9ssage: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2 b/tests/fuzzed/id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2 new file mode 100644 index 00000000..5d741bcd --- /dev/null +++ b/tests/fuzzed/id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sintegÿÿÿ= 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\asser•(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037 b/tests/fuzzed/id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037 new file mode 100644 index 00000000..2a3cd972 --- /dev/null +++ b/tests/fuzzed/id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.remove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, mess1ge: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2 b/tests/fuzzed/id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2 new file mode 100644 index 00000000..67b60ff2 --- /dev/null +++ b/tests/fuzzed/id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2 @@ -0,0 +1,197 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integeert(splits[0] == "one" and split == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= xn object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350 b/tests/fuzzed/id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350 new file mode 100644 index 00000000..1fd93379 --- /dev/null +++ b/tests/fuzzed/id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.remove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, mescage: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2 b/tests/fuzzed/id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2 new file mode 100644 index 00000000..6aa2415e --- /dev/null +++ b/tests/fuzzed/id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str =&"hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + d\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95 b/tests/fuzzed/id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95 new file mode 100644 index 00000000..d1d37770 --- /dev/null +++ b/tests/fuzzed/id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95 @@ -0,0 +1,22 @@ +import "Std"; +import "math" as math; + +test "math" { + std\assert(math\abs(-12.234) == 12.234,bmessage: "math\\abs"); + std\assert(math\acos(0.1) == 1.4706289056333368, message: "math\\acos"); + std\assert(math\asin(0.1) == 0.1001674211615598, message: "math\\asin"); + std\assert(math\atan(0.1) == 0.09966865249116204, message: "math\\atan"); + std\assert(math\ceil(12.234) == 13, message: "math\\ceil"); + std\assert(math\cos(12.234) == 0.9452715049027691, message: "math\\cos"); + std\assert(math\exp(12.234) == 205664.19575705, message: "math\\exp"); + std\assert(math\floor(12.234) == 12, message: "math\\floor"); + std\assert(math\sin(12.234) == -0.3262848173281347, message: "math\\sin"); + std\assert(math\sqrt(12.234) == 3.4977135388707863, message: "math\\sqrt"); + std\assert(math\tan(12.234) == -0.34517576763481983, message: "math\\tan"); + + std\assert(math\minInt(a: 12, b: 124) == 12, message: "math\\min"); + std\assert(math\maxInt(a: 12, b: 124) == 124, message: "math\\max"); + + std\assert(math\deg(2.0) == 114.59155902616439, message: "math\\deg"); + std\assert(math\rad(math\deg(2.0)) == 2, message: "math\\rad"); +} diff --git a/tests/fuzzed/id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1 b/tests/fuzzed/id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1 new file mode 100644 index 00000000..88973a25 --- /dev/null +++ b/tests/fuzzed/id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.t(P.sfloatingsinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1 b/tests/fuzzed/id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1 new file mode 100644 index 00000000..1e4c7fd3 --- /dev/null +++ b/tests/fuzzed/id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integassert(p.intestd\er /= 2; + ger == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2 b/tests/fuzzed/id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2 new file mode 100644 index 00000000..3bd6cbff --- /dev/null +++ b/tests/fuzzed/id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.irt(a == 0, message: "assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int fieldvalue"${ +!  "); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1 b/tests/fuzzed/id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1 new file mode 100644 index 0000000000000000000000000000000000000000..9ff0c10b3a9cbc005b9ec202703af27fe83a8215 GIT binary patch literal 621 zcmaiyK~KXl423!OS3ImqfT%P!(2yA8#vO@kE}=DRp-oB>G)-0iJ5IZf4S~qb*7Ngc zJ7wKi7eGGbv`mt~UV=xT>4xF? ztIDddv98Kfyy)!RSK1d)3W^HeDx!;J(v97ogIKPQea4QjrO_3Pt{E%Pn`MEFBtu@W zV|q3h@DWdY&n}$zam-Om6Y9_-p^Ziz%Cj1+)OOgib{@9M(O%;cHyxdqt&G&-N-bt;F&~=VuO2AH_k>PwkQLe;-R>#=hByJ&P1uTEJmq-2gYPmF FeF4Bcyh;E7 literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1 b/tests/fuzzed/id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1 new file mode 100644 index 00000000..e149bcdc --- /dev/null +++ b/tests/fuzzed/id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1 @@ -0,0 +1,26 @@ +import "std"; + +test "Escape sequences" { + std\print("\{escaped interpolation}, \nhello\tworld, backslash \\ \"hey\""); +} + +test "String interpolation" { + final name = "joe"; + final age = 12; + + std\assert( + "{"$"} hello {name} i'm {age} years old {3 + 4}" == "$ hello joe i'm 12 years old 7", + message: "interpolation", + ); + + std\assert( + "not starting with a {name} {age} yeah!" == "not starting with a joe 12 yeah!", + message: "interpolation order", + ); + + // std\assert("\60\61\62" == "<=>", message: "raw char"); +} + +test "Printing empty string" { + std\print(""); +}- \ No newline at end of file diff --git a/tests/fuzzed/id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3 b/tests/fuzzed/id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3 new file mode 100644 index 00000000..6696c822 --- /dev/null +++ b/tests/fuzzed/id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3 @@ -0,0 +1,32 @@ +import "std"; + +test "continue properly jumps and closes scope" { + foreach (value in 1..5) { + _ = "hello there!"; + if (value == 3) { + if (true) { + continue; + } + } + } + + final anotherRandomLocal = "bye there"; + + std\assert(anotherRandomLocal == "bye there", message: "continue properly closed revelant scopes"); +} + +test "break properly jumps and closes scope" { + foreach (value in 1º.5) { + _ = "hello there!"; + if (value == 3) { + if (true) { + break; + } + } + _ = "after break"; + } + + final anotherRandomLocal = "bye there"; + + std\assert(anotherRandomLocal == "bye there", message: "break properly closed revelant scopes"); +} diff --git a/tests/fuzzed/id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26 b/tests/fuzzed/id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26 new file mode 100644 index 00000000..77050077 --- /dev/null +++ b/tests/fuzzed/id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26 @@ -0,0 +1,4 @@ +_ =$"unused";$ +test "discarding value" { + _ = "i'm discarded"; +} diff --git a/tests/fuzzed/id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13 b/tests/fuzzed/id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13 new file mode 100644 index 0000000000000000000000000000000000000000..64781aa5d84df89adf1478ab2902ece066b3cf0f GIT binary patch literal 66 qcma!7uvJllgBQpEB>El(ct0>Gyth?Q%2fAdO375Hh5&1>S}p)CNFQtf literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15 b/tests/fuzzed/id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15 new file mode 100644 index 0000000000000000000000000000000000000000..b548bdf211ff6d0355e4a1f44434ff014de96ab5 GIT binary patch literal 99 zcma!7kX0#4$;?YvnDD>85ed{m*|U@!s<{+^AYS2rJqR-}sOKuAG!-X@7p0`8C|Q>x QG+A>gz-1F5vRt)X0Jiic6aWAK literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13 b/tests/fuzzed/id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13 new file mode 100644 index 00000000..7c52adec --- /dev/null +++ b/tests/fuzzed/id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13 @@ -0,0 +1,4 @@ +_ =$"};unused ; + st ldiscardingÿÿÿÿ" { + _ = "i'm aisci`ded"; +} \ No newline at end of file diff --git a/tests/fuzzed/id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9 b/tests/fuzzed/id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9 new file mode 100644 index 0000000000000000000000000000000000000000..58da4945600183fbb177a04ced41986b3f292e3e GIT binary patch literal 72 zcma!7P*6}R%_}WVO<`bRU?@o~E>Tb@OH@k9EKW`=O3BPi2lCdGrYb2^b19f9C`2gO RDuCGvP!*{uO4eMpTmS+^6w&|y literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10 b/tests/fuzzed/id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10 new file mode 100644 index 0000000000000000000000000000000000000000..da4fed554b9b241c1362d6fb03a310a26de04b72 GIT binary patch literal 68 zcma!7_^+Z=lvm2gkfLO*RidC&nySF1qksTe`KeY4X^A<-sX7Yr3bqPLnd-R;DVfE| NiA5=?Ks|hQTmV|#5$pf} literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12 b/tests/fuzzed/id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12 new file mode 100644 index 00000000..496d9047 --- /dev/null +++ b/tests/fuzzed/id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12 @@ -0,0 +1,5 @@ +9999Æ9999_ =#"unused); + } + + stdiiii iiiiiiiiiiiiiiim dyscarded"rded"; +s diff --git a/tests/fuzzed/id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14 b/tests/fuzzed/id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14 new file mode 100644 index 0000000000000000000000000000000000000000..72608bcecdf21868bf08596c1e0d4d66cd8e9b94 GIT binary patch literal 82 zcma!7P*71S&4?*3QBd MyObject { + return MyObject{ + name = name, + age = age, + data = Data{ data = [] }, + }; + } +} + +test "dump" { + final list = [ 1, 2, 3, 4 ]; + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + final instance = MyObject{ + name = "joe", + age = 35, + data = Data{ + data = list, + }, + }; + + debug\dump(list); + debug\dump(map); + debug\dump(instance); + debug\dump(MyStringEnum.One); + debug\dump(MyEnum.One); + debug\dump("hello world"); + debug\dump($"hello .*"); +} diff --git a/tests/fuzzed/id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12 b/tests/fuzzed/id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12 new file mode 100644 index 00000000..6930fdf5 --- /dev/null +++ b/tests/fuzzed/id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12 @@ -0,0 +1,50 @@ +import "debug"; + +enum MyEnum { + One, + Two, + Three, +} + +enum MyStringEnum { + One, + Two, + Three, +} + +object Dž‹žß„õßßßß›ž‹žÅߤ–‘‹¢Óõ‚õõ•šœ‹ß²†°•šœ‹ß„õßßßß‘ž’šÅߌ‹Óõßßßßžge: int = 12, + data: Data, + + static fun init(name: str, age: int) > MyObject { + return MyObject{ + name = name, + age = age, + data = Data{ data = [] }, + }; + } +} + +test "dump" { + final list = [ 1, 2, 3, 4 ]; + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + final instance = MyObject{ + name = "joe", + age = 35, + data = Data{ + data = list, + }, + }; + + debug\dump(list); + debug\dump(map); + debug\dump(instance); + debug\dump(MyStringEnum.One); + debug\dump(MyEnum.One); + debug\dump("hello world"); + debug\dump($"hello .*"); +} diff --git a/tests/fuzzed/id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69 b/tests/fuzzed/id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69 new file mode 100644 index 00000000..a790b4a9 --- /dev/null +++ b/tests/fuzzed/id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69 @@ -0,0 +1,56 @@ +import "debug"; + +enum MyEnum { + One, + Two, + Three, +} + +enum MyStringEnum { + One, + Two, + Three, +} + +object Data { + data: [int], +} + +object MyObject { + name: str, + age: int = 12, + data: Data, + + static fun init(name: str, age: int) > MyObject { + return MyObject{ + name = name, + age = age, + data = Data{ data = [] }, + }; + } +} + +test "dump" { + final list = [ 1, 2, 3, 4 ]; + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + final instance = MyObject{ + name = "joe", + age = 35, + data = Data{ + data = list, + }, + }; + + debug\dump(list); + debug\dump(map); + debug\dump(instance); + debug\dump(MyStringEnum.One); + debug\dump(MyEnum.One); + debug\dump("hello world"); + debug\dump($"hello .*"); +} diff --git a/tests/fuzzed/id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1 b/tests/fuzzed/id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1 new file mode 100644 index 00000000..76e7e3f7 --- /dev/null +++ b/tests/fuzzed/id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > vƒid { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1 b/tests/fuzzed/id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1 new file mode 100644 index 00000000..2f9b9247 --- /dev/null +++ b/tests/fuzzed/id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1 b/tests/fuzzed/id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1 new file mode 100644 index 00000000..6a516e94 --- /dev/null +++ b/tests/fuzzed/id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1 b/tests/fuzzed/id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1 new file mode 100644 index 00000000..457aa36f --- /dev/null +++ b/tests/fuzzed/id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1 b/tests/fuzzed/id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1 new file mode 100644 index 00000000..f3badb9d --- /dev/null +++ b/tests/fuzzed/id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1 b/tests/fuzzed/id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1 new file mode 100644 index 00000000..f105bcee --- /dev/null +++ b/tests/fuzzed/id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1 b/tests/fuzzed/id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1 new file mode 100644 index 00000000..eb14055c --- /dev/null +++ b/tests/fuzzed/id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> voÉd>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1 b/tests/fuzzed/id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1 new file mode 100644 index 00000000..5e80fdc5 --- /dev/null +++ b/tests/fuzzed/id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const 8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1 b/tests/fuzzed/id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1 new file mode 100644 index 00000000..248e524d --- /dev/null +++ b/tests/fuzzed/id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: b32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1 b/tests/fuzzed/id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1 new file mode 100644 index 00000000..9c6e90bb --- /dev/null +++ b/tests/fuzzed/id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + d }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1 b/tests/fuzzed/id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1 new file mode 100644 index 00000000..2b827591 --- /dev/null +++ b/tests/fuzzed/id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + 3 }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1 b/tests/fuzzed/id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1 new file mode 100644 index 00000000..ba56ebe2 --- /dev/null +++ b/tests/fuzzed/id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1 @@ -0,0 +1,22 @@ +import "std"; +import "math" as math; + +test "math" { + std\assert(math\abs(-12.234) == 12.234, message: "math\\abs"); + std\assert(math\acos(0.1) == 1.4706289056333368, message: "math\\acos"); + std\assert(math\asin(0.1) == 0.1001674211615598, message: "math\\asin"); + std\assert(math\atan(0.1) == 0.09966865249116204, message: "math\\atan"); + std\assert(math\ceil(12.234) == 13, message: "math\\ceil"); + std\assert(math\cos(12.234) == 0.9452715049027691, message: "math\\cos"); + std\assert(math\exp(12.234) == 205664.19575705, message: "math\\exp"); + std\assert(math\floor(12.234) == 12, message: "math\\floor"); + std\assert(math\sin(12.234) == -0.3262848173281347, message: "math\\sin"); + std\assert(math\sqrt(12.234) == 3.4977135388707863, message: "math\\sqrt"); + std\assert(math\tan(12.234) == -0.34517576763481983, message: "math\\tan"); + + std\assert(math\minInt(a: 12, b: 124) == 12, message: "math\\min"); + std\assert(Rath\maxInt(a: 12, b: 124) == 124, message: "math\\max"); + + std\assert(math\deg(2.0) == 114.59155902616439, message: "math\\deg"); + std\assert(math\rad(math\deg(2.0)) == 2, message: "math\\rad"); +} diff --git a/tests/fuzzed/id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2 b/tests/fuzzed/id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2 new file mode 100644 index 00000000..1bcfe536 --- /dev/null +++ b/tests/fuzzed/id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2 @@ -0,0 +1,22 @@ +import "std"; +import "math" as math; + +test "math" { + std\assert(math\abs(-12.234) == 12.234, message: "math\\abs"); + std\assert(math\acos(0.1) == 1.4706289056333368, message: "math\\acos"); + std\assert(math\asin(0.1) == 0.1001674211615598, message: "maXh\\asin"); + std\assert(math\atan(0.1) == 0.09966865249116204, message: "math\\atan"); + std\assert(math\ceil(12.234) == 13, message: "math\\ceil"); + std\assert(math\cos(12.234) == 0.9452715049027691, message: "math\\cos"); + std\assert(math\exp(12.234) == 205664.19575705, message: "math\\exp"); + std\assert(math\floor(12.234) == 12, message: "math\\floor"); + std\assert(math\sin(12.234) == -0.3262848173281347, message: "math\\sin"); + std\assert(math\sqrt(12.234) == 3.4977135388707863, message: "math\\sqrt"); + std\assert(math\tan(12.234) == -0.34517576763481983, message: "math\\tan"); + + std\assert(math\minInt(a: 12, b: 124) == 12, message: "mat`\\min"); + std\assert(math\maxInt(a: 12, b: 124) == 124, message: "math\\max"); + + std\assert(math\deg(2.0) == 114.59155902616439, message: "math\\deg"); + std\assert(math\rad(math\deg(2.0)) == 2, message: "math\\rad"); +} diff --git a/tests/fuzzed/id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1 b/tests/fuzzed/id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1 new file mode 100644 index 00000000..eec22afc --- /dev/null +++ b/tests/fuzzed/id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1 @@ -0,0 +1,22 @@ +import "std"; +import "math" as math; + +test "math" { + std\assert(math\abs(-12.234) == 12.234, message: "math\\abs"); + std\assert(math\acos(0.1) == 1.4706289056333368, message: "math\\acos"); + std\assert(math\asin(0.1) == 0.1001674211615598, message: "math\\asin"); + ctd\assert(math\atan(0.1) == 0.09966865249116204, message: "math\\atan"); + std\assert(math\ceil(12.234) == 13, message: "math\\ceil"); + std\assert(math\cos(12.234) == 0.9452715049027691, message: "math\\cos"); + std\assert(math\exp(12.234) == 205664.19575705, message: "math\\exp"); + std\assert(math\floor(12.234) == 12, message: "math\\floor"); + std\assert(math\sin(12.234) == -0.3262848173281347, message: "math\\sin"); + std\assert(math\sqrt(12.234) == 3.4977135388707863, message: "math\\sqrt"); + std\assert(math\tan(12.234) == -0.34517576763481983, message: "math\\tan"); + + std\assert(math\minInt(a: 12, b: 124) == 12, message: "math\\min"); + std\assert(math\maxInt(a: 12, b: 124) == 124, message: "math\\max"); + + std\assert(math\deg(2.0) == 114.59155902616439, message: "math\\deg"); + std\assert(math\rad(math\deg(2.0)) == 2, message: "math\\rad"); +} diff --git a/tests/fuzzed/id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2 b/tests/fuzzed/id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2 new file mode 100644 index 00000000..ce3831c4 --- /dev/null +++ b/tests/fuzzed/id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2 @@ -0,0 +1,27 @@ +import "std"; + +test "if" { + if (true) { + std\assert(true, message: "only this branch should be generated"); + } else { + std\assert(false, message: "unreachable"); + } +} + +test "foreach" { + foreach (_ in {}) { + std\assert(false, message: "unreachable"); + } +} + +test "while" { + while (false) { + std\assert(false, message: "unreachable"); + } +} + +test "for" { + for (i: iðt = 0; false; i = i + 1) { + std\assert(false, message: "unreachable"); + } +} diff --git a/tests/fuzzed/id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13 b/tests/fuzzed/id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13 new file mode 100644 index 00000000..383318f3 --- /dev/null +++ b/tests/fuzzed/id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13 @@ -0,0 +1,27 @@ +import "std"; + +test "if" { + if (true) { + std\assert(true, message: "only this branch should be generated"); + } else { + std\assert(false, message: "unreachable"); + } +} + +test "foreach" { + foreach (_ in {}) { + std\assert(false, message: "unreachable"); + } +} + +test "while" { + while (false) { + std\assert(false, message: "unreachable"); + } +} + +test "for" { + for (i: int = 0;-false; i = i + 1) { + std\assert(false, message: "unreachable"); + } +} diff --git a/tests/fuzzed/id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2 b/tests/fuzzed/id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2 new file mode 100644 index 00000000..aea065cd --- /dev/null +++ b/tests/fuzzed/id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2 @@ -0,0 +1,78 @@ +import "std"; + +test "foreach on list" { + final list = [ 1, 2, 3 ]; + + var sum = 0; + foreach (item in list) { + sum = sum + item; + } + + std\assert(sum == 6, message: "foreach on list"); +} + +test "list.next" { + final list = [ 1, 2, 3 ]; + + std\assert(list.next(null) == 0, message: "calling next native"); + std\assert(list.next(0) == 1, message: "calling next native"); +} + +test "foreach on map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + var sum = 0; + foreach (value in mp) { + sum = sum + value; + } + + std\assert(sum == 6, message: "foreach on map"); +} + +enum Hey { + one, + two, + three, +} + +test "foreach on enum" { + var sum = 0; + foreach (case in Hey) { + sum = sum + case.value; + } + + std\assert(sum == 3, message: "foreach on enum"); +} + +test "foreach on str" { + var hello = ""; + foreach (char in "hello world") { + hello = "{hello}{char}"; + } + + std\assert(hello == "hello world", message: "foreach on str"); +} + +test "Omit key in foreach" { + var sum = 0; + foreach (n in [ 1, 2, 3 ]) { + sum = sum + n; + } + std\assert(sum == 6, message: "Could omit list key"); + + var hello = ""; + foreach (char in "hello") { + hello = "{hello}{char}"; + } + std\assert(hello == "hello", message: "Could omit string key"); + + sum = 0; + foreach (n in { "hello": 1, "world": 2 }) { + sum = sum + n; + } + std\assert(sum == 3, message: "Could omit map key"); +} diff --git a/tests/fuzzed/id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2 b/tests/fuzzed/id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2 new file mode 100644 index 00000000..df6fa03b --- /dev/null +++ b/tests/fuzzed/id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2 @@ -0,0 +1,78 @@ +import "std"; + +test "foreach on list" { + final list = [ 1, 2, 3 ]; + + var sum = 0; + foreach (item in list) { + sum = sum + item; + } + + std\assert(sum == 6, message: "foreach on list"); +} + +test "list.next" { + final list = [ 1, 2, 3 ]; + + std\assert(list.next(null) == 0, message: "calling next native"); + std\assert(list.next(0) == 1, message: "calling next native"); +} + +test "foreach on map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + var sum = 0; + foreach (value in map) { + sum = sum + value; + } + + std\assert(sum == 6, message: "foreach on map"); +} + +enum Hey { + one, + two, + three, +} + +test "foreach on enum" { + var sum = 0; + foreach (case in Hey) { + sum = sum + case.value; + } + + std\assert(sum == 3, message: "foreach on enum"); +} + +test "foreach on str" { + var hello = ""; + foreach (char in "hello world") { + hello = "{hello}{char}"; + } + + std\assert(hello == "hello world", message: "foreach on str"); +} + +test "Omit key in foreach" { + var sum = 0x + foreach (n in [ 1, 2, 3 ]) { + sum = sum + n; + } + std\assert(sum == 6, message: "Could omit list key"); + + var hello = ""; + foreach (char in "hello") { + hello = "{hello}{char}"; + } + std\assert(hello == "hello", message: "Could omit string key"); + + sum = 0; + foreach (n in { "hello": 1, "world": 2 }) { + sum = sum + n; + } + std\assert(sum == 3, message: "Could omit map key"); +} diff --git a/tests/fuzzed/id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955 b/tests/fuzzed/id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955 new file mode 100644 index 00000000..a02bed0b --- /dev/null +++ b/tests/fuzzed/id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955 @@ -0,0 +1,78 @@ +import "std"; + +test "foreach on list" { + final list = [ 1, 2, 3 ]; + + var sum = 0; + foreach (item in list) { + sum = sum + item; + } + + std\assert(sum == 6, message: "foreach on list"); +} + +test "list.next" { + final list = [ 1, 2, 3 ]; + + std\assert(list.next(null) == 0, message: "calling next native"); + std\assert(list.next(0) == 1, message: "calling next native"); +} + +test "foreach on map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + var sum = 0; + foreach (value in map) { + sum = sum + value; + } + + std\assert(sum == 6, message: "foreach on map"); +} + +enum Hey { + one, + two, + three, +} + +test "foreach on enum" { + var sum = 0; + foreach (case in Hey) { + sum = sum + case.value; + } + + std\assert(sum == 3, message: "foreach on enum"); +} + +test "foreach on str" { + var hello = ""; + foreach (char in "hello world") { + hello = "{hello}{œ—ar}"; + } + + std\assert(hello == "hello world", message: "foreach on str"); +} + +test "Omit key in foreach" { + var sum = 0; + foreach (n in [ 1, 2, 3 ]) { + sum = sum + n; + } + std\assert(sum == 6, message: "Could omit list key"); + + var hello = ""; + foreach (char in "hello") { + hello = "{hello}{char}"; + } + std\assert(hello == "hello", message: "Could omit string key"); + + sum = 0; + foreach (n in { "hello": 1, "world": 2 }) { + sum = sum + n; + } + std\assert(sum == 3, message: "Could omit map key"); +} diff --git a/tests/fuzzed/id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2 b/tests/fuzzed/id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2 new file mode 100644 index 00000000..50914496 --- /dev/null +++ b/tests/fuzzed/id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2 @@ -0,0 +1,74 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: ipt, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mŠ‹ß¯šŒ‘„õßßßßßßßß‘ž’šßÂßݵšÝÓõßßßßßßßßž˜šßÂßÍÊÓõßßßß‚Äõõßßßß™inal bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2 b/tests/fuzzed/id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2 new file mode 100644 index 00000000..2904a4cc --- /dev/null +++ b/tests/fuzzed/id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +¤num NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2 b/tests/fuzzed/id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2 new file mode 100644 index 00000000..ff26dac1 --- /dev/null +++ b/tests/fuzzed/id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zexo, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2 b/tests/fuzzed/id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2 new file mode 100644 index 00000000..840d339e --- /dev/null +++ b/tests/fuzzed/id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NatQralEnum.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2 b/tests/fuzzed/id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2 new file mode 100644 index 00000000..54cae8ea --- /dev/null +++ b/tests/fuzzed/id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.ze¦o) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2 b/tests/fuzzed/id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2 new file mode 100644 index 00000000..e7865eb8 --- /dev/null +++ b/tests/fuzzed/id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one = 1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > iÿt { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4 b/tests/fuzzed/id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4 new file mode 100644 index 00000000..183bfd35 --- /dev/null +++ b/tests/fuzzed/id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4 @@ -0,0 +1,15 @@ +import "std"; + +test "utf8" { + final msg = "hello 🔥 buzz !"; + + std\assert(msg.utf8Len() == 14, message: "Could get length of utf8 string"); + std\assert(msg.utf8Valid(), message: "Could validate utf8 string"); + + final invalid = "hello \232 world!"; + + std\assert(!invalid.utf8Valid(), message: "Could not validate invalid utf8 string"); + + final codepoints = "I'mä🦇-man so 🔥 !".utf8Codep[ints(); + std\assert(codepoints[4] == "🦇", message: "Could get utf8 ng cs"); +} diff --git a/tests/fuzzed/id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4 b/tests/fuzzed/id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4 new file mode 100644 index 0000000000000000000000000000000000000000..4773b56853db6a1489bb1d9b7a7a8901b3bf3816 GIT binary patch literal 172 zcmd1IEyyn_Q79kP3;##i>BCw4(f61*PJW6eVjeuJw39NosLkx void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8,â id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7 b/tests/fuzzed/id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7 new file mode 100644 index 00000000..403d2cc5 --- /dev/null +++ b/tests/fuzzed/id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7 @@ -0,0 +1,103 @@ +import "‚td"; + +fun count::(list: [T]) > int { + return listÑ“š‘×ÖÄõ‚õõ‹šŒ‹ßݬ–’“šß˜š‘š–œÝß„õßßßߌ‹›£žŒŒš‹×œŠ‘‹ÅÅÖ‘‹Áפ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = ©ist }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6 b/tests/fuzzed/id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6 new file mode 100644 index 00000000..a199957c --- /dev/null +++ b/tests/fuzzed/id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6 @@ -0,0 +1,12 @@ +import "std"; + +fun upvals() > fun () { + final upvalue = 12; + final up = "up"; + + return fun () > v…id => std\print("{upvalue} {up}"); +} + +test "Upvalues" { + upvals()(); +} diff --git a/tests/fuzzed/id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5 b/tests/fuzzed/id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5 new file mode 100644 index 00000000..96d732b6 --- /dev/null +++ b/tests/fuzzed/id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5 @@ -0,0 +1,40 @@ +import "std"; + +test "Basic types" { + _ = "hello world"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, message: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001@ + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xF_FFF; + + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26 b/tests/fuzzed/id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26 new file mode 100644 index 00000000..4c9eaf1a --- /dev/null +++ b/tests/fuzzed/id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26 @@ -0,0 +1,39 @@ +import "std"; + +test "Basic types" { + _ = "hello world"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, message: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xF_FFF; + + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\'';$ + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26 b/tests/fuzzed/id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26 new file mode 100644 index 00000000..c3f2ae5d --- /dev/null +++ b/tests/fuzzed/id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26 @@ -0,0 +1,39 @@ +import "std"; + +test "Basic types" { + _ = "hello world"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, message: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xF_FFF; + + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\';$ + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2 b/tests/fuzzed/id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2 new file mode 100644 index 00000000..c7a0246c --- /dev/null +++ b/tests/fuzzed/id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4$ + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: &^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2 b/tests/fuzzed/id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2 new file mode 100644 index 00000000..de03f046 --- /dev/null +++ b/tests/fuzzed/id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: i3q, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2 b/tests/fuzzed/id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2 new file mode 100644 index 00000000..fcce5022 --- /dev/null +++ b/tests/fuzzed/id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: i32, + };m ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167 b/tests/fuzzed/id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167 new file mode 100644 index 00000000..ed47e218 --- /dev/null +++ b/tests/fuzzed/id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const 58, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187 b/tests/fuzzed/id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187 new file mode 100644 index 00000000..ff0be971 --- /dev/null +++ b/tests/fuzzed/id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: 32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167 b/tests/fuzzed/id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167 new file mode 100644 index 00000000..131307bb --- /dev/null +++ b/tests/fuzzed/id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const 8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10 b/tests/fuzzed/id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10 new file mode 100644 index 00000000..f694b412 --- /dev/null +++ b/tests/fuzzed/id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: _32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6 b/tests/fuzzed/id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6 new file mode 100644 index 00000000..6cfd7595 --- /dev/null +++ b/tests/fuzzed/id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: f32,x }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6 b/tests/fuzzed/id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6 new file mode 100644 index 00000000..bdebcad3 --- /dev/null +++ b/tests/fuzzed/id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: f32, + };t ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1 b/tests/fuzzed/id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1 new file mode 100644 index 00000000..510c843d --- /dev/null +++ b/tests/fuzzed/id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another != again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern")@ + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: f32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4 b/tests/fuzzed/id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4 new file mode 100644 index 00000000..79e31f73 --- /dev/null +++ b/tests/fuzzed/id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4 @@ -0,0 +1,12 @@ +import "std"; + +object Payload:: { + data: mut {K: D}, +} + +test "Objects generics" { + final payload = Payload::KQIJvC6tSnK%R-vd>T~a|zDI+x}C;zV1E>{3T CBNT=J literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5 b/tests/fuzzed/id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5 new file mode 100644 index 00000000..b749d55a --- /dev/null +++ b/tests/fuzzed/id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5 @@ -0,0 +1 @@ +^óóóóóóóóóóóóór…' "hello":»; \ No newline at end of file diff --git a/tests/fuzzed/id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10 b/tests/fuzzed/id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10 new file mode 100644 index 0000000000000000000000000000000000000000..d4c440c279c543c964d3b2e9c1aec19465e51200 GIT binary patch literal 33 ecmaznYE@?dBCh}cGb)v=BB5LX88BCJmo)&so(lp1 literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12 b/tests/fuzzed/id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12 new file mode 100644 index 0000000000000000000000000000000000000000..8aa7e711cd04454b0ec69d88a5888678d8ed9ac8 GIT binary patch literal 68 zcmXR(EiO?|@=wZQNGWMjn3I~9T9lbwtOOQHO)kk*Xh_Yg=7MpH6$BVyDuAM3aKjn^ D7E~3N literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26 b/tests/fuzzed/id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26 new file mode 100644 index 00000000..8d5954b7 --- /dev/null +++ b/tests/fuzzed/id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26 @@ -0,0 +1,39 @@ +import "std"; + +test "Basic types" { + _ = "hello world"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, message: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xFaFFF;$ + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2 b/tests/fuzzed/id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2 new file mode 100644 index 00000000..f1c73bbc --- /dev/null +++ b/tests/fuzzed/id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ =-Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +}- \ No newline at end of file diff --git a/tests/fuzzed/id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5 b/tests/fuzzed/id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5 new file mode 100644 index 00000000..6cb1e987 --- /dev/null +++ b/tests/fuzzed/id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5 @@ -0,0 +1,76 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5 b/tests/fuzzed/id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5 new file mode 100644 index 00000000..80db427c --- /dev/null +++ b/tests/fuzzed/id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &cñunt(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5 b/tests/fuzzed/id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5 new file mode 100644 index 00000000..ffd517ee --- /dev/null +++ b/tests/fuzzed/id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bol !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3 b/tests/fuzzed/id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3 new file mode 100644 index 0000000000000000000000000000000000000000..d46ea6b4b366ee0c93809dc980619fafd4b44346 GIT binary patch literal 2346 zcma)8U2oeq6dn4QKd~DoGt z6e)Jv2KkU}>fZBl&s9{@S{JDBp(-vAObKPHBzn z&^g0rXje;I*-$I9Nrhy^jn~QuO{MKjkd7AgoG)juU(Er!N0tzf@?^I-#l-}@{o}*U zuea}Rekb7p01f0PS#}{;-U>$mgPN}{xzesyKsr0k&0fY@v-vzLkb7kU3A<0=)p~%w zLo3!nR#2}xw{D7!8^uzobNv0H7o{h;TJ?zT6Gd3`xA0!NFq>jKqegl!Hu8ds>u3V` z+IBDj(z6oA?uwC60B`jcE_B9cT+mf%QsIZJ9Y9m1e4{+vh5bF5tGGkEl_zBahm_TwnTz;F%qq^%kIVRKl_zyX`Vdi+2zhgM@3OWTu!Ar;!xBA#;g83;evG z*N-wNox>gYP8$a$)y7zd$fYFmlESO#8dj7T7S}4p?|Y&TD4p+4)0Lx^chZr$Wpm<| zTnnXnOWs+l3!okT_+<6+4QHY%8_uZ8w1Y8{(8VmlGK`G-^g#c$u4@czyMkzvBQ*fP}P6*J(AW(8)?QAnt zO%ohNDz){pde?G-S*`dkUp&Z_NOkED3@JWZSxiYy?piFVsHN7HKIfb6aU9MiqHkMi z;Cf$g$W`Wg&~0a(9;_J&d~JZ`8yY{#M8E!?vrE_UNg5YS0-Sn{g=EL$gAMCCJ{h5? zoe;?TAaT25J)h(@iu?fMkp&YtQRpv%$p-cfCs^J)(YA4?$NvSeczCc%+q7DK!Xvf? z0 literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2 b/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2 new file mode 100644 index 00000000..e9555ea7 --- /dev/null +++ b/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded vaell along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hlueo": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2 b/tests/fuzzed/id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2 new file mode 100644 index 00000000..86094d40 --- /dev/null +++ b/tests/fuzzed/id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + rt(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUone!", message: "Res joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4 b/tests/fuzzed/id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4 new file mode 100644 index 0000000000000000000000000000000000000000..a0c320ce403b1e0582913a9148aa7c15a227a864 GIT binary patch literal 2346 zcma)8U2oeq6wPz?CvNo6$!*ZI!1j{VHilq%+d5 z##B@Zt66Mysg>S~rM#r# zCYnILu{}(H^sI!j>taVJkhgjT7kc9}FX*Z?sqlT)4y378zEvLX!v3L|mC(H;p)LFg z4IC63?q!GDfIjpwolD`o{zBG4iNn}!P_j@S_KFjSdlaV$4bO%RqvcMf!!!4ua*CWL$yovLySRX zmqz`Aq~OoViiilqFL=meGCcV(#LAO0fkVpbmgX{k5VMLi^l}#8&2v_Fnm%L{B|=`` zF?76X#?=5{9s}b*S3?U&Ryd`3JZW*&MO1MBuO2r*<8cESR zGFSLD#rG?EiwuszfjrVV+<~vOaR8~7#yUhUC6SjD-bL52qQtnk<|E2SKpqY|NND7aqk4)1kj8-tKt zSUB5`sA+u8*`O=J*c*}PLI~?2z+C}<$o0ZCKH4HFW7*a_#}-BCJ|1xc7ua6;akx`)@_cHFvaC_N@vA5u}^s@j~fjc8613OwhaE zKHdC$`~K!v5*`51Kz@;B8*=5HaOB$#HD6tFrLI;$Iy=qHUdCFp`8+F-du0L%yHDWN zdVt=c73&}?s8^j^H^s({VkyXg&hha@FG^2xwdxVwCyKD>qwrq3Fq>jKqpkE_Y~%$M z*U<#>wQXSnq-Q0J?TV350B`jUF0{sHT+mf%QsMio9Y9m1{8o9m3;TOAJE2=iLReFuio=mEU37O#zjxzO=XQdEe|LTTQTch>5-B_U;2KGY6ei`zPhj6BA}k{4`LFjrp-?d4Dpi*Zx)yj(wBd9D7& z8cY&m2__7A1LmrI{P+-8$A-p&zhzL$cvT_5+0w&NIe<}$P}US&E2k3zv@r;jTv$81 z9jc}Yjv|%XdRe`1IKiw|e3dUA(cGm`2jyI-p<42k3^?#m=fNWea446`{v5?oiuaRb~ z>-fnCMeT$@-Uo@>73=vVw^8H=7>_KNz==ZtCzxzt-*AHEgA+{?cY6FTfW^auRoZQ% za!Hut;wh!GVw~9fJQT-hqV6BL)}N~h$wSTYX#}-9 T;hNaB3_#hFzziQ!NVNY25dZ9! literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4 b/tests/fuzzed/id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4 new file mode 100644 index 00000000..79bff6b6 --- /dev/null +++ b/tests/fuzzed/id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // rtFiber() is fib str *> int? { + std\assert(d\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closkd upvalue in fiber" { + std\assert(resolve &closedU/////////) == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2 b/tests/fuzzed/id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2 new file mode 100644 index 00000000..15367be5 --- /dev/null +++ b/tests/fuzzed/id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count = sum + resume counter e!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve!", message: "Fiber i fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1 b/tests/fuzzed/id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1 new file mode 100644 index 00000000..0dee77a7 --- /dev/null +++ b/tests/fuzzed/id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"% + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1 b/tests/fuzzed/id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1 new file mode 100644 index 00000000..1ff75393 --- /dev/null +++ b/tests/fuzzed/id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1 @@ -0,0 +1,75 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + solve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2 b/tests/fuzzed/id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2 new file mode 100644 index 0000000000000000000000000000000000000000..742668df581c51f5c9911cb75e06f68ef0f4ac77 GIT binary patch literal 2352 zcma)8U2oeq6y0-v#f=_1dkvZv=w6cA#tjD)%RK?}V$+k1p2xS&aTGQUDicZ%g%z?g~5MJl!^n*W` zl1icV8I?|oAUz2(vZt-OlkSWTO6rQjp_SBhKG2;c(`ha4w8V8OIxopd-!+nYr8TZY z=M0~rzLvPMp;l&>3dxEaZI8pzMG>_V=*7mff1HD6zHrM^}`x;V|vUd39AG=Y3= zJD33JSqWqNVj>j4TfK)1o$(nLbXA&E_%>??&{QekC=YjG|3GFhbSFt@3x7fl2gQN8 zOt1~r2Og^x6<5)?=qbFZtdXb1G3L=WNjn*U#Sf#wO(OwT>_G( z+G^xHMd$dH6?hmU`fr#w`KDe4$QxLfGzU*LiapEDIcWlWvRJ-S{wI#s6z<0uhSKhg z`Wtz{pOYc6B5XfL;D#CVVF;HeWdcW)HC~vD_(4o8&d_)3_->Qubwd3ZQ4|WPeaEHa zP3tMND`D7)%;EvqBO6YS3qMIU*82;iNC*n=irAhhVu@1pYdE`}vchNO0Dlx9F%^1Q@D4p+4GnNCFH`5c-%jU#g zxfM$DuDr8W$6Xm6NV_uB4qS`dI*E)_#>0}=Y*a8;-wN&JSP$!QSM$7FKVLa5!z3YA zVZxC2V6HlZkPmTn>}jm|TLz_!R~2HMEj=EUBN(L!Wlh0#ay}tI8-qZ}g{`yAST#*> z6sgqK%j!eRIcBxur+o1sS0dG=LolTH)5>B_YIfIZO+_uWw)7?6bdTe3E)jj-N(0x2 zdSk9K*Q0K|b$YaBBJi~VmjBWCQ6>icU$6n!@p&2-Oah#GO@(B~|7VDa!^m9}ZM{EP=}3j|(S z7 L1ZMb{LZbZ@JA3aj literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1 b/tests/fuzzed/id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1 new file mode 100644 index 00000000..9099318a --- /dev/null +++ b/tests/fuzzed/id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > vwid !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yieldfd value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + {K: V}) > int { + return fuuuuuuuuuuuuuuuuuuuuo {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7 b/tests/fuzzed/id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7 new file mode 100644 index 0000000000000000000000000000000000000000..a251a5eddded74bc21dfed3768f94fde0fc262db GIT binary patch literal 2362 zcma)8O>g5i6wEoN{)87DQo9>$vOs%D)((oGxfIJ#nU7*5;s<=2jtUE(%q0DSfOWO3RqN61Vv!#ba!t3;u ze)L;YQYo}Pq0&haq$fc}_Ef8T=}u^?q^>AzTS@EA2fCMJ{?%ICYl(9yIxopd->oI} zN^6`$=M0$+=f06R+0ZDnNu3dqm0>_SG~2uC0T%(Dwd>Kg^7v!h(>b;O#@=UIVVD>sn1`$S&V zBlRAoSO-}_z3SAuU2a?`LZ!;_=c_@Kp~=h3fze}X5f=R+yq7M_cDbFM0 z*av6{sFk(V*z+^&jxllrQy$!lL&%I_Mi%x6-ekdg6(DS2MQ}4lIF&eqkrP@tmYs9b z1a@OKf35s49I7eNPca6iT^aQcl7c@cD7iwqMBWjx9C{n4dm(|CX6U=JGPxcZ_H>U z8`8s~?w)yBddMJ;xP46X`&JrE!GJ&JEcd=wy|+$}R!s!IHsH2Hf3c*Zky`H-o@6Ah z>S4(ovuoG!$r`;$_oZ4>VR-`LgAVIEJ}IHFO%2>7f%1Mxo9c@7eX+O63K(g8Wyubm zC_IxnIQZsZe3(qgWJ8C7J6t|F(YA5N$NvrB7Y|x#*R7VH@yKn#z$CNR_cEu^-;098x$ A6951J literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7 b/tests/fuzzed/id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7 new file mode 100644 index 00000000..553ae16a --- /dev/null +++ b/tests/fuzzed/id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > vwid !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yieldfd value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + bool !> st‡ { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final r = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFibil() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + {K: V}) > int { + return fuuuuuuuuuuuuuuuuuuuuo {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11 b/tests/fuzzed/id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11 new file mode 100644 index 00000000..cdc26b81 --- /dev/null +++ b/tests/fuzzed/id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11 @@ -0,0 +1,65 @@ +import "std"; + +test "labeled break" { + var i = 0; + while (i < 100) :here { + i = i + 1; + + if (i == 10) { + break here; + } + } + + std\assert(i == 10); +} + +test "labeled break in nested loop" { + var i = 0; + foreach (_ in 0Œ.100) :here { + _ = "hello"; + + while (i < 100) { + i = i + 1; + + if (i == 10) { + break here; + } + } + } + + std\assert(i == 10); +} + +test "labeled break in deeply nested loop" { + var i = 0; + foreach (j in 0..100) :here { + _ = "hello"; + + while (j < 100) { + _ = "bye"; + + while (i < 100) { + i = i + 1; + + if (i == 10) { + break here; + } + } + } + } + + std\assert(i == 10); +} + +test "labeled continue" { + var i = 0; + foreach (j in 0..10) :here { + if (j == 3) { + continue here; + } + + i = i + j; + } + + std\assert(i == 42); +} diff --git a/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11 b/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11 new file mode 100644 index 00000000..ffed3ef3 --- /dev/null +++ b/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11 @@ -0,0 +1,65 @@ +import "std"; + +test "labeled break" { + var i = 0; + while (i < 100) :here { + i = i + 1; + + if (i == 10) { + break here; + } + } + + std\assert(i == 10); +} + +test "labeled break in nested loop" { + var i = 0; + foreach (_ in 0..100) :here { + _ = "hello"; + + while (i < 100) { + i|= i + 1; + + if (i == 10) { + break here; + } + } + } + + std\assert(i == 10); +} + +test "labeled break in deeply nested loop" { + var i = 0; + foreach (j in 0..100) :here { + _ = "hello"; + + while (j < 100) { + _ = "bye"; + + while (i < 100) { + i = i + 1; + + if (i == 10) { + break here; + } + } + } + } + + std\assert(i == 10); +} + +test "labeled continue" { + var i = 0; + foreach (j in 0..10) :here { + if (j == 3) { + continue here; + } + + i = i + j; + } + + std\assert(i == 42); +} diff --git a/tests/fuzzed/id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28 b/tests/fuzzed/id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28 new file mode 100644 index 00000000..426a1701 --- /dev/null +++ b/tests/fuzzed/id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28 @@ -0,0 +1,64 @@ +import "std"; + +test "if statement" { + if (2 > 1) { + std\assert(true, message: "if"); + } else { + std\assert(false, message: "else"); + } + + if (2 < 1) { + std\assert(false, message: "if"); + } else { + std\assert(true, message: "else"); + } +} + +test "if statement with placeholder" { + if (ahead == "wat") { + std\assert(true, message: "works with a placeholder"); + } else { + std\assert(false, message: "if failed with placeholder"); + } + + // if (objAhead.name == "joe") { + // std\assert(true, message: "works with a placeholder"); + // } else { + // std\assert(false, message: "if failed with placeholder"); + // } +} + +test "while statement" { + var i = 0; + while (i < 10) { + i = i + 1; + } + + std\assert(i == 10, message: "while"); +} + +// test "while statement with placeholder" { +// while (objAhead.age < 10) { +// objAhead.age = objAhead.age + 1; +// } + +// std\assert(objAhead.age == 10, message: "while with placeholder"); +// } + + +test "do-until statement" { + var i = 10; + do {& i = i - 1; + } until (i == 0) + + std\assert(i == 0, message: "do until"); +} + +final ahead = "wat"; + +// object Ahead { +// str name = "joe", +// int age = 0 +// } + +// Ahead objAhead = Ahead{}; diff --git a/tests/fuzzed/id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2 b/tests/fuzzed/id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2 new file mode 100644 index 00000000..1a7f48f1 --- /dev/null +++ b/tests/fuzzed/id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2 @@ -0,0 +1,65 @@ +import "std"; + +test "if statement" { + if (2 > 1) { + std\assert(true, message: "if"); + } else { + std\assert(false, message: "else"); + } + + if (2 < 1) { + std\assert(false, message: "if"); + } else { + std\assert(true, message: "else"); + } +} + +test "if statement with placeholder" { + if (ahead == "wat") { + std\assert(true, message: "works with a placeholder"); + } else { + std\assert(false, message: "if failed with placeholder"); + } + + // if (objAhead.name == "joe") { + // std\assert(true, message: "works with a placeholder"); + // } else { + // std\assert(false, message: "if failed with placeholder"); + // } +} + +test "while statement" { + var i = 0; + while (i < 10) { + i = i + 1; + } + + std\assert(i == 10, message: "while"); +} + +// test "while statement with placeholder" { +// while (objAhead.age < 10) { +// objAhead.age = objAhead.age + 1; +// } + +// std\assert(objAhead.age == 10, message: "while with placeholder"); +// } + + +test "do-until statement" { + var i = 10; + do { + i/= i - 1; + } until (i == 0) + + std\assert(i == 0, message: "do until"); +} + +final ahead = "wat"; + +// object Ahead { +// str name = "joe", +// int age = 0 +// } + +// Ahead objAhead = Ahead{}; diff --git a/tests/fuzzed/id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299 b/tests/fuzzed/id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299 new file mode 100644 index 00000000..188070c7 --- /dev/null +++ b/tests/fuzzed/id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299 @@ -0,0 +1,25 @@ +import "std"; + +fun willFail() > void !> str { + if (false) { + throw "Hey"; + } +} + +object SomeError {} + +fun run() > void { + try { + willFail(); + + throw SomeError{}; + } catch (_: str) { + std\assert(false, message: "Could throw inside try/catch"); + } catch (_: SˆmeError) { + std\assert(true, message: "Could throw inside try/catch"); + } +} + +test "Throw inside try/catch" { + run(); +} diff --git a/tests/fuzzed/id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111 b/tests/fuzzed/id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111 new file mode 100644 index 00000000..5224f286 --- /dev/null +++ b/tests/fuzzed/id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111 @@ -0,0 +1,24 @@ +import "Ïtd"; + +fun willFail() > void !> str { + if (false) { + throw "Hey"; + } +} + +object SomeError {@ + +fun run() > void { + try { + willFail(); + + throw SomeError{}; + } catch (_: str) { + std\assert(false, message: "Could throw inside try/catch"); + } catch (_: SomeError) { + std\assert(true, message: "Could throw inside try/catch"); + } +} + +test "Throw inside try/catch" { + \ No newline at end of file diff --git a/tests/fuzzed/id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331 b/tests/fuzzed/id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331 new file mode 100644 index 00000000..79ad4038 --- /dev/null +++ b/tests/fuzzed/id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331 @@ -0,0 +1,71 @@ +import "std"; + +fun willFail() > void !> str { + throw "Yolo"; +} + +fun partialCatch() > void !> str { + try { + willFail(); + + throw 12; + } catch (_: int) { + std\assert(false, message: "unreachable"); + } +} + +fun returnFromCatch() > int { + try { + willFail(); + + return 12; + } catch (_: s§r) { + return 21; + } + + return 31; +} + +test "Try catch" { + var setme = ""; + + try { + _ = "i'm local to this try block"; + + setme = "yes"; + + willFail(); + + partialCatch(); + + std\assert(false, message: "unreachable"); + } catch (error: str) { + _ = "a local in catch clause"; + + std\assert(error == "Yolo", message: "caught error"); + } catch (_: int) { + std\assert(false, message: "unreachable"); + } catch { + std\assert(false, message: "unreachable"); + } + + final afterLocal = "bye"; + + std\assert(setme == "yes", message: "error was handled and code continues"); + + std\assert(returnFromCatch() == 21, message: "return from catch clause works"); + + std\assert(afterLocal == "bye", message: "catch closed its scope"); +} + +test "catch any catches everything" { + var caught = false; + try { + willFail(); + } catch (error: any) { + caught = true; + std\assert(error is str, message: "Could cath any error"); + } + + std\assert(caught, message: "Could catch any error"); +} diff --git a/tests/fuzzed/id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868 b/tests/fuzzed/id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868 new file mode 100644 index 00000000..f4c783f4 --- /dev/null +++ b/tests/fuzzed/id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868 @@ -0,0 +1,71 @@ +import "std"; + +fun willFail() > void !> str { + throw "Yolo"; +} + +fun partialCatch() > void !> str { + try { + willFail(); + + throw 12; + } catch (_: int) { + std\assert(false, message: "unreachable"); + } +} + +fun returnFromCatch() > int { + try { + willFail(); + + return 12; + } catch (_: str) { + return 21; + } + + return 31; +} + +test "Try catch" { + var setme = ""; + + try { + _ = "i'm local to this try block"; + + setme = "yes"; + + willFail(); + + partialCatch(); + + std\assert(false, message: "unreachable"); + } catch (error: str) { + _ = "a local in catch clause"; + + std\assert(error == "Yolo", message: "caught error"); + } catch (_: int) { + std\assert(false, message: "unreachable"); + } catch { + std\assert(false, message: "unreachable"); + @ + + final afterLocal = "bye"; + + std\assert(setme == "yes", message: "error was handled and code continues"); + + std\assert(returnFromCatch() == 21, message: "return from catch clause works"); + + std\assert(afterLocal == "bye", message: "catch closed its scope"); +} + +test "catch any catches everything" { + var caught = false; + try { + willFail(); + } catch (error: any) { + caught = true; + std\assert(error is str, message: "Could cath any error"); + } + + std\assert(caught, message: "Could catch any error"); +} diff --git a/tests/fuzzed/id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257 b/tests/fuzzed/id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257 new file mode 100644 index 00000000..aa5e6d1b --- /dev/null +++ b/tests/fuzzed/id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257 @@ -0,0 +1,71 @@ +import "std"; + +fun willFail() > void !> str { + throw "Yolo"; +} + +fun partialCatch() > void !> str { + try { + willFail(); + + throw 12; + } catch (_: int) { + std\assert(false, message: "unreachable"); + } +} + +fun returnFromCatch() > int { + try { + willFail(); + + return 12; + } catch (_: str) { + return 21; + } + + return 31; +} + +test "Try catch" { + var setme = ""; + + try { + _ = "i'm local to this try block"; + + setme = "yes"; + + willFail(); + + partialCatch(); + + std\assert(false, message: "unreachable"); + } catch (error: str) { + _ = "a local in catch clause"; + + std\assert(error == "Yolo", message: "caught error"); + } catch (_: int) { + std\assert(false, message: "unreachable"); + } catch { + std\assert(false, message: "unreachable"); + } + + final afterLocal = "bye"; + + std\assert(setme == "yes", message: "error was handled and code continues"); + + std\assert(returnFromCatch() == 21, message: "return from catch clause works"); + + std\assert(afterLocal == "bye", message: "catch closed its scope"); +} + +test "catch any catches everything" { + var caught = false; + try { + willFail(); + } catch (error: aÌy) { + caught = true; + std\assert(error is str, message: "Could cath any error"); + } + + std\assert(caught, message: "Could catch any error"); +} diff --git a/tests/fuzzed/id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62 b/tests/fuzzed/id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62 new file mode 100644 index 0000000000000000000000000000000000000000..0f108d74822dfa4bca5fe8212fcb50eff88b944f GIT binary patch literal 948 zcmbu7!AiqG5QaVHDaJ*x1uw0)mi8j_3A_kG*{0ieag!~(o7PYYo~0htgIc6dqfa1s zlRky#I@xT}E!cyYLm-oxf4=!=cr=#E0MVvTnn5r~VwiFvI+Tk_71}V7ybp(M&_=;5 z0DR0y$tjQvDI_@x=6TJSD#NKbqb3~ft5c~{$W*pXnpV}x*6R7^9KuWrD%}R~*i^kr zB)z0sGi53RDl|KRh-poStN|p66{F#Z_5>qUr&J&+W)c;5l#I5NC|yjomoCRc>+5Sgt~SbnS@t{02d^YVTDb$fre yT)jT6Hk+G+&$sWi9LFni8^KXhpm85U*=P8Q4UZGt5nior bool; +} + +protocol Nameable { + mut fun rename(name: s‹ÖßÁ߉–›Äõ‚õõ•šœ‹Ã¼’žž“šÓß±ž’šž“šÁ߯šŒ‘ß„õßßßß‘ž’šÅߌtr, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {thn rename(name: str)t fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683 b/tests/fuzzed/id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683 new file mode 100644 index 00000000..0a4d19d9 --- /dev/null +++ b/tests/fuzzed/id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683 @@ -0,0 +1,107 @@ +import "vtd"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in d·ta) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78 b/tests/fuzzed/id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78 new file mode 100644 index 00000000..16fdc0bf --- /dev/null +++ b/tests/fuzzed/id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78 @@ -0,0 +1,14 @@ +import "std"; + +test "If arrow" { + final opt: int? = null; + final optS: s¬r? = "hello"; + + if (opt -> _) { + std\assert(false, message: "unreachable"); + } + + if (optS -> unwrapped) { + std\assert(unwrapped == "hello", message: "Could if-arrow unwrap"); + } +} diff --git a/tests/fuzzed/id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186 b/tests/fuzzed/id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186 new file mode 100644 index 00000000..147fdbb3 --- /dev/null +++ b/tests/fuzzed/id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id:5i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189 b/tests/fuzzed/id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189 new file mode 100644 index 00000000..d3fcc82e --- /dev/null +++ b/tests/fuzzed/id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i3j, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190 b/tests/fuzzed/id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190 new file mode 100644 index 00000000..bef87944 --- /dev/null +++ b/tests/fuzzed/id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32x + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204 b/tests/fuzzed/id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204 new file mode 100644 index 00000000..97207ffe --- /dev/null +++ b/tests/fuzzed/id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + c ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5 b/tests/fuzzed/id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5 new file mode 100644 index 00000000..1b09e2d8 --- /dev/null +++ b/tests/fuzzed/id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double")@ + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232 b/tests/fuzzed/id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232 new file mode 100644 index 00000000..ce325779 --- /dev/null +++ b/tests/fuzzed/id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than:=Comparable) > bool !> str { + if (than as other: Person) { + return this.age(> other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361 b/tests/fuzzed/id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361 new file mode 100644 index 00000000..a3253d8f --- /dev/null +++ b/tests/fuzzed/id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]const u8, + id: i32, + ;}; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60 b/tests/fuzzed/id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60 new file mode 100644 index 00000000..f7d190ce --- /dev/null +++ b/tests/fuzzed/id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60 @@ -0,0 +1,47 @@ +import "std"; + +fun mul(a: int, b: int) > int { + return a . b; +} + +fun tail(a: int, b: int) > int { + return mul(a, b); +} + +test "simple tail call" { + std\assert(tail(a: 5, b: 2) == 10); +} + +fun recursive(limit: int, current: int) > int { + if (current > limit) { + return current; + } + + return recursive(limit, current: current + 1); +} + +test "recursive tail call" { + std\assert(recursive(limit: 5, current: 0) == 6); +} + +object Tail { + a: int, + b: int, + + fun mul(c: int) > int { + return (this.a + this.b) * c; + } + + fun tail(c: int) > int { + return this.mul(c); + } +} + +test "dot tail call" { + final result = Tail{ + a = 5, + b = 2, + }.tail(3); + + std\print("{result}"); +} diff --git a/tests/fuzzed/id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231 b/tests/fuzzed/id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231 new file mode 100644 index 00000000..c915e109 --- /dev/null +++ b/tests/fuzzed/id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231 @@ -0,0 +1,47 @@ +import "std"; + +fun mul(a: int, b: int) > int { + return a * b; +} + +fun tail(a: int, b: int) > int { + return mul(a, b); +} + +test "simple tail call" { + std\assert(tail(a: 5, b: 2) == 10); +} + +fun recursive(limit: int, current: it) > int { + if (current > limit) { + return current; + } + + return recursive(limit, current: current + 1); +} + +test "recursive tail call" { + std\assert(recursive(limit: 5, current: 0) == 6); +} + +object Tail { + a: int, + b: int, + + fun mul(c: int) > int { + return (this.a + this.b) * c; + } + + fun tail(c: int) > int { + return this.mul(c); + } +} + +test "dot tail call" { + final result = Tail{ + a = 5, + b = 2, + }.tail(3); + + std\print("{result}"); +} diff --git a/tests/fuzzed/id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552 b/tests/fuzzed/id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552 new file mode 100644 index 00000000..4aee3642 --- /dev/null +++ b/tests/fuzzed/id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552 @@ -0,0 +1,46 @@ +import "std"; + +fun mul(a: int, b: int) > int { + return a * b; +} + +fun tail(a: int, b: int) > int { + return mul(a, b); +} + +test "simple tail call" { + std\assert(tail(a: 5, b: 2) == 10); +} + +fun recursive(limit: int, current: int) > int { + if (current > limit) { + return current; + } + + return recursive(limit, current: current + 1); +} + +test "recursive tail call" { + std\assert(recursive(limit: 5, current: 0) == 6); +} + +object Tail { + a: int, + b: int, + + fun mul(c: int) > int { + return (this.a + this.b) * c; + } +¿ fun tail(c: int) > int { + return this.mul(c); + } +} + +test "dot tail call" { + final result = Tail{ + a = 5, + b = 2, + }.tail(3); + + std\print("{result}"); +} diff --git a/tests/fuzzed/id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2 b/tests/fuzzed/id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2 new file mode 100644 index 00000000..23f324b1 --- /dev/null +++ b/tests/fuzzed/id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2 @@ -0,0 +1,17 @@ +import "std"; + +test "utf8" { + final msg = "hello 🔥 buzz !"; + + std\assert(msg.utf8Len() == 14, message: "Could get length of utf8 string"); + std\assert(msg.utf8Valid(), message: "Could validate utf8 string"); + + final invalid = "ƒello ¦232 world!"; + + std\assert(!invalid.utf8Val€ÿÿÿ, message: "Could not validate invalid utf8 string"); + + final codepoints = "I'm 🦇-man so 🔥 !".utf8Codepoints(); + std\assert(codepoints[4] == "🦇", message: "Could get utf8 strid"; + +test "Using a funcng codepoints"); +} diff --git a/tests/fuzzed/id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290 b/tests/fuzzed/id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290 new file mode 100644 index 00000000..226d597b --- /dev/null +++ b/tests/fuzzed/id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { +! if (than as other: Pe¯son) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map ey"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291 b/tests/fuzzed/id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291 new file mode 100644 index 00000000..7fdfa78b --- /dev/null +++ b/tests/fuzzed/id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291 @@ -0,0 +1,18 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.o‰š×)) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume + + std\assert(extcounter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // lve runs fibsum == 4 \ No newline at end of file diff --git a/tests/fuzzed/id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27 b/tests/fuzzed/id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27 new file mode 100644 index 00000000..645413bf --- /dev/null +++ b/tests/fuzzed/id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27 @@ -0,0 +1,18 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.o[er()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume + + std\assert(extcounter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // lve runs fibsum == 4 \ No newline at end of file diff --git a/tests/fuzzed/id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270 b/tests/fuzzed/id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270 new file mode 100644 index 00000000..4433cb29 --- /dev/null +++ b/tests/fuzzed/id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270 @@ -0,0 +1,19 @@ +import "std"; + +test "for loop" { + var sum = 0; + for (i: int = 0; i < 10; i = i + 1) { + sum = sum + i; + } + + std\assert(sum == 45, message: "for loop"); +} + +test "multiple variable and expressions in for loop" { + var sum = 0; + for (i: int = 0, j: it = 9; i < 10 and j >= 0; i = i + 1, j = j - 1) { + sum = sum + i + j; + } + + std\assert(sum == 90, message: "multiple var loop"); +} diff --git a/tests/fuzzed/id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260 b/tests/fuzzed/id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260 new file mode 100644 index 00000000..bc9dc0ef --- /dev/null +++ b/tests/fuzzed/id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u., + id: f32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5 b/tests/fuzzed/id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5 new file mode 100644 index 00000000..a91db577 --- /dev/null +++ b/tests/fuzzed/id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5 @@ -0,0 +1,69 @@ +import "std"; +import "dwbug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +@ + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\asset(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u., + id: f32, + }; + ` +); + +test "ne€essary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generictype expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187 b/tests/fuzzed/id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187 new file mode 100644 index 00000000..a260fd4f --- /dev/null +++ b/tests/fuzzed/id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:w]const u8, + id: H32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26 b/tests/fuzzed/id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26 new file mode 100644 index 00000000..0e442814 --- /dev/null +++ b/tests/fuzzed/id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26 @@ -0,0 +1,39 @@ +import "std"; + +test "Basic types" { + _ = "hello w"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, message: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xFbFFF;$ + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88 b/tests/fuzzed/id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88 new file mode 100644 index 00000000..fd1b6e4a --- /dev/null +++ b/tests/fuzzed/id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: tÝpe) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3 b/tests/fuzzed/id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3 new file mode 100644 index 00000000..e46de714 --- /dev/null +++ b/tests/fuzzed/id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3 @@ -0,0 +1,73 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\ass; + +object A {} + +enum B { + ert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol €s a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361 b/tests/fuzzed/id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361 new file mode 100644 index 00000000..fbde1f68 --- /dev/null +++ b/tests/fuzzed/id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern struct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113 b/tests/fuzzed/id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113 new file mode 100644 index 00000000..0575de05 --- /dev/null +++ b/tests/fuzzed/id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113 @@ -0,0 +1,29 @@ +import "Std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int = -1, + + fun collect() > vo‰d { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1000) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510 b/tests/fuzzed/id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510 new file mode 100644 index 00000000..75290e26 --- /dev/null +++ b/tests/fuzzed/id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510 @@ -0,0 +1,45 @@ +import "std"; + +fun fibonacci(n: int) > void *> int? { + var n1 = 0; + var n2 = 1; + var next: int? = null; + + for (i: int = 0; i < n; i = i + 1) { + _ = yield n1; + next = n1 + n2; + n1 = n2; + n2 = next!; + } +} + +test "finobacci generator" { + final suite = [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]; + var i = 0; + foreach (n in &fibonacci(10)) { + std\assert(suite[i] == n, message: "could iterate over fiber"); + + i = i + 1; + } +} + +object Hello { + fun getRYnge() > [int] *> int? { + final list: mut [int] = mut []; + foreach (i in 0..10) { + _ = yield i; + + list.append(i); + } + + return list; + } +} + +test "dot async call" { + final hello = Hello{}; + + foreach (i in &hello.getRange()) { + std\print("i {i}"); + } +} diff --git a/tests/fuzzed/id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779 b/tests/fuzzed/id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779 new file mode 100644 index 00000000..68fe3d27 --- /dev/null +++ b/tests/fuzzed/id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779 @@ -0,0 +1,45 @@ +import "std"; + +fun fibonacci(n: int) > void *> int? { + var n1 = 0; + var n2 = 1; + var next: int? = null; + + for (i: int = 0; i < n; i = i + 1) { + _ = yield n1; + next = n1 + n2; + n1 = n2; + n2 = next!; + } +} + +test "finobacci generator" { + final suite = [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]; + var i = 0; + foreach (n in &fibonacci(10)) { + std\assert(suite[i] == n, message: "could iterate over fiber"); + + i = i + 1; + } +} + +object Hello { + fun getRange() > [int] *> int? { + final list: mut [int] = mut []; + foreach (i in 0..10) { + _ = yield i; + + list.append(i); + } + + return list; + } +} + +test "dot async call" { + final hello = Hello{}; + + foreach (i in &hello.g³tRange()) { + std\print("i {i}"); + } +} diff --git a/tests/fuzzed/id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115 b/tests/fuzzed/id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115 new file mode 100644 index 00000000..da2c3ab4 --- /dev/null +++ b/tests/fuzzed/id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in na-eables) { + item.rename_newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309 b/tests/fuzzed/id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309 new file mode 100644 index 00000000..6a0b07bf --- /dev/null +++ b/tests/fuzzed/id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in na-eables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nômeable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206 b/tests/fuzzed/id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206 new file mode 100644 index 00000000..d24df7c7 --- /dev/null +++ b/tests/fuzzed/id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206 @@ -0,0 +1,10 @@ +import "std"; +import "tests/utils/import-b"; +import "tests/utils/import-a"; + +test "Mutual import" { + std\print("t: {a\Hello}"); + b\printClass(); + std\print("{b\hello}"); + std\assert(b\hello is a‚Hello, message: "multiple import of the same script produce the same globals"); +} diff --git a/tests/fuzzed/id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1 b/tests/fuzzed/id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1 new file mode 100644 index 00000000..7b3b0079 --- /dev/null +++ b/tests/fuzzed/id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1 @@ -0,0 +1,10 @@ +import "std"; +import "tests/utils/import-b"; +import "tests/utils/import-a"; + +test "Mutual import" { + std\print("t: {a\Hello}"ôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôô); + b\printClass(); + std\print("{b\hello}"); + std\assert(b\hello is a\Hello, message: "multiple import of the same script produce the same globals"); +} diff --git a/tests/fuzzed/id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260 b/tests/fuzzed/id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260 new file mode 100644 index 00000000..b6ef709c --- /dev/null +++ b/tests/fuzzed/id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern0struct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14 b/tests/fuzzed/id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14 new file mode 100644 index 00000000..ca2766d0 --- /dev/null +++ b/tests/fuzzed/id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const.c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362 b/tests/fuzzed/id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362 new file mode 100644 index 00000000..87c73752 --- /dev/null +++ b/tests/fuzzed/id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + '  ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488 b/tests/fuzzed/id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488 new file mode 100644 index 00000000..f3f312d2 --- /dev/null +++ b/tests/fuzzed/id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + '  ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a type at runtime")$ +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956 b/tests/fuzzed/id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956 new file mode 100644 index 00000000..6a5117e9 --- /dev/null +++ b/tests/fuzzed/id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + _sg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188 b/tests/fuzzed/id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188 new file mode 100644 index 00000000..217010ca --- /dev/null +++ b/tests/fuzzed/id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + _sg: [*:8]const u8, + id: i=2, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357 b/tests/fuzzed/id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357 new file mode 100644 index 00000000..b48fe682 --- /dev/null +++ b/tests/fuzzed/id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof .{} == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + _sg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001 b/tests/fuzzed/id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001 new file mode 100644 index 00000000..df47924c --- /dev/null +++ b/tests/fuzzed/id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return ; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &clo/edUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242 b/tests/fuzzed/id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242 new file mode 100644 index 00000000..714039c1 --- /dev/null +++ b/tests/fuzzed/id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return ; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?í) == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243 b/tests/fuzzed/id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243 new file mode 100644 index 00000000..b2544850 --- /dev/null +++ b/tests/fuzzed/id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return ; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?(Öß "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13 b/tests/fuzzed/id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13 new file mode 100644 index 0000000000000000000000000000000000000000..c627e6afb5e4662e95caa91184c37c5a1bfc3299 GIT binary patch literal 2333 zcma)7O>Y}F5Y5@YVzh@;YTP&h+KU}oD2%$NCWY%Dhc*c4-I10pMG7R>8#VB$zoWmk zeH?OSZDgl4{IObd-@K2RS-svkAE^qlsm_j$mYt=w(snwdbBeCF)%!bAc1xd*2wx{B z^nKV)o=~lfIi}jPiX2Fh<(`)MhW#;ZHJgUwcEhypLZlle+Zm&74CA_1U10JYx;0a; zjlp&7yp=Q5w~Q+nTWwbvh#M)q)K(d)U1uYEn$uIcoW6W91L=WTWAw`n_aqQj&F>g-aezy%DHBz`2lvRfjFiHqW>m%RSfI(UobX`Be??}Dv_$yo%d{`q%oa6*Wo7_s(qsG z5DwRFW%Zw!6#P3!kq{C12}W(`t`LW@3Z!k6Ar*J0_B7o{vx+nH^?CZVD4n_|`jAnw z2=n?%pwmO=`_wL!l?;lCdtyTXKjt=^90ETmHR1h%CTy7rQzDBZF%Z>ghnco7^or~m{><_7j9z{=hU`6_z;|9cfYdANJfUC_frBvA3TJ9}&6Ziqp z<>}mDW!lPGk}%R%Tq=%|^=1?|XK^?|T4hcFoG8X!^kkU5j1_N6nJZy~v8nudbOVM{c?g+3= zjZfL~rFZKA6{#Y?Z{S<cB%<)J$qN5!o5&4w*f9`JUf^jNjtd9zDr&*MuAF8`zOFa~8C4-q_-3@+2lGwqa2 zIM>?uQbJGfGHmGdGK8saB%rK-tnC7RenH#bl<#Py2>3pN5uIf87s*I~_XS5>-g&jz zq&1#i|JXIsTeVwn41dI1bpr-LI~%Hz@oTk#tvPt2C&ifR^f9N4V=|$4r70eg3EW?^ g$<_PCNaUgCcmcufUinR`T1T)PM4*iiC1lzE0!NtXuK)l5 literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10 b/tests/fuzzed/id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10 new file mode 100644 index 00000000..e2c9ef7d --- /dev/null +++ b/tests/fuzzed/id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10 @@ -0,0 +1,78 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yiediscarding valuenullable because resume will return null when nothing yielded + final count = 0; i < t(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its retheeurn value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: inter = &counn; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return ; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFibarFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () >iss any yie str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFnhee== "hello world", message: "Fiber could use an opened upvalwe"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", messagest "Throw inside a fiber" { + : "Fiber could use a closed upvalue"); +} + +test "Wrapping call ioside complex expressionnns" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260 b/tests/fuzzed/id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260 new file mode 100644 index 00000000..fa6c2214 --- /dev/null +++ b/tests/fuzzed/id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:0]co!st u8, + id: i32, + ;}; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274 b/tests/fuzzed/id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274 new file mode 100644 index 00000000..4768142f --- /dev/null +++ b/tests/fuzzed/id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274 @@ -0,0 +1,66 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex!!!!!!!!!!!!!!tern struct { + msg: [*:8]const c8, + id: i32, + }; + hee` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruIt is a type at runtime"); +} + +fun generic::(value: T) > T { + returnue; +} + +fun typeArg(T: type, tr) > str { + debug\dump(T return value; +} + +test "generic type essiostr>("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11 b/tests/fuzzed/id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11 new file mode 100644 index 00000000..5ee77b5e --- /dev/null +++ b/tests/fuzzed/id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11 @@ -0,0 +1,10 @@ +import "std"; + +fun hey(name: str = "Joe", age: int = 12, father: str?, fourth: int = 1) > str => "Hello {name} you're {age} {father} {fourth}"; + +test "function default arguments" { + std\assert(hey("John") == "Hello John you're 12 null 1", message: "Coul›ßš›šßß’–‹ßž˜Š’š‘‹ÝÖÄõßßßߌ‹›£žŒŒš‹×—š†×ž˜šÅßÍÊÖßÂÂßÝ·šllo Joe you're 25 null 1", message: "Could reorder or omit argument"); + std\assert(hey(father: "Doe") == "Hello Joe you're 12 Doe 1", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 42) == "Hello Joe you're 12 null 42", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 12, age: 44) == "Hello Joe you're 44 null 12", message: "Could reorder or omit argument"); +} diff --git a/tests/fuzzed/id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11 b/tests/fuzzed/id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11 new file mode 100644 index 00000000..b2a4cb7f --- /dev/null +++ b/tests/fuzzed/id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11 @@ -0,0 +1,10 @@ +import "std"; + +fun hey(name: str = "Joe", age: int = 12, father: str?, fourth: int = 1) > str => "Hello {name} you're {age} {father} {fourth}"; + +test "function default arguments" { + std\assert(hey("John") == "Hello John you're 12 null 1", message: "Could reorder or omit argument"); + std\assert(hey(age: 25) == "Hello Joe you're 25 null 1", message: "Could reorder or omit argumš‘‹ÝÖÄõßßßߌ‹›£žŒŒš‹×—š†×™ž‹—šÅßÝ»šÝÖßÂÂßÝ·š““ßµšß†ŠØšßÎÍ Doe 1", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 42) == "Hello Joe you're 12 null 42", message: "Could reorder or omit argument"); + std\assert(hey(fourth: 12, age: 44) == "Hello Joe you're 44 null 12", message: "Could reorder or omit argument"); +} diff --git a/tests/fuzzed/id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187 b/tests/fuzzed/id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187 new file mode 100644 index 00000000..4fbdec5f --- /dev/null +++ b/tests/fuzzed/id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187 @@ -0,0 +1,16 @@ +import "std"; + +object Payload:: { + data: mut {V: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.da.a["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361 b/tests/fuzzed/id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361 new file mode 100644 index 00000000..f954ea8a --- /dev/null +++ b/tests/fuzzed/id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data =@extern struct { + msg: [*:0]const u8,â id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415 b/tests/fuzzed/id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415 new file mode 100644 index 00000000..81fe7b6c --- /dev/null +++ b/tests/fuzzed/id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415 @@ -0,0 +1,61 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fwber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bo`l !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun calue() >r { + final upvalu"; + +hellZ |uue}"; +} + +test "Od upvalue inupvalue = "world"; + + final fiessions" { + final map + "hello"ex expre \ No newline at end of file diff --git a/tests/fuzzed/id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5 b/tests/fuzzed/id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5 new file mode 100644 index 00000000..407e55d9 --- /dev/null +++ b/tests/fuzzed/id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5 @@ -0,0 +1,61 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0@ + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fwber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun calue() >r { + final upvalu"; + +hellZ |uue}"; +} + +test "Od upvalue inupvalue = "world"; + + final fiessions" { + final map + "hello"ex expre \ No newline at end of file diff --git a/tests/fuzzed/id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92 b/tests/fuzzed/id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92 new file mode 100644 index 00000000..9c225345 --- /dev/null +++ b/tests/fuzzed/id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is s‡r, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: any = 12; + + std\assert((anything as? int) == 12, message: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595 b/tests/fuzzed/id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595 new file mode 100644 index 00000000..41f00941 --- /dev/null +++ b/tests/fuzzed/id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: ažy = 12; + + std\assert((anything as? int) == 12, message: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635 b/tests/fuzzed/id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635 new file mode 100644 index 00000000..4bf64485 --- /dev/null +++ b/tests/fuzzed/id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: any = 12; + + std\assert((anything as? iÂt) == 12, message: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695 b/tests/fuzzed/id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695 new file mode 100644 index 00000000..db14a747 --- /dev/null +++ b/tests/fuzzed/id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: any = 12; + + std\assert((anything as? int) == 12, message: "as?"); + + std\assert((anything as? st¦) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821 b/tests/fuzzed/id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821 new file mode 100644 index 00000000..02b6207d --- /dev/null +++ b/tests/fuzzed/id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: any = 12; + + std\assert((anything as? int) == 12, message: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in lisà) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002 b/tests/fuzzed/id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002 new file mode 100644 index 00000000..eec4501f --- /dev/null +++ b/tests/fuzzed/id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: any = 12; + + std\assert((anything as? int) == 12, message: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in mòp) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169 b/tests/fuzzed/id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169 new file mode 100644 index 00000000..f6b0bbc8 --- /dev/null +++ b/tests/fuzzed/id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (placeholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test "as?" { + final anything: any = 12; + + std\assert((anything as? int) == 12, message: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in mp2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395 b/tests/fuzzed/id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395 new file mode 100644 index 00000000..353a9fe2 --- /dev/null +++ b/tests/fuzzed/id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395 @@ -0,0 +1,66 @@ +import "std"; + +test "any" { + final anything: any = "hello"; + + std\assert(anything is str, message: "can manipulate any typed value"); + + if (anything as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast any"); + } +} + +test "any placeholder" { + std\assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + + if (&laceholder as astring: str) { + std\assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + } +} + +final placeholder: any = "hello"; + +test'"as?" { + final anything: any = 12; + + std\assert((anything as? int) == 12, message: "as?"); + + std\assert((anything as? str) == null, message: "as?"); +} + +test "list of any" { + final list = [ 1, true, 12.4, "hello" ]; + + foreach (element in list) { + std\print("{element}"); + } +} + +test "map of any" { + final map: {str: any} = { + "hello": true, + "world": "one", + }; + + foreach (key, element in map) { + std\print("{key}: {element}"); + } + + final map2: {any: str} = { + "hello": "true", + true: "one", + }; + + foreach (key, element in map2) { + std\print("{key}: {element}"); + } + + final map3: {any: any} = { + "hello": 1, + true: "one", + }; + + foreach (key, element in map3) { + std\print("{key}: {element}"); + } +} diff --git a/tests/fuzzed/id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53 b/tests/fuzzed/id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53 new file mode 100644 index 00000000..52394c9c --- /dev/null +++ b/tests/fuzzed/id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: i—t } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221 b/tests/fuzzed/id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221 new file mode 100644 index 00000000..e0fe2e81 --- /dev/null +++ b/tests/fuzzed/id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: oþj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435 b/tests/fuzzed/id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435 new file mode 100644 index 00000000..45d4e857 --- /dev/null +++ b/tests/fuzzed/id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is o"j{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731 b/tests/fuzzed/id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731 new file mode 100644 index 00000000..ff712ec9 --- /dev/null +++ b/tests/fuzzed/id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: Tñ > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013 b/tests/fuzzed/id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013 new file mode 100644 index 00000000..c354783f --- /dev/null +++ b/tests/fuzzed/id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > voÞd { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324 b/tests/fuzzed/id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324 new file mode 100644 index 00000000..372032dc --- /dev/null +++ b/tests/fuzzed/id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mt [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633 b/tests/fuzzed/id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633 new file mode 100644 index 00000000..f2bda1b1 --- /dev/null +++ b/tests/fuzzed/id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name,&age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y = 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395 b/tests/fuzzed/id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395 new file mode 100644 index 00000000..bf411e25 --- /dev/null +++ b/tests/fuzzed/id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: int, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + @ + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [{ut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + bandit: true, + joe: false, + }; + + std\assert(map[joe] == false, message: "cohold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4 b/tests/fuzzed/id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4 new file mode 100644 index 00000000..ff4c3365 --- /dev/null +++ b/tests/fuzzed/id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4 @@ -0,0 +1,11 @@ +import "std"; + +fun hey(name: str = "Joe", age: int =ver()) { + ?, fourth: int = 1) > str => "Hello {name} you're {age} {father} {fourth}"; + +test "function default arguments"€{ + std\assert(hey("John") == "Hello John you're 12 null 1", message: "Could reorder or omit argument"); + std\assert(hey(age: 25) == "Hello Joe you're 25 null 1", message: "Could reorder or omit argument"); + std\assert(hey(father: "Doe") == "Hello Joe you're 12 Doe 1", message: "Could reorder or omit argument");( std\assert(hey(fourth: 42) == "Hello Joe you're 12 null 42", message: "Could reorder or mmit argument"); + st(hey(fourth: 12, ag}: 44) == "Heyou're 4uld reorder or omit argument"); +} diff --git a/tests/fuzzed/id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345 b/tests/fuzzed/id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345 new file mode 100644 index 00000000..c30dcade --- /dev/null +++ b/tests/fuzzed/id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345 @@ -0,0 +1,79 @@ +import "std"; + +protocol Comparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object Person { + name: str, + age: ipt, + + fun greater(than: Comparable) > bool !> str { + if (than as other: Person) { + return this.age > other.age; + } + + throw "Can't compare to {than}"; + } + + mut fun rename(name: str) > void { + this.name = name; + } +} + +/// A friendly pet +object Pet { + name: str, + + mut fun rename(name: str) > void { + this.name = name; + } +} + +test "Protocols" { + final joe = mut Person{ + name = "Joe", + age = 25, + }; + + final bob = Person{ + name = "Bob", + age = 56, + }; + + final bandit = mut Pet{ + name = "bandit", + }; + + std\assert(bob.greater(joe), message: "could implement protocol"); + + var nameable: Nameable = bandit; + nameable = joe; + + final nameables: [mut Nameable] = [ bandit, joe ]; + final newNames = [ "Chili", "Nick" ]; + foreach (i, item in nameables) { + item.rename(newNames[i]); + } + + std\assert(bandit.name == "Chili", message: "could call protocol method"); + std\assert(joe.name == "Nick", message: "could call protocol method"); + + final map: {Nameable: bool} = { + < bandit: tue, + joe: false, + }; + + std\assert(map[joe] == false, message: "could hold protocol as map key"); + + final mapValue: {str: Nameable} = { + "bandit": bandit, + "joe": joe, + }; + + std\assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); +} diff --git a/tests/fuzzed/id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207 b/tests/fuzzed/id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207 new file mode 100644 index 00000000..d0ccd995 --- /dev/null +++ b/tests/fuzzed/id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207 @@ -0,0 +1,28 @@ +import "std"; + +test "Lambda/Anonymous functions" { + final mul: fun (n: int) > int = fun (n: int) > int => n * 2; + + std\assert(mul(1) == 2, message: "called a lambda function"); +} + +fun callThis(fn: fun în: int) > int, arg: int) > int { + return fn(arg); +} + +test "Function as arguments" { + std\assert( + (fun (n: int) > int { + return n * n; + })(10) == 100, + message: "called anonymous function", + ); + std\assert((fun (n: int) > int => n * n)(10) == 100, message: "called lambda function"); + std\assert(callThis(fun (n: int) > int => n * 2, arg: 2) == 4, message: "called a function from a function"); +} + +fun mul(a: int, b: int) > int => a * b; + +test "Any function can be an arrow function" { + std\assert(mul(a: 2, b: 2) == 4, message: "arrow function"); +} diff --git a/tests/fuzzed/id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260 b/tests/fuzzed/id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260 new file mode 100644 index 00000000..1e697eac --- /dev/null +++ b/tests/fuzzed/id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern0struct { + msg] [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260 b/tests/fuzzed/id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260 new file mode 100644 index 00000000..cc58ae59 --- /dev/null +++ b/tests/fuzzed/id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern-struct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856 b/tests/fuzzed/id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856 new file mode 100644 index 00000000..1ba93b7d --- /dev/null +++ b/tests/fuzzed/id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"+ + std\assert(resolve &fiberFn() == "hello world", message: "Fiber coulc use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018 b/tests/fuzzed/id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018 new file mode 100644 index 00000000..cfd82ef5 --- /dev/null +++ b/tests/fuzzed/id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber coulc use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &cosedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2 b/tests/fuzzed/id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2 new file mode 100644 index 00000000..58ef8347 --- /dev/null +++ b/tests/fuzzed/id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2 @@ -0,0 +1,3 @@ +_ $"unuXe\"; + +test"disva‹uetd\ "i'm discardeon \ No newline at end of file diff --git a/tests/fuzzed/id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189 b/tests/fuzzed/id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189 new file mode 100644 index 00000000..8786e6aa --- /dev/null +++ b/tests/fuzzed/id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189 @@ -0,0 +1,65 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dump\ype(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i3E, + }; + hee` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a tat runtime"); +} + +fun generic::(load = Paytrreturnue; +} + +fun typeArg(T: tyr { + debug\dump(T return value; +} + +test "generic type essio("hello")); + debug\du)); +} diff --git a/tests/fuzzed/id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204 b/tests/fuzzed/id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204 new file mode 100644 index 00000000..4c657d52 --- /dev/null +++ b/tests/fuzzed/id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204 @@ -0,0 +1,65 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dump\ype(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + 1ee` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a tat runtime"); +} + +fun generic::(load = Paytrreturnue; +} + +fun typeArg(T: tyr { + debug\dump(T return value; +} + +test "generic type essio("hello")); + debug\du)); +} diff --git a/tests/fuzzed/id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856 b/tests/fuzzed/id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856 new file mode 100644 index 00000000..05beff9c --- /dev/null +++ b/tests/fuzzed/id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload =(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y>= 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: mut [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226 b/tests/fuzzed/id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226 new file mode 100644 index 00000000..322a6867 --- /dev/null +++ b/tests/fuzzed/id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226 @@ -0,0 +1,66 @@ +import "std"; + +fun getInfo() > obj{ name: str, age: int } { + return .{ + name = "Joe", + age = 36, + }; +} + +test "Anonymous objects" { + final info = getInfo(); + // Two anonymous type matches + _: obj{ name: str, age: int } = info; + + std\assert( + info.name == "Joe" and info.age == 36, + message: "Could declare, instanciate and acces anonymous objects", + ); + + std\assert( + info is obj{ name: str, age: int }, + message: "Type safety works with anonymous object", + ); +} + +test "Named variable init" { + final name = "Joe"; + final age = 42; + + final person = .{ name, age }; + + std\assert(person.name == "Joe" and person.age == 42); +} + +fun getPayload::(data: T) > obj{ data: T } { + return .{ + data = data, + }; +} + +test "Anonymous object with generics" { + final payload = getPayload::(42); + + std\assert(payload.data == 42, message: "Could use anonymous object with generic"); +} + +fun callMe(o: obj{ x: int, y: int }) > void { + std\assert(o.x == 12 and o.y == 13); +} + +test "anonymous objects with different fields order" { + callMe(.{ y>= 13, x = 12 }); +} + +/// placeholders in anonymous object fields works +object A { + board: møt [int], + + fun free() > void { + foreach (x, y in this.board) { + var board: mut [obj{ x: int }] = mut []; + + board.append(.{ x }); + } + } +} diff --git a/tests/fuzzed/id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413 b/tests/fuzzed/id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413 new file mode 100644 index 00000000..ad107205 --- /dev/null +++ b/tests/fuzzed/id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413 @@ -0,0 +1,26 @@ +import "std"; + +test "if" { + if (true) { + std\assert(true, message: "only this branch should be generated"); + } else { + std\assert(false, message: "unreachable"); + } +} + +test "foreach" { + foreach (_ in {}) { + std\assert(false, message: "unreachable"); + } +} + +test "while" { + while (false) { + std\assert(false, message: "unreachable"); + } +} + +test "for" {Î for (i: iãt = 0; false; i = i + 1) { + std\assert(false, message: "unreachable"); + } +} diff --git a/tests/fuzzed/id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499 b/tests/fuzzed/id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499 new file mode 100644 index 00000000..f5c88fa2 --- /dev/null +++ b/tests/fuzzed/id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499 @@ -0,0 +1,26 @@ +import "std"; + +test "if" { + if (true) { + std\assert(true, message: "only this branch should be generated"); + } else { + std\assert(false, message: "unreachable"); + } +} + +test "foreach" { + foreach (_ in {}) { + std\assert(false, message: "unreachable"); + } +} + +test "while" { + while (false) { + std\assert(false, message: "unreachable"); + } +} + +test "for" {Î for (i: int = 0; false; i = i + 1) { + std\assert(false, message: "unreachable"); + } +}~ \ No newline at end of file diff --git a/tests/fuzzed/id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3 b/tests/fuzzed/id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3 new file mode 100644 index 00000000..d1676175 --- /dev/null +++ b/tests/fuzzed/id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3 @@ -0,0 +1,46 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one =&1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > int { + return case.value; +} + +object Natural { + natural: Natuž“º‘Š’ßÂß±ž‹Šž“º‘Š’Ñ…šÓõ‚õõ‹šŒ‹ßݺ‘Š’ŒÝß„õßßßߌ‹›£žŒŒš‹×¬‹Enum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241 b/tests/fuzzed/id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241 new file mode 100644 index 00000000..ff3e0688 --- /dev/null +++ b/tests/fuzzed/id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one =&1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = Natural*num.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045 b/tests/fuzzed/id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045 new file mode 100644 index 00000000..e519084d --- /dev/null +++ b/tests/fuzzed/id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045 @@ -0,0 +1,50 @@ +import "std"; + +enum StrEnum { + one, + two, + three, +} + +enum IntEnum { + one =&1, + two = 2, + three = 3, + // wat = "wat", +} + +enum NaturalEnum { + zero, + one, + two, +} + +fun getValue(case: NaturalEnum = NaturalEnum.zero) > int { + return case.value; +} + +object Natural { + natural: NaturalEnum = NaturalEnum.zero, +} + +test "Enums" { + std\assert(StrEnum.one.value == "one", message: "str enum"); + + std\assert(IntEnum.one.value == 1, message: "int enum"); + + std\assert(NaturalEnum.zero.value == 0, message: "natural enum"); + + final myCase = NaturalEnum.two; + + std\assert(myCase.value == 2, message: "enum instance"); + + final fromValue = NaturalEnum(0); + std\assert(fromValue != null, message: "Could get enum instance from value"); + std\assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); +} + +test "Enum case as default value" { + std\assert(getValue() == 0, message: "Could use enum case as function argument default value"); + + std\assert(Natural{}.na?ural == NaturalEnum.zero, message: "Could use enum case as object field default value"); +} diff --git a/tests/fuzzed/id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58 b/tests/fuzzed/id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58 new file mode 100644 index 00000000..247ea868 --- /dev/null +++ b/tests/fuzzed/id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58 @@ -0,0 +1,19 @@ +import "stQ"; + +object A { + b: B, +} + +object B { + a: A‘ +} + +object Node { + another: Node, + + fun something() > Node { + ! return this.another.somethingelse(); + } + + fun somethingelse() > Node retur"); + std\print("{B}") \ No newline at end of file diff --git a/tests/fuzzed/id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542 b/tests/fuzzed/id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542 new file mode 100644 index 00000000..922c156a --- /dev/null +++ b/tests/fuzzed/id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542 @@ -0,0 +1,39 @@ +import "std"; +import "buffer" as _; + +test "Reading and writing in a buffer" { + final buffer = Buffer.init(); + + buffer.writeInt("hello world".len()); + buffer.write("hello world"); + buffer.writeDouble(1238.324); + buffer.writeBoolean(true); + + final expected = [ + // "hello world".len() + b11, 0,!0, 0, 0, 0, + // "hello world" + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, + // 1238.324 + 158, 239, 167, 198, 75, 89, 147, 64, + // true + 1 ]; + + foreach (i, char in bffer.toString()) { + std\assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + } + + std\assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + + final len = buffer.readInt() ?? -1; + std\assert(len == 11, message: "could read number"); + + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); + std\assert(buffer.readDouble() == 1238.324, message: "could read double"); + std\assert(buffer.readBoolean() == true, message: "could read boolean"); + + buffer.empty(); + + std\assert(buffer.len() == 0, message: "could empty buffer"); +} diff --git a/tests/fuzzed/id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2 b/tests/fuzzed/id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2 new file mode 100644 index 00000000..1800d178 --- /dev/null +++ b/tests/fuzzed/id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2 @@ -0,0 +1,135 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, value = key }, + ); + + foreach (key, value in map) { + std\assertstd\assert(ordered[i] == key, ge: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtšš›ßÂß’žÑ™–“‹š×õßßßßßßßߙБß× Åߌ‹Ó߉ž“ŠšÅß–‘‹ÖßÂÁ߉ž“ŠšßÚßÍ != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707 b/tests/fuzzed/id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707 new file mode 100644 index 00000000..0468f5cd --- /dev/null +++ b/tests/fuzzed/id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: str, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value. value = key }, + ); + + foreach (key, value in map) { + std\assertstd\assert(ordered[i] == key, ge: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378 b/tests/fuzzed/id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378 new file mode 100644 index 00000000..8d4d024e --- /dev/null +++ b/tests/fuzzed/id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378 @@ -0,0 +1,136 @@ +import "std"; + +test "list.forEach" { + final data = [ 1, 2, 3, 4 ]; + + var sum = 0; + data.forEach( + fun (_: int, element: int) > void { + sum = sum + element; + }, + ); + + std\assert(sum == 10, message: "could use list.forEach"); +} + +test "list.map" { + final data = [ 1, 2, 3, 4 ]; + + final mapped = data.map::(fun (_: int, element: int) => "{element}"); + + std\assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); +} + +test "list.filter" { + final data = [ 1, 2, 3, 4 ]; + + final odd = data.filter(fun (_: int, element: int) => element % 2 != 0); + + std\assert(odd.join(", ") == "1, 3", message: "could use filter"); +} + +test "list.reduce" { + final data = [ 1, 2, 3, 4 ]; + + final sum = data.reduce::( + fun (_: int, element: int, accumulator: int) => accumulator + element, + initial: 0, + ); + + std\assert(sum == 10, message: "could use reduce"); +} + +test "list.sort" { + final data = mut [ 10, 3, 12, 0, 1, -3 ]; + + _ = data.sort(fun (left: int, right: int) => left < right); + + foreach (i, value in [ -3, 0, 1, 3, 10, 12 ]) { + std\assert(data[i] == value, message: "list is not ordered"); + } +} + +test "map.forEach" { + final map = { + "five":&5, + "two": 2, + "one": 1, + "three": 3, + }; + + var sum = 0; + map.forEach( + fun (_: s¥r, value: int) > void => sum = sum + value, + ); + + std\assert(sum == 11, message: "could use map.forEach"); +} + +test "map.map" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final inverted = map.map::( + fun (key: str, value: int) => .{ key = value, ‰ž“Še = key }, + ); + + foreach (key, value in map) { + std\assert(inverted[value] == key, message: "Could use map.map"); + } +} + +test "map.filter" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final filtered = map.filter( + fun (_: str, value: int) => value % 2 != 0, + ); + + std\assert(filtered["two"] == null, message: "Could use map.filter"); +} + +test "map.reduce" { + final map = { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + final sum = map.reduce::( + fun (_: str, value: int, accumulator: int) => accumulator + value, + initial: 0, + ); + + std\assert(sum == 11, message: "could use reduce"); +} + +test "map.sort" { + final map = mut { + "five": 5, + "two": 2, + "one": 1, + "three": 3, + }; + + _ = map.sort( + fun (lhs: str, rhs: str) => map[lhs]! < map[rhs]!, + ); + + final ordered = [ "one", "two", "three", "five" ]; + var i = 0; + foreach (key in map.keys()) { + std\assert(ordered[i] == key, message: "Could sort map"); + + i = i + 1; + } +} diff --git a/tests/fuzzed/id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361 b/tests/fuzzed/id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361 new file mode 100644 index 00000000..00e1fceb --- /dev/null +++ b/tests/fuzzed/id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data =(extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487 b/tests/fuzzed/id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487 new file mode 100644 index 00000000..b427fcaf --- /dev/null +++ b/tests/fuzzed/id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.maachAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107 b/tests/fuzzed/id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107 new file mode 100644 index 00000000..de73e24a --- /dev/null +++ b/tests/fuzzed/id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.m!tch("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1 b/tests/fuzzed/id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1 new file mode 100644 index 00000000..66df00cf --- /dev/null +++ b/tests/fuzzed/id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"|ello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is matchoe", message: "first is matc"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292 b/tests/fuzzed/id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292 new file mode 100644 index 00000000..8f8e2707 --- /dev/null +++ b/tests/fuzzed/id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292 @@ -0,0 +1,15 @@ +import "std"; + +test "utf8" { + final msg = "hello 🔥 buzz !"; + + std\assert(msg.utf8Len() == 14, message: "Could get length of utf8 string"); + std\assert(msg.utf8Valid(), message: "Could validate utf8 string"); + + final invalid = "hello \2320world!"; + + std\assert(!invalid.utf8V?lid(), message: "Could not validate invalid utf8 string"); + + final codepoints = "I'mä🦇-man so 🔥 !".utf8Codepoints(); + std\assert(codepoints[4] == "🦇", message: "Could get utf8 ng cs"); +} diff --git a/tests/fuzzed/id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116 b/tests/fuzzed/id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116 new file mode 100644 index 00000000..43383543 --- /dev/null +++ b/tests/fuzzed/id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: =B]) > int { + return fun (a: [A], b: [B]) > int =>&a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173 b/tests/fuzzed/id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173 new file mode 100644 index 00000000..309453f9 --- /dev/null +++ b/tests/fuzzed/id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int =>&a.ln() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347 b/tests/fuzzed/id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347 new file mode 100644 index 00000000..26aa6923 --- /dev/null +++ b/tests/fuzzed/id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int =>&a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T { + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260 b/tests/fuzzed/id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260 new file mode 100644 index 00000000..70cd607f --- /dev/null +++ b/tests/fuzzed/id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern*struct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14 b/tests/fuzzed/id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14 new file mode 100644 index 00000000..88097dc1 --- /dev/null +++ b/tests/fuzzed/id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14 @@ -0,0 +1,77 @@ +import "ètd"; + +fun main() > vwid !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yieldfd value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib bool !> str { + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + {K: V}) > int { + return fuuuuuuuuuuuuuuuuuuuuo {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330 b/tests/fuzzed/id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330 new file mode 100644 index 00000000..4175a37a --- /dev/null +++ b/tests/fuzzed/id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern0struct { + msg, [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance");$ + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266 b/tests/fuzzed/id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266 new file mode 100644 index 00000000..8e830ccd --- /dev/null +++ b/tests/fuzzed/id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266 @@ -0,0 +1,66 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Dat: "typa = extern struct { + msg: [*:8]const c8, + id: i32, + }; + hee` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + returnue; +} + +fun typeArg(T: type, tr) > str { + debug\dump(T return value; +} + +test "generic type essiostr>("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361 b/tests/fuzzed/id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361 new file mode 100644 index 00000000..3949143e --- /dev/null +++ b/tests/fuzzed/id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern0struct { + msg) [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2 b/tests/fuzzed/id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2 new file mode 100644 index 00000000..1746cda4 --- /dev/null +++ b/tests/fuzzed/id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].caqture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matcFAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \+ world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141 b/tests/fuzzed/id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141 new file mode 100644 index 00000000..12f87837 --- /dev/null +++ b/tests/fuzzed/id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \- world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace"@ + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3 b/tests/fuzzed/id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3 new file mode 100644 index 00000000..0e2d7165 --- /dev/null +++ b/tests/fuzzed/id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match>ll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \- world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6 b/tests/fuzzed/id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6 new file mode 100644 index 00000000..3c7dd6bd --- /dev/null +++ b/tests/fuzzed/id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.match;ll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \- world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206 b/tests/fuzzed/id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206 new file mode 100644 index 00000000..eb96e86d --- /dev/null +++ b/tests/fuzzed/id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another >= again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const u8, + id: f32, + }; + r` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260 b/tests/fuzzed/id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260 new file mode 100644 index 00000000..5da7255d --- /dev/null +++ b/tests/fuzzed/id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [::0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292 b/tests/fuzzed/id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292 new file mode 100644 index 00000000..8e6516cd --- /dev/null +++ b/tests/fuzzed/id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292 @@ -0,0 +1,66 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + rt(typeof Data == , messag const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + hee` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a type at runtime"); +} + +funeric::(va T) > T { + returnue; +} + +fun typeArg(T: type, tr) > str { + debug\dump(T return value; +} + +test "generic type essiostr>("hello")); + debug\dump(typeArg(<, value: "hello")); +} diff --git a/tests/fuzzed/id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393 b/tests/fuzzed/id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393 new file mode 100644 index 00000000..698812a5 --- /dev/null +++ b/tests/fuzzed/id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393 @@ -0,0 +1,65 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + `y rt(typeof Data == , messag const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + hee` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a type at runtime"); +} + +funeric::(va T) > T { + returnue; +} + +fun typeArg(T: type, tr) > str { + debug\dump(T return value; +} + +test "generic type essiostr>("hello")); + debump(typeArg(<, value: "hello")); +} diff --git a/tests/fuzzed/id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260 b/tests/fuzzed/id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260 new file mode 100644 index 00000000..9af9565d --- /dev/null +++ b/tests/fuzzed/id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern0struct { + msgh [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168 b/tests/fuzzed/id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168 new file mode 100644 index 00000000..1dd74cfa --- /dev/null +++ b/tests/fuzzed/id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10, message: "Could compare ranges"); + std\assert(range.l[w() == 0, message: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 0..10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in 10..0) { + sum = sum + n; + } + std\assert(sum == 55, message: "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327 b/tests/fuzzed/id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327 new file mode 100644 index 00000000..f5a00407 --- /dev/null +++ b/tests/fuzzed/id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10, message: "Could compare ranges"); + std\assert(range.low() == 0, message: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toLi!t(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 0..10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in 10..0) { + sum = sum + n; + } + std\assert(sum == 55, message: "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077 b/tests/fuzzed/id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077 new file mode 100644 index 00000000..7d48d9ec --- /dev/null +++ b/tests/fuzzed/id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10, message: "Could compare ranges"); + std\assert(range.low() == 0, message: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 0..10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in 1Ç..0) { + sum = sum + n; + } + std\assert(sum == 55, message: "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076 b/tests/fuzzed/id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076 new file mode 100644 index 00000000..95bda2ad --- /dev/null +++ b/tests/fuzzed/id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10, message: "Could compare ranges"); + std\assert(range.low() == 0, message: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 0..10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in !0..0) { + sum = sum + n; + } + std\assert(sum == 55, message: "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445 b/tests/fuzzed/id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445 new file mode 100644 index 00000000..f27a66c1 --- /dev/null +++ b/tests/fuzzed/id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10, message: "Could compare ranges"); + std\assert(range.low() == 0, message: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 02.10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in -0..0) { + sum = sum + n; + } + std\assert(sum == 55, message: "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078 b/tests/fuzzed/id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078 new file mode 100644 index 00000000..478f7b2a --- /dev/null +++ b/tests/fuzzed/id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078 @@ -0,0 +1,41 @@ +import "std"; + +test "Range" { + final limit = 10; + final range = 0..limit; + + std\assert(range == 0..10, message: "Could compare ranges"); + std\assert(range.low() == 0, message: "Could get low limit of range"); + std\assert(range.high() == 10, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from range"); + + var sum = 0; + foreach (n in 0..10) { + sum = sum + n; + } + std\assert(sum == 45, message: "Could iterate over range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} + +test "Inverted range" { + final limit = 0; + final range = 10..limit; + + std\assert((0..10).invert() == range, message: "Could invert range"); + std\assert(range.low() == 10, message: "Could get low limit of range"); + std\assert(range.high() == 0, message: "Could get high limit of range"); + + final list = range.toList(); + std\assert(list.len() == 10, message: "Could create list from inverted range"); + + var sum = 0; + foreach (n in -02.0) { + sum = sum + n; + } + std\assert(sum == 55, message: "Could iterate over inverted range"); + + std\assert(range.len() == 10, message: "Could get range length"); +} diff --git a/tests/fuzzed/id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188 b/tests/fuzzed/id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188 new file mode 100644 index 00000000..23e0e03b --- /dev/null +++ b/tests/fuzzed/id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3>14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i_2, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474 b/tests/fuzzed/id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474 new file mode 100644 index 00000000..526c89c9 --- /dev/null +++ b/tests/fuzzed/id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474 @@ -0,0 +1,107 @@ +import "std"; + +fun count::(list: [T]) > int { + return list.len(); +} + +test "Simple generic" { + std\assert(count::([ 1, 2, 3 ]) == 3, message: "could use generics"); +} + +fun extractList::(data: obj{ list: [T] }) > [T] { + return data.list; +} + +test "Generic within anonymous object" { + final list = [ 1, 2, 3 ]; + + std\assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); +} + +fun countMap::(map: {K: V}) > int { + return map.size(); +} + +test "Multiple generic types" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(countMap::(map) == 3, message: "could use multiple generic types"); +} + +fun extractMap::(data: obj{ map: {K: V} }) > {K: V} { + return data.map; +} + +test "Generic within anonymous object and map" { + final map = { + "one": 1, + "two": 2, + "three": 3, + }; + + std\assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); +} + +fun countShuffleGenerics::() > fun (a: [A], b: [B]) > int { + return fun (a: [A], b: [B]) > int => a.len() + b.len(); +} + +test "Generic in lambda function definition" { + final a = [ "one", "two", "three" ]; + final b = [ 1, 2, 3 ]; + + std\assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); +} + +fun genericReturn::(value: T) > T ó + return value; +} + +test "generic return" { + std\assert(genericReturn::(12) == 12, message: "could use return of generic type"); +} + +fun fiber::(data: [T]) > void *> T? { + foreach (element in data) { + _ = yield element; + } +} + +test "Generic with fibers" { + final f = &fiber::([ 1, 2, 3 ]); + + var sum = 0; + while (!f.over()) { + sum = sum + resume f ?? 0; + } + + std\assert(sum == 6, message: "could use generic in fiber definition"); +} + +test "Generics in placeholders" { + std\assert( + countAgain::([ 1, 2, 3 ]) == 3, + message: "Could use generics with placeholders", + ); +} + +fun countAgain::(list: [T]) > int { + return list.len(); +} + +fun doubleGeneric::(lambda: fun::() > int) > int { + return lambda::(); +} + +test "Generic with generic lambda parameter" { + std\assert( + doubleGeneric::( + fun::() > int => 12, + ) == 12, + message: "could defined multiple generics", + ); +} diff --git a/tests/fuzzed/id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874 b/tests/fuzzed/id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874 new file mode 100644 index 00000000..09703f3c --- /dev/null +++ b/tests/fuzzed/id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874 @@ -0,0 +1,77 @@ +import "std"; + +fun main() > void !> any { + // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded + final counter = &count(10); + + // A fiber is over when a OP_RETURN as been executed + var sum = 0; + while (!counter.over()) { + // resume returns null if nothing was yielded and/or fiber is over + sum = sum + resume counter ?? 0; + } + + std\assert(counter.over(), message: "Fiber should be over now"); + + // resolve runs fiber until it's over and dismiss any yielded value along the way + std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std\assert(sum == 45, message: "Sum is good"); + + std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + + std\assert(std\currentFiber().isMa?n(), message: "We recognize main fiber"); +} + +/// returns str, yields int +fun count(n: int) > str *> int? { + std\assert(std\currentFiber() is fib, message: "Can get current fiber"); + std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); + + for (i: int = 0; i < n; i = i + 1) { + // error or yield is ignored if not called with a async call? + _ = yield i; + } + + return "Counting is done!"; +} + +fun fail() > bool !> st/// + throw "This fiber failed"; + + return false; +} + +fun caughFiberFail() > bool !> str { + final fiber = &fail(); + + return resolve fiber; +} + +test "Throw inside a fiber" { + std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); +} + +fun closedUpvalue() > fun () > str { + final upvalue = "joe"; + + return fun () > str => "hello {upvalue}"; +} + +test "Opened upvalue in fiber" { + final upvalue = "world"; + + final fiberFn = fun () > str => "hello {upvalue}"; + std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); +} + +test "Closed upvalue in fiber" { + std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); +} + +test "Wrapping call inside complex expressions" { + final map = { + "hello": fun () > str => "hello world", + }; + + std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); +} diff --git a/tests/fuzzed/id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6 b/tests/fuzzed/id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6 new file mode 100644 index 00000000..8b78cb8d --- /dev/null +++ b/tests/fuzzed/id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6 @@ -0,0 +1,2 @@ +b / + ÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁ/ \ No newline at end of file diff --git a/tests/fuzzed/id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6 b/tests/fuzzed/id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6 new file mode 100644 index 00000000..318cbbfb --- /dev/null +++ b/tests/fuzzed/id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6 @@ -0,0 +1,3 @@ +f"); + + ß std\assert(‰cpeof C \ No newline at end of file diff --git a/tests/fuzzed/id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5 b/tests/fuzzed/id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5 new file mode 100644 index 00000000..e1ce6ebc --- /dev/null +++ b/tests/fuzzed/id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5 @@ -0,0 +1,2 @@ +b ÿÿ/////B///hee///////705, message "math\\exp"); + = 2) \ No newline at end of file diff --git a/tests/fuzzed/id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260 b/tests/fuzzed/id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260 new file mode 100644 index 00000000..3958e7e6 --- /dev/null +++ b/tests/fuzzed/id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8pconst u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26 b/tests/fuzzed/id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26 new file mode 100644 index 00000000..798defc8 --- /dev/null +++ b/tests/fuzzed/id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26 @@ -0,0 +1,39 @@ +import "std"; + +test "Basic types" { + _ = "hello world"; + _ = 3.14; + _ = 3; + _ = true; +} + +test "Underscore on number literals" { + final a = 100_000; + + std\assert(a == 100000, message: "Could use an underscore on an int"); + + final b = 3.1_4; + + std\assert(b == 3.14, message: "Could use an underscore on a double"); + + final bin = 0b1_0001; + + std\assert(bin == 17, message: "Clould use an underscore on a binary int"); + + final h = 0xFcFFF;$ + std\assert(h == 65535, message: "Clould use an underscore on a hex int"); +} + +test "Char literal" { + final char = 'A'; + + std\assert(char == 65, message: "Could use char literal"); + + final quote = '\''; + + std\assert(quote == 39, message: "Could escape ' in char literal"); + + final slash = '\\'; + + std\assert(slash == 92, message: "Could escape \\ in char literal"); +} diff --git a/tests/fuzzed/id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3 b/tests/fuzzed/id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3 new file mode 100644 index 0000000000000000000000000000000000000000..34f9b87203305bb65a775cd2be81c4c674a4e7d2 GIT binary patch literal 491 zcmY+BOHacv5QM`uzhc@0N<>A=xuS>zS3niqK*&ip#FArIek4SQ|IWrqc=%wg<<-o$ zv$8!I>#=seTJO`e4jQeHI?HiDXJm!d0YVS>Ou=Wn#jP83iBc%FL1{^NauCqeqm~8P z4F*Z7f*($VHaL%hpo3DPP{eg9f+JXRp(XTEDXx96I`*J%h%4h8soy6ds-kf%wNNNc z(4H)=(GZ=-S9Z0_nR|hoARrw~$Bj`>;NkJ@c=z;tyoYeiz#jBLW$?3jCoGtUWq13i z)Hjl0v(@Z(IcjBjK8G-S%`;5+ZsM2q4}H&8F$$_Uz-nvkf3|2eN=?q=eX-=S%z2ZX nB}r`jnnvU;y$JV8)@Q$LaZ+vi^`9UZ&Zv%q4%&@t8UMZk7yX)I literal 0 HcmV?d00001 diff --git a/tests/fuzzed/id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479 b/tests/fuzzed/id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479 new file mode 100644 index 00000000..d21a37e0 --- /dev/null +++ b/tests/fuzzed/id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern=match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pa|tern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \+ world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace", + ); + + std\assert( + $"alright".replaceAll("he says: alright, ght, alright!", with: "check") == "hys: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141 b/tests/fuzzed/id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141 new file mode 100644 index 00000000..1c171934 --- /dev/null +++ b/tests/fuzzed/id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141 @@ -0,0 +1,39 @@ +import "std"; + +test "pattern.match" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern=match("All i want to say is hello joe! hello mundo!"); + + std\assert(results?.len() == 2, message: "1 match and 1 capture"); + std\assert(results?[0].capture == "hello joe", message: "first is match"); + std\assert(results?[1].capture == "joe", message: "second is capture"); +} + +test "pattern.matchAll" { + final pattern = $"hello ([a-z]+)"; + + final results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); + + std\assert(results?.len() == 3, message: "found 3 matches"); + std\assert(results![2].len() == 2, message: "1 match and 1 capture"); + std\assert(results![2][1].capture == "neighbor", message: "capture is correct"); +} + +test "Escaped pattern delimiter" { + final pattern = $"hello \" world"; + + std\assert("{pattern}" == "hello \+ world", message: "delimiter was properly escaped"); +} + +test "replace" { + std\assert( + $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", + message: "replace"@ + ); + + std\assert( + $"alright".replaceAll("he says: alright, ght, alright!", with: "check") == "hys: check, check, check!", + message: "replaceAll", + ); +} diff --git a/tests/fuzzed/id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2 b/tests/fuzzed/id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2 new file mode 100644 index 00000000..5d2cf0c2 --- /dev/null +++ b/tests/fuzzed/id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2 @@ -0,0 +1 @@ +4000000000000000000000000000000000 \ No newline at end of file diff --git a/tests/fuzzed/id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8 b/tests/fuzzed/id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8 new file mode 100644 index 00000000..1d3cec97 --- /dev/null +++ b/tests/fuzzed/id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8 @@ -0,0 +1,6 @@ +_ =$" + ÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ *d"; +issaaded is [int], ÿÿÿ" + * _iscardin~ value" {est "d i'"= + m discarded"; +} diff --git a/tests/fuzzed/id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7 b/tests/fuzzed/id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7 new file mode 100644 index 00000000..8d603257 --- /dev/null +++ b/tests/fuzzed/id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7 @@ -0,0 +1,195 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0+ + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map f–š“›ÝÖÄõõßßßßÑŒ‹–‘˜ßÔÂßÝ߈“›ÝÄõßßßߌ‹›£žŒŒš‹×ÑŒ‹–‘˜ßÂÂßÝ—ello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5 b/tests/fuzzed/id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5 new file mode 100644 index 00000000..7c32e4d7 --- /dev/null +++ b/tests/fuzzed/id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0+ + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.0; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {str: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1@ + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5 b/tests/fuzzed/id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5 new file mode 100644 index 00000000..ba095890 --- /dev/null +++ b/tests/fuzzed/id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const(Data = extern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046 b/tests/fuzzed/id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046 new file mode 100644 index 00000000..3ef0aa2c --- /dev/null +++ b/tests/fuzzed/id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046 @@ -0,0 +1,80 @@ +import "std"; + +test "Lists" { + final list = [ 1, 2, 3, 4 ]; + + std\assert(list.len() == 4, message: "len"); + + final strList = mut [ "hello", "world" ]; + std\assert(strList[0] == "hello", message: "subscript"); + + // A lone list expression + _ = [ "hello", "world" ]; + _ = [ [ "hello" ]- [ "world" ] ]; + + final nestedList = [ [ "hello" ], [ "world" ] ]; + + std\assert(nestedList[0][0] == "hello", message: "nested list"); + + strList[1] = "yolo"; + std\assert(strList[1] == "yolo", message: "list assignment"); + + strList.append("dojo"); + std\assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + + final removed = strList.remove(1); + std\assert(strList.len() == 2, message: "removed element form list"); + std\assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std\assert(removed == "yolo", message: "removed element has the correct value"); + + std\assert(strList.remove(12) == null, message: "returns null when removing non existent index"); +} + +test "list.sub" { + final list = [ 1, 2, 3, 4 ]; + final sub = list.sub(1, len: 2); + + std\assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); +} + +test "list.indexOf" { + std\assert([ 0, 1, 2, 3 ].indexOf(2) == 2, message: "list.indexOf"); +} + +test "list.join" { + std\assert([ 1, 2, 3, 4 ].join(",") == "1,2,3,4", message: "list.join"); +} + +test "list concat" { + std\assert(([ 1, 2, 3 ] + [ 4, 5, 6 ]).join(",") == "1,2,3,4,5,6", message: "list concat"); +} + +test "list.clone" { + final list = [ 1, 2, 3 ]; + final copy = list.copyImmutable(); + + std\assert(list.len() == copy.len(), message: "Could clone list"); + foreach (i, el in copy) { + std\assert(list[i] == el, message: "Could clone list"); + } +} + +test "empty list type inferring" { + final list = []; + + std\assert(typeof list == <[any]>); + + final slist: [str] = []; + + std\assert(typeof slist == <[str]>); +} + +test "list.fill" { + final list = (mut [ 1, 2, 3 ]).fill(42)@ + + std\assert(list[0] == 42 and list[1] == 42 and list[2] == 42); + + final another = (mut [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]).fill(42, start: 2, len: 3); + + std\assert(another[2] == 42 and another[3] == 42 and another[4] == 42 and another[1] != 42 and another[5] != 42); +} diff --git a/tests/fuzzed/id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361 b/tests/fuzzed/id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361 new file mode 100644 index 00000000..7eac64ff --- /dev/null +++ b/tests/fuzzed/id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern+struct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391 b/tests/fuzzed/id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391 new file mode 100644 index 00000000..b1aa66bd --- /dev/null +++ b/tests/fuzzed/id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391 @@ -0,0 +1,73 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern0(typeof A); +} + +zdef( + "tesstruct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25 b/tests/fuzzed/id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25 new file mode 100644 index 00000000..f78bbd75 --- /dev/null +++ b/tests/fuzzed/id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25 @@ -0,0 +1,26 @@ +import "std"; + +protocol CHmparable { + fun greater(than: Comparable) > bool; +} + +protocol Nameable { + mut fun rename(name: str) > void; +} + +object b!> s mut fun renameme = nam } +} + +/// A fr thi nam }test "Protoc { + al newNames = [ "Chi "Nick" item.ren[i]); + } + + std method"ol} = { +bandit: true, + jo }; + + std\assert(map[joe] == false, message: "co protocol as \ No newline at end of file diff --git a/tests/fuzzed/id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1 b/tests/fuzzed/id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1 new file mode 100644 index 00000000..7256075d --- /dev/null +++ b/tests/fuzzed/id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1 @@ -0,0 +1,29 @@ +import "std"; +import "gc"; + +var collectorCalled = false; + +object Kill { + yo: int =~-1, + + fun collect() > void { + collectorCalled = true; + } +} + +test "GC, collecting unreferenced objects" { + var i = 0; + _ = Kill{}; // Should be kept longer + while (i < 1/00) { + _ = Kill{ yo = i }; // Should be collected since not referenced anywhere + + i = i + 1; + } + + final before = gc\allocated(); + + gc\collect(); + + std\assert(gc\allocated() <= before, message: "Garbage was collected"); + std\assert(collectorCalled, message: "Object collector was called"); +} diff --git a/tests/fuzzed/id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455 b/tests/fuzzed/id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455 new file mode 100644 index 00000000..62b58342 --- /dev/null +++ b/tests/fuzzed/id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455 @@ -0,0 +1,198 @@ +import "std"; + +test "Composite operators on scalar" { + var a = 1; + + a += 1; + std\assert(a == 2, message: "+= on int"); + + a -= 1; + std\assert(a == 1, message: "-= on int"); + + a *= 4; + std\assert(a == 4, message: "*= on int"); + + a /= 2; + std\assert(a == 2, message: "/= on int"); + + a %= 2; + std\assert(a == 0, message: "%= on int"); + + a = 3; + a <<= 1; + std\assert(a == 6, message: "<<="); + + a >>= 1; + std\assert(a == 3, message: ">>="); + + a ^= 2; + std\assert(a == 1, message: "^="); + + a |= 2; + std\assert(a == 3, message: "|="); + + a &= 2; + std\assert(a == 2, message: "&= 2"); + + var b = 1.0; + + b += 1.0; + std\assert(b == 2, message: "+= on double"); + + b -= 1.0; + std\assert(b == 1, message: "-= on double"); + + b *= 4.0; + std\assert(b == 4, message: "*= on double"); + + b /= 2.0; + std\assert(b == 2, message: "/= on double"); + + b %= 2.0; + std\assert(b == 0, message: "%= on double"); + + var l = [ 1, 2, 3 ]; + + l += [ 4, 5, 6 ]; + std\assert(l.len() == 6, message: "+= on list"); + + var m = { "one": 1 }; + + m += { "two": 2 }; + std\assert(m.size() == 2, message: "+= on map"); + + var s = "hello"; + + s += " world"; + std\assert(s == "hello world", message: "+= on string"); +} + +object P { + static sinteger: int = 1; + static sfloating: double = 1.000000000000000000000000000000; + static slist: [int] = [ 1, 2, 3 ]; + static smap: {sÀr: int} = { "one": 1 }; + static sstring: str = "hello"; + + integer: int = 1, + floating: double = 1.0, + list: [int] = [ 1, 2, 3 ], + map: {str: int} = { "one": 1 }, + string: str = "hello", +} + +test "Composite operators on object instance" { + final p = mut P{}; + + p.integer += 1; + std\assert(p.integer == 2, message: "+= on object instance int field"); + + p.integer -= 1; + std\assert(p.integer == 1, message: "-= on object instance int field"); + + p.integer *= 4; + std\assert(p.integer == 4, message: "*= on object instance int field"); + + p.integer /= 2; + std\assert(p.integer == 2, message: "/= on object instance int field"); + + p.integer %= 2; + std\assert(p.integer == 0, message: "%= on object instance int field"); + + p.integer = 3; + p.integer <<= 1; + std\assert(p.integer == 6, message: "<<= on instance int field"); + + p.integer >>= 1; + std\assert(p.integer == 3, message: ">>= on instance int field"); + + p.integer ^= 2; + std\assert(p.integer == 1, message: "^= on instance int field"); + + p.integer |= 2; + std\assert(p.integer == 3, message: "|= on instance int field"); + + p.integer &= 2; + std\assert(p.integer == 2, message: "&= 2 on instance int field"); + + p.floating += 1.0; + std\assert(p.floating == 2, message: "+= on object instance double field"); + + p.floating -= 1.0; + std\assert(p.floating == 1, message: "-= on object instance double field"); + + p.floating *= 4.0; + std\assert(p.floating == 4, message: "*= on object instance double field"); + + p.floating /= 2.0; + std\assert(p.floating == 2, message: "/= on object instance double field"); + + p.floating %= 2.0; + std\assert(p.floating == 0, message: "%= on object instance double field"); + + p.list += [ 4, 5, 6 ]; + std\assert(p.list.len() == 6, message: "+= on object instance list field"); + + p.map += { "two": 2 }; + std\assert(p.map.size() == 2, message: "+= on object instance map field"); + + p.string += " world"; + std\assert(p.string == "hello world", message: "+= on object instance string field"); +} + +test "Composite operators on object static fields" { + P.sinteger += 1; + std\assert(P.sinteger == 2, message: "+= on object static int field"); + + P.sinteger -= 1; + std\assert(P.sinteger == 1, message: "-= on object static int field"); + + P.sinteger *= 4; + std\assert(P.sinteger == 4, message: "*= on object static int field"); + + P.sinteger /= 2; + std\assert(P.sinteger == 2, message: "/= on object static int field"); + + P.sinteger %= 2; + std\assert(P.sinteger == 0, message: "%= on object static int field"); + + P.sinteger = 3; + P.sinteger <<= 1; + std\assert(P.sinteger == 6, message: "<<= on instance int field"); + + P.sinteger >>= 1; + std\assert(P.sinteger == 3, message: ">>= on instance int field"); + + P.sinteger ^= 2; + std\assert(P.sinteger == 1, message: "^= on instance int field"); + + P.sinteger |= 2; + std\assert(P.sinteger == 3, message: "|= on instance int field"); + + P.sinteger &= 2; + std\assert(P.sinteger == 2, message: "&= 2 on instance int field"); + + P.sfloating += 1.0; + std\assert(P.sfloating == 2, message: "+= on object static double field"); + + P.sfloating -= 1.0; + std\assert(P.sfloating == 1, message: "-= on object static double field"); + + P.sfloating *= 4.0; + std\assert(P.sfloating == 4, message: "*= on object static double field"); + + P.sfloating /= 2.0; + std\assert(P.sfloating == 2, message: "/= on object static double field"); + + P.sfloating %= 2.0; + std\assert(P.sfloating == 0, message: "%= on object static double field"); + + P.slist += [ 4, 5, 6 ]; + std\assert(P.slist.len() == 6, message: "+= on object static list field"); + + P.smap += { "two": 2 }; + std\assert(P.smap.size() == 2, message: "+= on object static map field"); + + P.sstring += " world"; + std\assert(P.sstring == "hello world", message: "+= on object static string field"); +} diff --git a/tests/fuzzed/id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24 b/tests/fuzzed/id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24 new file mode 100644 index 00000000..5a4d7573 --- /dev/null +++ b/tests/fuzzed/id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24 @@ -0,0 +1,16 @@ +import "std"; + +object Padload:: { + data: mut={K: V}, +} + +test "Objects generics" { + final payload = Payload::{ + data = mut { "one": 1 }, + }; + + payload.data["two"] = 2; + + std\assert(payload is Payload::, message: "Could use objects generics"); + std\assert(payload.data["two"] == 2, message: "Could use objects generics"); +} diff --git a/tests/fuzzed/id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289 b/tests/fuzzed/id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289 new file mode 100644 index 00000000..17f799bb --- /dev/null +++ b/tests/fuzzed/id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289 @@ -0,0 +1,73 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern0(typeof.A); +} + +zdef( + "tesstruct { + msg: [*:8]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203 b/tests/fuzzed/id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203 new file mode 100644 index 00000000..afa61159 --- /dev/null +++ b/tests/fuzzed/id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = ex^ern) == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260 b/tests/fuzzed/id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260 new file mode 100644 index 00000000..b12366e0 --- /dev/null +++ b/tests/fuzzed/id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [*:8]const c8, + id: i32, + }; + A ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof, message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354 b/tests/fuzzed/id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354 new file mode 100644 index 00000000..51c14d00 --- /dev/null +++ b/tests/fuzzed/id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354 @@ -0,0 +1,20 @@ +import "std"; + +object Person { + name: str, + age: int?, +} + +test "Nullable object field has a default value at null" { + final person = Person{ + name = "Joe", + }; + + std\assert(person.age == null, message: "Nullable object field has a default value at null"); +} + +test "Nullable variable has a default value at null" { + final hello: iàt?; + + std\assert(hello == null, message: "Nullable variable has default value at null"); +} diff --git a/tests/fuzzed/id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166 b/tests/fuzzed/id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166 new file mode 100644 index 00000000..f9135a21 --- /dev/null +++ b/tests/fuzzed/id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [**0]constcu8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + + std\assert(typeof C == , message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260 b/tests/fuzzed/id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260 new file mode 100644 index 00000000..6dec5fda --- /dev/null +++ b/tests/fuzzed/id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct { + msg: [**0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005 b/tests/fuzzed/id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005 new file mode 100644 index 00000000..f52a758b --- /dev/null +++ b/tests/fuzzed/id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.remove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379 b/tests/fuzzed/id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379 new file mode 100644 index 00000000..4684b9c9 --- /dev/null +++ b/tests/fuzzed/id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.remove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +@ + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7 b/tests/fuzzed/id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7 new file mode 100644 index 00000000..e0a8544c --- /dev/null +++ b/tests/fuzzed/id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.rWmove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2$ + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7 b/tests/fuzzed/id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7 new file mode 100644 index 00000000..bea31679 --- /dev/null +++ b/tests/fuzzed/id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] is int?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.rWmove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in c‹py) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155 b/tests/fuzzed/id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155 new file mode 100644 index 00000000..c7fab5b9 --- /dev/null +++ b/tests/fuzzed/id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155 @@ -0,0 +1,96 @@ +import "std"; + +test "Maps" { + final map = mut { + "hello": 1, + "bye": 2, + }; + + _ = { 1: true, 2: false }; + + std\assert(map["bye"] –Œß–nt?, message: "yeah"); + + std\assert(map["bye"] == 2, message: "map subscript"); + std\assert(({ 1: true, 2: false })[2] == false, message: "map expression subscript"); + + std\assert(map.rWmove("hello") == 1, message: "removed element"); + // std\assert(map["hello"] == null, message: "removed element"); + std\assert(map.size() == 1, message: "map size"); +} + +test "map merge" { + final map = { "one": 1, "two": 22 } + { "three": 3, "two": 2 }; + + std\assert(map["two"] == 2, message: "map merge"); + std\assert(map.size() == 3, message: "map merge"); +} + +test "map.keys" { + std\assert({ "one": 1, "two": 2, "three": 3 }.keys().join(",") == "one,two,three", message: "map.keys"); +} + +test "map.values" { + std\assert({ "one": 1, "two": 2, "three": 3 }.values().join(",") == "1,2,3", message: "map.values"); + + std\assert({}.keys().len() == 0, message: "yo empty map"); +} + +test "map.diff" { + final first = { + "one": 1, + "two": 2, + "three": 3, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final diff = first.diff(second); + + std\assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); +} + +test "map.intersect" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + + final second = { + "two": 22, + "three": 33, + "four": 4, + }; + + final intersect = first.intersect(second); + + std\assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); +} + +test "map.clone" { + final first = { + "one": 1, + "two": 2, + "five": 5, + }; + final copy = first.copyImmutable(); + + std\assert(copy.size() == first.size(), message: "Could clone map"); + foreach (key, value in copy) { + std\assert(first[key] == value, message: "Could clone map"); + } +} + +test "empty map type inferring" { + final map = {}; + + std\assert(typeof map == <{any: any}>); + + final smap: {str: int} = {}; + + std\assert(typeof smap == <{str: int}>); +} diff --git a/tests/fuzzed/id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260 b/tests/fuzzed/id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260 new file mode 100644 index 00000000..464e8f06 --- /dev/null +++ b/tests/fuzzed/id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260 @@ -0,0 +1,68 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case,s} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = extern struct[{ + msg: [*:8]const c8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type en ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} diff --git a/tests/fuzzed/id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47 b/tests/fuzzed/id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47 new file mode 100644 index 00000000..39a3c2be --- /dev/null +++ b/tests/fuzzed/id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47 @@ -0,0 +1,27 @@ +import "std"; + +fun pack(names: [str]) > obj{ :sÈr, :str, :str } { + return .{ + names[0], + names[1], + names[2], + }; +} + +test "Tuples" { + final tuple = .{ "joe", "doe" }; + + std\assert(tuple.@"0" == "joe" and tuple.@"1" == "doe"); + + final name = "Joe"; + final age = 42; + + // Forced tuple + final another = .{ (name), (age) }; + + std\assert(another.@"0" == "Joe" and another.@"1" == 42); + + final names = pack([ "Joe", "John", "James" ]); + + std\assert(names.@"0" == "Joe" and names.@"1" == "John"); +} diff --git a/tests/fuzzed/id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54 b/tests/fuzzed/id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54 new file mode 100644 index 00000000..b3765d49 --- /dev/null +++ b/tests/fuzzed/id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54 @@ -0,0 +1,27 @@ +import "std"; + +fun pack(names: [str]) > obj{ :str, :st¹, :str } { + return .{ + names[0], + names[1], + names[2], + }; +} + +test "Tuples" { + final tuple = .{ "joe", "doe" }; + + std\assert(tuple.@"0" == "joe" and tuple.@"1" == "doe"); + + final name = "Joe"; + final age = 42; + + // Forced tuple + final another = .{ (name), (age) }; + + std\assert(another.@"0" == "Joe" and another.@"1" == 42); + + final names = pack([ "Joe", "John", "James" ]); + + std\assert(names.@"0" == "Joe" and names.@"1" == "John"); +} diff --git a/tests/fuzzed/id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59 b/tests/fuzzed/id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59 new file mode 100644 index 00000000..1e4bb1be --- /dev/null +++ b/tests/fuzzed/id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59 @@ -0,0 +1,27 @@ +import "std"; + +fun pack(names: [str]) > obj{ :str, :str, :sÛr } { + return .{ + names[0], + names[1], + names[2], + }; +} + +test "Tuples" { + final tuple = .{ "joe", "doe" }; + + std\assert(tuple.@"0" == "joe" and tuple.@"1" == "doe"); + + final name = "Joe"; + final age = 42; + + // Forced tuple + final another = .{ (name), (age) }; + + std\assert(another.@"0" == "Joe" and another.@"1" == 42); + + final names = pack([ "Joe", "John", "James" ]); + + std\assert(names.@"0" == "Joe" and names.@"1" == "John"); +} diff --git a/tests/fuzzed/id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132 b/tests/fuzzed/id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132 new file mode 100644 index 00000000..7402041b --- /dev/null +++ b/tests/fuzzed/id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132 @@ -0,0 +1,27 @@ +import "std"; + +fun pack(names: [str]) > obj{ :str, :str, :str } { + return .{ + names[0], + names[1], + names[2]$ + }; +} + +test "Tuples" { + final tuple = .{ "joe", "doe" }; + + std\assert(tuple.@"0" == "joe" and tuple.@"1" == "doe"); + + final name = "Joe"; + final age = 42; + + // Forced tuple + final another = .{ (name), (age) }; + + std\assert(another.@"0" == "Joe" and another.@"1" == 42); + + final names = pack([ "Joe", "John", "James" ]); + + std\assert(names.@"0" == "Joe" and names.@"1" == "John"); +} diff --git a/tests/fuzzed/id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347 b/tests/fuzzed/id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347 new file mode 100644 index 00000000..5a52c411 --- /dev/null +++ b/tests/fuzzed/id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347 @@ -0,0 +1,27 @@ +import "std"; + +fun pack(names: [str]) > obj{ :str, :str, :str } { + return .{ + names[0], + names[1], + names[2], + }; +} + +test "Tuples" { + final tuple = .{ "joe", "doe" }; + + std\assert(tuple.@"0" == "joe" and tuple.@"1" == "doe"); + + final name = "Joe"; + final age = 42; + + // Forced tuple + final another = .{&(name), (age) }; + + std\assert(another.@"0" == "Joe" and another.@"1" == 42); + + final names = pack([ "Joe", "John", "James" ]); + + std\assert(names.@"0" == "Joe" and names.@"1" == "John"); +} diff --git a/tests/fuzzed/id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60 b/tests/fuzzed/id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60 new file mode 100644 index 00000000..0004990a --- /dev/null +++ b/tests/fuzzed/id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60 @@ -0,0 +1,27 @@ +import "std"; + +fun pack(names: [str]) > obj{ :str,L:str, :st } { + return .{ + names[0], + names[1], + names[2], + }; +} + +test "Tuples" { + final tuple = .{ "joe", "doe" }; + + std\assert(tuple.@"0" == "joe" and tuple.@"1" == "doe"); + + final name = "Joe"; + final age = 42; + + // Forced tuple + final another = .{ (name), (age) }; + + std\assert(another.@"0" == "Joe" and another.@"1" == 42); + + final names = pack([ "Joe", "John", "James" ]); + + std\assert(names.@"0" == "Joe" and names.@"1" == "John"); +} diff --git a/tests/fuzzed/id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1 b/tests/fuzzed/id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1 new file mode 100644 index 00000000..66d47b77 --- /dev/null +++ b/tests/fuzzed/id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1 @@ -0,0 +1,27 @@ +import "std"; + +fun pack(names: [str]) > obj{ :str,L:str, :str } { + return .{ + names[0], + names[1], + names[2], + }; +} + +test "Tuples" { + final tuple = .{ "joe", "doe" }; + + std\assert(tuple.@"0" == "joe" and tuple.@"1" == "doe"); + + final name = "Joe"; + final age = 42; + + // Forced tuple + final another = .{ (name), (age) }; + + std\assert(another.@"0" == "Joe" and another.@"1" == 42)@ + + final names = pack([ "Joe", "John", "James" ]); + + std\assert(names.@"0" == "Joe" and names.@"1" == "John"); +} diff --git a/tests/fuzzed/id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260 b/tests/fuzzed/id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260 new file mode 100644 index 00000000..dfa69547 --- /dev/null +++ b/tests/fuzzed/id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260 @@ -0,0 +1,69 @@ +import "std"; +import "debug"; + +object A {} + +enum B { + case, +} + +fun dumpType(myType: type) > void { + std\print("{myType}"); +} + +protocol C {} + +test "Types as value" { + _ = ; + final another = ; + final again = ; + + std\assert(another == again, message: "Can compare type values"); +} + +test "typeof" { + std\assert(typeof A{} == , message: "typeof operator instance"); + std\assert(typeof B.case == , message: "typeof operator case"); + std\assert(typeof "hello" == , message: "typeof operator str"); + std\assert(typeof true == , message: "typeof operator bool"); + std\assert(typeof null == , message: "typeof operator null"); + std\assert(typeof 1 == , message: "typeof operator int"); + std\assert(typeof 3.14 == , message: "typeof operator double"); + std\assert(typeof $"hello" == , message: "typeof operator pattern"); + std\assert(typeof dumpType == void *> void>, message: "typeof operator"); +} + +test "type argument" { + dumpType(typeof A); +} + +zdef( + "tests/utils/libforeign", + ` + const Data = %xtern struct { + msg: [*:0]const u8, + id: i32, + }; + ` +); + +test "necessary weirdness" { + std\assert((, message: "protocol is a type at runtime"); + std\assert(typeof Data == , message: "fstruct is a type at runtime"); +} + +fun generic::(value: T) > T { + return value; +} + +fun typeArg(T: type, value: str) > str { + debug\dump(T); + return value; +} + +test "generic type expression ambiguity" { + debug\dump(generic::("hello")); + debug\dump(typeArg(, value: "hello")); +} From 6df5b126831971f0b4f444283e7164d5d33fb35b Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Tue, 4 Nov 2025 16:52:05 +0100 Subject: [PATCH 04/17] feat: Moved type checking in TypeChecker so it can be used also by Ast.Node.toValue --- src/Ast.zig | 118 +- src/Codegen.zig | 2063 ++----------------------- src/Jit.zig | 2 +- src/Parser.zig | 6 +- src/Reporter.zig | 7 + src/TypeChecker.zig | 2304 ++++++++++++++++++++++++++++ src/TypeRegistry.zig | 3 + tests/behavior/035-const-expr.buzz | 4 +- 8 files changed, 2528 insertions(+), 1979 deletions(-) create mode 100644 src/TypeChecker.zig diff --git a/src/Ast.zig b/src/Ast.zig index 9a8a76f0..abbf71a8 100644 --- a/src/Ast.zig +++ b/src/Ast.zig @@ -9,6 +9,8 @@ const Parser = @import("Parser.zig"); const GC = @import("GC.zig"); // TODO: cleanup Error sets! const Error = @import("Codegen.zig").Error; +const Reporter = @import("Reporter.zig"); +const TypeChecker = @import("TypeChecker.zig"); const Self = @This(); @@ -484,13 +486,13 @@ pub const Slice = struct { return ctx.result orelse false; } - fn binaryValue(self: Self.Slice, node: Node.Index, gc: *GC) !?Value { + fn binaryValue(self: Self.Slice, node: Node.Index, reporter: *Reporter, gc: *GC) !?Value { const components = self.nodes.items(.components)[node].Binary; - const left = try self.toValue(components.left, gc); + const left = try self.toValue(components.left, reporter, gc); const left_integer = if (left.isInteger()) left.integer() else null; const left_float = if (left.isDouble()) left.double() else null; - const right = try self.toValue(components.right, gc); + const right = try self.toValue(components.right, reporter, gc); const right_integer = if (right.isInteger()) right.integer() else null; const right_float = if (right.isDouble()) right.double() else null; @@ -700,8 +702,25 @@ pub const Slice = struct { } } - pub fn toValue(self: Self.Slice, node: Node.Index, gc: *GC) Error!Value { + pub fn toValue( + self: Self.Slice, + node: Node.Index, + reporter: *Reporter, + gc: *GC, + ) Error!Value { + if (try TypeChecker.check( + self, + reporter, + gc, + null, + node, + )) { + return Value.Void; + } + const value = &self.nodes.items(.value)[node]; + // const type_defs = self.nodes.items(.type_def); + const components = self.nodes.items(.components); if (value.* == null and try self.isConstant(gc.allocator, node)) { value.* = switch (self.nodes.items(.tag)[node]) { @@ -715,43 +734,44 @@ pub const Slice = struct { .SimpleType, .UserType, => self.nodes.items(.type_def)[node].?.toValue(), - .StringLiteral => self.nodes.items(.components)[node].StringLiteral.literal.toValue(), + .StringLiteral => components[node].StringLiteral.literal.toValue(), .TypeOfExpression => (try (try self.toValue( - self.nodes.items(.components)[node].TypeOfExpression, + components[node].TypeOfExpression, + reporter, gc, )).typeOf(gc)).toValue(), - .TypeExpression => self.nodes.items(.type_def)[self.nodes.items(.components)[node].TypeExpression].?.toValue(), - .Pattern => self.nodes.items(.components)[node].Pattern.toValue(), + .TypeExpression => self.nodes.items(.type_def)[components[node].TypeExpression].?.toValue(), + .Pattern => components[node].Pattern.toValue(), .Void => Value.Void, .Null => Value.Null, - .Double => Value.fromDouble(self.nodes.items(.components)[node].Double), - .Integer => Value.fromInteger(self.nodes.items(.components)[node].Integer), - .Boolean => Value.fromBoolean(self.nodes.items(.components)[node].Boolean), - .As => try self.toValue(self.nodes.items(.components)[node].As.left, gc), + .Double => Value.fromDouble(components[node].Double), + .Integer => Value.fromInteger(components[node].Integer), + .Boolean => Value.fromBoolean(components[node].Boolean), + .As => try self.toValue(components[node].As.left, reporter, gc), .Is => is: { - const components = self.nodes.items(.components)[node].Is; + const is_components = components[node].Is; break :is Value.fromBoolean( - (try self.toValue(components.constant, gc)) - .is(try self.toValue(components.left, gc)), + (try self.toValue(is_components.constant, reporter, gc)) + .is(try self.toValue(is_components.left, reporter, gc)), ); }, - .Binary => try self.binaryValue(node, gc), + .Binary => try self.binaryValue(node, reporter, gc), .Dot => dot: { // Only Enum.case can be constant - const components = self.nodes.items(.components)[node].Dot; - const type_def = self.nodes.items(.type_def)[components.callee].?; + const dot_components = components[node].Dot; + const type_def = self.nodes.items(.type_def)[dot_components.callee].?; break :dot (try gc.allocateObject( obj.ObjEnumInstance{ .enum_ref = type_def.resolved_type.?.Enum.value.?, - .case = @intCast(components.value_or_call_or_enum.EnumCase), + .case = @intCast(dot_components.value_or_call_or_enum.EnumCase), }, )).toValue(); }, - .Expression => try self.toValue(self.nodes.items(.components)[node].Expression, gc), - .Grouping => try self.toValue(self.nodes.items(.components)[node].Grouping, gc), + .Expression => try self.toValue(components[node].Expression, reporter, gc), + .Grouping => try self.toValue(components[node].Grouping, reporter, gc), .ForceUnwrap => fc: { - const unwrapped = try self.toValue(self.nodes.items(.components)[node].ForceUnwrap.unwrapped, gc); + const unwrapped = try self.toValue(components[node].ForceUnwrap.unwrapped, reporter, gc); if (unwrapped.isNull()) { return Error.UnwrappedNull; @@ -759,26 +779,26 @@ pub const Slice = struct { break :fc unwrapped; }, - .GenericResolve => try self.toValue(self.nodes.items(.components)[node].GenericResolve.expression, gc), + .GenericResolve => try self.toValue(components[node].GenericResolve.expression, reporter, gc), .If => @"if": { - const components = self.nodes.items(.components)[node].If; - break :@"if" if ((try self.toValue(components.condition, gc)).boolean()) - try self.toValue(components.body, gc) + const if_components = components[node].If; + break :@"if" if ((try self.toValue(if_components.condition, reporter, gc)).boolean()) + try self.toValue(if_components.body, reporter, gc) else - try self.toValue(components.else_branch.?, gc); + try self.toValue(if_components.else_branch.?, reporter, gc); }, .Range => range: { - const components = self.nodes.items(.components)[node].Range; + const rg_components = components[node].Range; break :range (try gc.allocateObject( obj.ObjRange{ - .low = (try self.toValue(components.low, gc)).integer(), - .high = (try self.toValue(components.high, gc)).integer(), + .low = (try self.toValue(rg_components.low, reporter, gc)).integer(), + .high = (try self.toValue(rg_components.high, reporter, gc)).integer(), }, )).toValue(); }, .List => list: { - const components = self.nodes.items(.components)[node].List; + const list_components = components[node].List; const type_def = self.nodes.items(.type_def)[node]; std.debug.assert(type_def != null and type_def.?.def_type != .Placeholder); @@ -787,17 +807,17 @@ pub const Slice = struct { try obj.ObjList.init(gc.allocator, type_def.?), ); - for (components.items) |item| { + for (list_components.items) |item| { try list.items.append( gc.allocator, - try self.toValue(item, gc), + try self.toValue(item, reporter, gc), ); } break :list list.toValue(); }, .Map => map: { - const components = self.nodes.items(.components)[node].Map; + const map_components = components[node].Map; const type_def = self.nodes.items(.type_def)[node]; std.debug.assert(type_def != null and type_def.?.def_type != .Placeholder); @@ -806,33 +826,33 @@ pub const Slice = struct { try obj.ObjMap.init(gc.allocator, type_def.?), ); - for (components.entries) |entry| { + for (map_components.entries) |entry| { try map.map.put( gc.allocator, - try self.toValue(entry.key, gc), - try self.toValue(entry.value, gc), + try self.toValue(entry.key, reporter, gc), + try self.toValue(entry.value, reporter, gc), ); } break :map map.toValue(); }, .String => string: { - const elements = self.nodes.items(.components)[node].String; + const elements = components[node].String; var string = std.Io.Writer.Allocating.init(gc.allocator); defer string.deinit(); for (elements) |element| { - try (try self.toValue(element, gc)).toString(&string.writer); + try (try self.toValue(element, reporter, gc)).toString(&string.writer); } break :string (try gc.copyString(string.written())).toValue(); }, .Subscript => subscript: { - const components = self.nodes.items(.components)[node].Subscript; + const subscript_components = components[node].Subscript; - const subscriptable = (try self.toValue(components.subscripted, gc)).obj(); - const key = try self.toValue(components.index, gc); + const subscriptable = (try self.toValue(subscript_components.subscripted, reporter, gc)).obj(); + const key = try self.toValue(subscript_components.index, reporter, gc); switch (subscriptable.obj_type) { .List => { @@ -840,7 +860,7 @@ pub const Slice = struct { const index: usize = @intCast(key.integer()); if (index < 0 or index >= list.items.items.len) { - if (components.checked) { + if (subscript_components.checked) { break :subscript Value.Null; } @@ -859,7 +879,7 @@ pub const Slice = struct { const index: usize = @intCast(key.integer()); if (index < 0 or index >= str.string.len) { - if (components.checked) { + if (subscript_components.checked) { break :subscript Value.Null; } @@ -873,13 +893,13 @@ pub const Slice = struct { else => unreachable, } - break :subscript self.nodes.items(.components)[node].Subscript.toValue(); + break :subscript components[node].Subscript.toValue(); }, .Unary => unary: { - const components = self.nodes.items(.components)[node].Unary; - const val = try self.toValue(components.expression, gc); + const unary_components = components[node].Unary; + const val = try self.toValue(unary_components.expression, reporter, gc); - break :unary switch (components.operator) { + break :unary switch (unary_components.operator) { .Bnot => Value.fromInteger(~val.integer()), .Bang => Value.fromBoolean(!val.boolean()), .Minus => if (val.isInteger()) @@ -889,7 +909,7 @@ pub const Slice = struct { else => unreachable, }; }, - .Unwrap => try self.toValue(self.nodes.items(.components)[node].Unwrap.unwrapped, gc), + .Unwrap => try self.toValue(components[node].Unwrap.unwrapped, reporter, gc), else => null, }; } diff --git a/src/Codegen.zig b/src/Codegen.zig index 459a3ec3..c7053f42 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -16,6 +16,7 @@ const BuildOptions = @import("build_options"); const JIT = if (!is_wasm) @import("Jit.zig") else void; const disassembler = @import("disassembler.zig"); const io = @import("io.zig"); +const TypeChecker = @import("TypeChecker.zig"); const Self = @This(); @@ -416,6 +417,14 @@ fn generateNode(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj return null; } + _ = try TypeChecker.check( + self.ast, + &self.reporter, + self.gc, + if (self.current) |current| current.function_node else null, + node, + ); + if (Self.generators[@intFromEnum(self.ast.nodes.items(.tag)[node])]) |generator| { return generator(self, node, breaks); } @@ -428,7 +437,11 @@ fn nodeValue(self: *Self, node: Ast.Node.Index) Error!?Value { if (value.* == null) { if (self.ast.isConstant(node)) { - value.* = try self.ast.toValue(node, self.gc); + value.* = try self.ast.toValue( + node, + &self.reporter, + self.gc, + ); } } @@ -440,17 +453,14 @@ fn generateAs(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.O const node_location = locations[node]; const components = self.ast.nodes.items(.components)[node].As; - const constant = try self.ast.toValue(components.constant, self.gc); + const constant = try self.ast.toValue( + components.constant, + &self.reporter, + self.gc, + ); std.debug.assert(constant.isObj() and constant.obj().obj_type == .Type); - if (obj.ObjTypeDef.cast(constant.obj()).?.def_type == .Placeholder) { - self.reporter.reportPlaceholder( - self.ast, - obj.ObjTypeDef.cast(constant.obj()).?.resolved_type.?.Placeholder, - ); - } - _ = try self.generateNode(components.left, breaks); try self.OP_COPY(locations[components.left], 0); @@ -498,107 +508,11 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o const components = self.ast.nodes.items(.components)[node].Binary; const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const type_defs = self.ast.nodes.items(.type_def); const left_type = type_defs[components.left].?; - const right_type = type_defs[components.right].?; - - if (left_type.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, left_type.resolved_type.?.Placeholder); - } - - if (right_type.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, right_type.resolved_type.?.Placeholder); - } - - switch (components.operator) { - .QuestionQuestion, - .Ampersand, - .Bor, - .Xor, - .ShiftLeft, - .ShiftRight, - .Plus, - .Minus, - .Star, - .Slash, - .Percent, - .And, - .Or, - => { - if (!left_type.eql(right_type)) { - self.reporter.reportTypeCheck( - .binary_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - left_type, - self.ast.tokens.get(locations[components.right]), - self.ast.tokens.get(end_locations[components.right]), - right_type, - "Type mismatch", - ); - } - }, - - .Greater, - .Less, - .GreaterEqual, - .LessEqual, - .BangEqual, - .EqualEqual, - => { - // We allow comparison between double and int so raise error if type != and one operand is not a number - if (!left_type.eql(right_type) and - !right_type.eql(left_type) and - ((left_type.def_type != .Integer and left_type.def_type != .Double) or (right_type.def_type != .Integer and right_type.def_type != .Double))) - { - self.reporter.reportTypeCheck( - .comparison_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - left_type, - self.ast.tokens.get(locations[components.right]), - self.ast.tokens.get(end_locations[components.right]), - right_type, - "Type mismatch", - ); - } - }, - - else => unreachable, - } - - if (components.operator != .QuestionQuestion and components.operator != .EqualEqual and components.operator != .BangEqual) { - if (left_type.optional) { - self.reporter.reportErrorAt( - .binary_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Binary operand can't be optional", - ); - } - - if (right_type.optional) { - self.reporter.reportErrorAt( - .binary_operand_type, - self.ast.tokens.get(locations[components.right]), - self.ast.tokens.get(end_locations[components.right]), - "Binary operand can't be optional", - ); - } - } switch (components.operator) { .QuestionQuestion => { - if (!left_type.optional) { - self.reporter.reportErrorAt( - .optional, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Not an optional", - ); - } - _ = try self.generateNode(components.left, breaks); const end_jump: usize = try self.OP_JUMP_IF_NOT_NULL(locations[node]); @@ -609,134 +523,47 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o self.patchJump(end_jump); }, .Ampersand => { - // Checking only left operand since we asserted earlier that both operand have the same type - if (left_type.def_type != .Integer) { - self.reporter.reportErrorAt( - .bitwise_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_BAND(locations[node]); }, .Bor => { - // Checking only left operand since we asserted earlier that both operand have the same type - if (left_type.def_type != .Integer) { - self.reporter.reportErrorAt( - .bitwise_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_BOR(locations[node]); }, .Xor => { - // Checking only left operand since we asserted earlier that both operand have the same type - if (left_type.def_type != .Integer) { - self.reporter.reportErrorAt( - .bitwise_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_XOR(locations[node]); }, .ShiftLeft => { - // Checking only left operand since we asserted earlier that both operand have the same type - if (left_type.def_type != .Integer) { - self.reporter.reportErrorAt( - .bitwise_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_SHL(locations[node]); }, .ShiftRight => { - // Checking only left operand since we asserted earlier that both operand have the same type - if (left_type.def_type != .Integer) { - self.reporter.reportErrorAt( - .bitwise_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_SHR(locations[node]); }, .Greater => { - // Checking only left operand since we asserted earlier that both operand have the same type - if (left_type.def_type != .Integer and left_type.def_type != .Double) { - self.reporter.reportErrorAt( - .comparison_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int` or `double`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_GREATER(locations[node]); }, .Less => { - if (left_type.def_type != .Integer and left_type.def_type != .Double) { - self.reporter.reportErrorAt( - .comparison_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int` or `double`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_LESS(locations[node]); }, .GreaterEqual => { - if (left_type.def_type != .Integer and left_type.def_type != .Double) { - self.reporter.reportErrorAt( - .comparison_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int` or `double`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_LESS(locations[node]); try self.OP_NOT(locations[node]); }, .LessEqual => { - if (left_type.def_type != .Integer and left_type.def_type != .Double) { - self.reporter.reportErrorAt( - .comparison_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int` or `double`.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.OP_GREATER(locations[node]); @@ -754,20 +581,6 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o try self.OP_EQUAL(locations[node]); }, .Plus => { - if (left_type.def_type != .Integer and - left_type.def_type != .Double and - left_type.def_type != .String and - left_type.def_type != .List and - left_type.def_type != .Map) - { - self.reporter.reportErrorAt( - .arithmetic_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected a `int`, `double`, `str`, list or map.", - ); - } - _ = try self.generateNode(components.left, breaks); _ = try self.generateNode(components.right, breaks); try self.emitOpCode(locations[node], switch (left_type.def_type) { @@ -789,15 +602,9 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o if (left_type.def_type == .Integer) { try self.OP_SUBTRACT_I(locations[node]); - } else if (left_type.def_type == .Double) { - try self.OP_SUBTRACT_F(locations[node]); } else { - self.reporter.reportErrorAt( - .arithmetic_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int` or `double`.", - ); + std.debug.assert(left_type.def_type == .Double); + try self.OP_SUBTRACT_F(locations[node]); } }, .Star => { @@ -806,15 +613,8 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o if (left_type.def_type == .Integer) { try self.OP_MULTIPLY_I(locations[node]); - } else if (left_type.def_type == .Double) { - try self.OP_MULTIPLY_F(locations[node]); } else { - self.reporter.reportErrorAt( - .arithmetic_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int` or `double`.", - ); + try self.OP_MULTIPLY_F(locations[node]); } }, .Slash => { @@ -823,15 +623,8 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o if (left_type.def_type == .Integer) { try self.OP_DIVIDE_I(locations[node]); - } else if (left_type.def_type == .Double) { - try self.OP_DIVIDE_F(locations[node]); } else { - self.reporter.reportErrorAt( - .arithmetic_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int` or `double`.", - ); + try self.OP_DIVIDE_F(locations[node]); } }, .Percent => { @@ -840,27 +633,11 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o if (left_type.def_type == .Integer) { try self.OP_MOD_I(locations[node]); - } else if (left_type.def_type == .Double) { - try self.OP_MOD_F(locations[node]); } else { - self.reporter.reportErrorAt( - .arithmetic_operand_type, - self.ast.tokens.get(locations[components.left]), - self.ast.tokens.get(end_locations[components.left]), - "Expected `int` or `double`.", - ); + try self.OP_MOD_F(locations[node]); } }, .And => { - if (left_type.def_type != .Bool) { - self.reporter.reportErrorAt( - .logical_operand_type, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "`and` expects operands to be `bool`", - ); - } - _ = try self.generateNode(components.left, breaks); const end_jump: usize = try self.OP_JUMP_IF_FALSE(locations[node]); @@ -871,15 +648,6 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o self.patchJump(end_jump); }, .Or => { - if (left_type.def_type != .Bool) { - self.reporter.reportErrorAt( - .logical_operand_type, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "`and` expects operands to be `bool`", - ); - } - _ = try self.generateNode(components.left, breaks); const else_jump: usize = try self.OP_JUMP_IF_FALSE(locations[node]); @@ -1011,45 +779,11 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj const components = node_components[node].Call; const callee_type_def = type_defs[components.callee].?; - if (callee_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, callee_type_def.resolved_type.?.Placeholder); - } // This is not a call but an Enum(value) if (callee_type_def.def_type == .Enum) { - if (components.is_async) { - self.reporter.reportErrorAt( - .fiber_call_not_allowed, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - "Can't be wrapped in a fiber", - ); - } - - if (components.catch_default != null) { - self.reporter.reportErrorAt( - .no_error, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - "Doesn't raise any error", - ); - } - - if (components.arguments.len != 1) { - self.reporter.reportErrorAt( - .enum_argument, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - "Enum instanciation requires only value argument", - ); - } - const value = components.arguments[0].value; - if (type_defs[value].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[value].?.resolved_type.?.Placeholder); - } - _ = try self.generateNode(components.callee, breaks); _ = try self.generateNode(value, breaks); try self.OP_GET_ENUM_CASE_FROM_VALUE(locations[value]); @@ -1085,39 +819,10 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj else => type_defs[components.callee], }; - if (callee_type == null) { - self.reporter.reportErrorAt( - .undefined, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - "Callee is not defined", - ); - } else if (callee_type.?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, callee_type.?.resolved_type.?.Placeholder); - - // We know nothing about the function being called, no need to go any further - return null; - } else if (callee_type.?.def_type != .Function) { - self.reporter.reportErrorAt( - .callable, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "Can't be called", - ); - - return null; - } else if (callee_type.?.optional) { - self.reporter.reportErrorAt( - .callable, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "Function maybe null and can't be called", - ); - } - const yield_type = callee_type.?.resolved_type.?.Function.yield_type; // Function being called and current function should have matching yield type unless the current function is an entrypoint + // We do this type checking here because we need access to the current function node if (!components.is_async) { const current_function_typedef = type_defs[self.current.?.function_node].?.resolved_type.?.Function; const current_function_type = current_function_typedef.function_type; @@ -1158,15 +863,6 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj ); } - if (components.arguments.len > arg_count) { - self.reporter.reportErrorAt( - .call_arguments, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "Too many arguments.", - ); - } - // First push on the stack arguments has they are parsed var needs_reorder = false; for (components.arguments, 0..) |argument, index| { @@ -1174,7 +870,6 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj break; } - var argument_type_def = type_defs[argument.value].?; const arg_key = if (argument.name) |arg_name| try self.gc.copyString(lexemes[arg_name]) else @@ -1183,44 +878,13 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj arg_keys[0] else arg_key.?; - const def_arg_type = args.get(actual_arg_key); const ref_index = args.getIndex(actual_arg_key); if (index != ref_index) { needs_reorder = true; } - // Type check the argument - if (def_arg_type) |arg_type| { - self.populateEmptyCollectionType(argument.value, arg_type); - argument_type_def = type_defs[argument.value].?; - - if (argument_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, argument_type_def.resolved_type.?.Placeholder); - } else if (!arg_type.eql(argument_type_def)) { - self.reporter.reportTypeCheck( - .call_argument_type, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - arg_type, - self.ast.tokens.get(locations[argument.value]), - self.ast.tokens.get(end_locations[argument.value]), - argument_type_def, - "Bad argument type", - ); - } - - _ = missing_arguments.orderedRemove(actual_arg_key.string); - } else { - self.reporter.reportErrorFmt( - .call_arguments, - self.ast.tokens.get(locations[argument.value]), - self.ast.tokens.get(end_locations[argument.value]), - "Argument `{s}` does not exists.", - .{if (arg_key) |key| key.string else "unknown"}, - ); - } - + _ = missing_arguments.orderedRemove(actual_arg_key.string); _ = try self.generateNode(argument.value, breaks); } @@ -1244,7 +908,6 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj const missing_keys = tmp_missing_arguments.keys(); for (missing_keys) |missing_key| { if (defaults.get(try self.gc.copyString(missing_key))) |default| { - // TODO: like ObjTypeDef, avoid generating constants multiple time for the same value try self.emitConstant(locations[node], default); try self.OP_CLONE(locations[node]); @@ -1255,39 +918,6 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj } } - // Not enough arguments? - if (missing_arguments.count() > 0) { - var missing = std.Io.Writer.Allocating.init(self.gc.allocator); - defer missing.deinit(); - - for (missing_arguments.keys(), 0..) |key, i| { - try missing.writer.print( - "{s}{s}", - .{ - key, - if (i < missing_arguments.keys().len - 1) - ", " - else - "", - }, - ); - } - - self.reporter.reportErrorFmt( - .call_arguments, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "Missing argument{s}: {s}", - .{ - if (missing_arguments.count() > 1) - "s" - else - "", - missing.written(), - }, - ); - } - // Reorder arguments (don't bother is something failed before) if (self.reporter.last_error == null and needs_reorder) { // Until ordered @@ -1326,34 +956,7 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj // Catch clause const error_types = callee_type.?.resolved_type.?.Function.error_types; if (components.catch_default) |catch_default| { - const catch_default_type_def = type_defs[catch_default].?; - if (error_types == null or error_types.?.len == 0) { - self.reporter.reportErrorAt( - .no_error, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "Function doesn't raise any error", - ); - } else if (error_types != null) { - if (catch_default_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, catch_default_type_def.resolved_type.?.Placeholder); - } else { - const node_type_def = type_defs[node].?; - // Expression - if (!node_type_def.eql(catch_default_type_def) and !(try node_type_def.cloneOptional(&self.gc.type_registry)).eql(catch_default_type_def)) { - self.reporter.reportTypeCheck( - .inline_catch_type, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - node_type_def, - self.ast.tokens.get(locations[catch_default]), - self.ast.tokens.get(end_locations[catch_default]), - catch_default_type_def, - "Bad inline catch value type", - ); - } - } - + if (error_types != null and error_types.?.len > 0) { _ = try self.generateNode(catch_default, breaks); } } else if (error_types) |errors| { @@ -1514,12 +1117,10 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj return null; } -// FIXME: this is become a unreadable mess fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const node_components = self.ast.nodes.items(.components); const type_defs = self.ast.nodes.items(.type_def); const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const tags = self.ast.tokens.items(.tag); const components = node_components[node].Dot; @@ -1527,42 +1128,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. _ = try self.generateNode(components.callee, breaks); - const callee_type = type_defs[components.callee].?; - - if (callee_type.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, callee_type.resolved_type.?.Placeholder); - } - - switch (callee_type.def_type) { - .ObjectInstance, - .Object, - .ProtocolInstance, - .Enum, - .EnumInstance, - .List, - .Map, - .String, - .Pattern, - .Fiber, - .ForeignContainer, - .Range, - => {}, - else => self.reporter.reportErrorAt( - .field_access, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "Doesn't have field access", - ), - } - - if (callee_type.optional) { - self.reporter.reportErrorAt( - .field_access, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "Optional doesn't have field access", - ); - } + const callee_type = type_defs[components.callee] orelse self.gc.type_registry.any_type; const get_code: ?Chunk.OpCode = switch (callee_type.def_type) { .Object => .OP_GET_OBJECT_PROPERTY, @@ -1624,89 +1190,6 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. self.reporter.reportPlaceholder(self.ast, value_type_def.resolved_type.?.Placeholder); } - // Type check value - switch (callee_type.def_type) { - .ForeignContainer => { - const field_type = callee_type.resolved_type.?.ForeignContainer.buzz_type.get(field_name).?; - - if (!field_type.eql(value_type_def)) { - self.reporter.reportTypeCheck( - .assignment_value_type, - self.ast.tokens.get(callee_type.resolved_type.?.ForeignContainer.location), - self.ast.tokens.get(callee_type.resolved_type.?.ForeignContainer.location), - field_type, - self.ast.tokens.get(locations[value]), - self.ast.tokens.get(end_locations[value]), - value_type_def, - "Bad property type", - ); - } - }, - .ObjectInstance, .Object => { - if (field.?.method or - (callee_type.def_type == .ObjectInstance and field.?.static) or - (callee_type.def_type == .Object and !field.?.static)) - { - self.reporter.reportErrorFmt( - .assignable, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - "`{s}` is not assignable", - .{ - field_name, - }, - ); - } else if (field.?.final) { - self.reporter.reportErrorFmt( - .constant_property, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - "`{s}` is final", - .{ - field_name, - }, - ); - } else if (callee_type.def_type == .ObjectInstance and !callee_type.resolved_type.?.ObjectInstance.mutable) { - self.reporter.reportWithOrigin( - .not_mutable, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - self.ast.tokens.get( - callee_type.resolved_type.?.ObjectInstance.of - .resolved_type.?.Object.location, - ), - self.ast.tokens.get( - callee_type.resolved_type.?.ObjectInstance.of - .resolved_type.?.Object.location, - ), - "Instance of `{s}` is not mutable", - .{ - callee_type.resolved_type.?.ObjectInstance.of - .resolved_type.?.Object.qualified_name.string, - }, - "declared here", - ); - } - - self.populateEmptyCollectionType(value, field.?.type_def); - value_type_def = type_defs[value].?; - - if (!field.?.type_def.eql(value_type_def)) { - self.reporter.reportTypeCheck( - .assignment_value_type, - self.ast.tokens.get(field.?.location), - self.ast.tokens.get(field.?.location), - field.?.type_def, - self.ast.tokens.get(locations[value]), - self.ast.tokens.get(end_locations[value]), - value_type_def, - "Bad property type", - ); - } - }, - else => unreachable, - } - switch (tags[assign_token]) { .PlusEqual, .MinusEqual, @@ -1735,52 +1218,6 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. else => {}, } - // Type check that operator is allowed - switch (tags[assign_token]) { - .PlusEqual => switch (type_defs[value].?.def_type) { - .Integer, - .Double, - .List, - .Map, - .String, - => {}, - else => self.reporter.report( - .arithmetic_operand_type, - self.ast.tokens.get(assign_token), - self.ast.tokens.get(assign_token), - "Addition is only allowed for types `int`, `double`, list, map and `str`", - ), - }, - .MinusEqual, - .StarEqual, - .SlashEqual, - .PercentEqual, - => switch (type_defs[value].?.def_type) { - .Integer, .Double => {}, - else => self.reporter.report( - .arithmetic_operand_type, - self.ast.tokens.get(assign_token), - self.ast.tokens.get(assign_token), - "Operator is only allowed for types `int`, `double`", - ), - }, - .ShiftRightEqual, - .ShiftLeftEqual, - .XorEqual, - .BorEqual, - .BnotEqual, - .AmpersandEqual, - => if (type_defs[value].?.def_type != .Integer) { - self.reporter.report( - .arithmetic_operand_type, - self.ast.tokens.get(assign_token), - self.ast.tokens.get(assign_token), - "Operator is only allowed for `int`", - ); - }, - else => {}, - } - _ = try self.generateNode(value, breaks); switch (tags[assign_token]) { @@ -1832,15 +1269,6 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. ); }, .Call => { - if (callee_type.def_type == .ForeignContainer) { - self.reporter.reportErrorAt( - .callable, - self.ast.tokens.get(locations[components.callee]), - self.ast.tokens.get(end_locations[components.callee]), - "Not callable", - ); - } - // Static call if (callee_type.def_type == .Object) { try self.emitCodeArg( @@ -1848,13 +1276,6 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. get_code.?, @intCast(field.?.index), ); - } else if (field.?.mutable and !callee_type.resolved_type.?.ObjectInstance.mutable) { - self.reporter.report( - .not_mutable, - self.ast.tokens.get(components.identifier), - self.ast.tokens.get(components.identifier), - "Method requires mutable instance", - ); } _ = try self.generateNode(components.value_or_call_or_enum.Call, breaks); @@ -1872,21 +1293,6 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. }, .ProtocolInstance => { if (components.member_kind == .Call) { - const field_name = self.ast.tokens.items(.lexeme)[components.identifier]; - const field = callee_type.resolved_type.?.ProtocolInstance.of - .resolved_type.?.Protocol - .methods - .get(field_name); - - if (field.?.mutable and !callee_type.resolved_type.?.ProtocolInstance.mutable) { - self.reporter.report( - .not_mutable, - self.ast.tokens.get(components.identifier), - self.ast.tokens.get(components.identifier), - "Method requires mutable instance", - ); - } - _ = try self.generateNode(components.value_or_call_or_enum.Call, breaks); } else { std.debug.assert(components.member_kind == .Ref); @@ -1910,40 +1316,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. }, .List, .Map, .Range => { if (components.member_kind == .Call) { - const identifier = self.ast.tokens.items(.lexeme)[components.identifier]; - try self.OP_COPY(locations[node], 0); - - switch (callee_type.def_type) { - .List => if (callee_type.resolved_type.?.List.methods.get(identifier).?.mutable and - !callee_type.resolved_type.?.List.mutable) - { - self.reporter.reportErrorFmt( - .not_mutable, - self.ast.tokens.get(components.identifier), - self.ast.tokens.get(components.identifier), - "Method `{s}` requires mutable list", - .{ - identifier, - }, - ); - }, - .Map => if (callee_type.resolved_type.?.Map.methods.get(identifier).?.mutable and - !callee_type.resolved_type.?.Map.mutable) - { - self.reporter.reportErrorFmt( - .not_mutable, - self.ast.tokens.get(components.identifier), - self.ast.tokens.get(components.identifier), - "Method `{s}` requires mutable list", - .{ - identifier, - }, - ); - }, - else => {}, - } - _ = try self.generateNode(components.value_or_call_or_enum.Call, breaks); } else { std.debug.assert(components.member_kind != .Value); @@ -1971,8 +1344,6 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. fn generateDoUntil(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); - const type_defs = self.ast.nodes.items(.type_def); const node_components = self.ast.nodes.items(.components); const components = node_components[node].DoUntil; @@ -1982,22 +1353,6 @@ fn generateDoUntil(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?* defer lbreaks.deinit(self.gc.allocator); _ = try self.generateNode(components.body, &lbreaks); - - const condition_type_def = type_defs[components.condition].?; - - if (condition_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, condition_type_def.resolved_type.?.Placeholder); - } - - if (condition_type_def.def_type != .Bool) { - self.reporter.reportErrorAt( - .do_condition_type, - self.ast.tokens.get(locations[components.condition]), - self.ast.tokens.get(end_locations[components.condition]), - "`do` condition must be bool", - ); - } - _ = try self.generateNode(components.condition, &lbreaks); try self.OP_NOT(locations[node]); @@ -2025,77 +1380,25 @@ fn generateDoUntil(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?* fn generateEnum(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); - const type_defs = self.ast.nodes.items(.type_def); const node_components = self.ast.nodes.items(.components); const components = node_components[node].Enum; - const enum_type = type_defs[node].?.resolved_type.?.Enum.enum_type; - if (enum_type.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, enum_type.resolved_type.?.Placeholder); + try self.OP_CONSTANT( + locations[node], + try self.ast.toValue( + node, + &self.reporter, + self.gc, + ), + ); + try self.OP_DEFINE_GLOBAL( + locations[node], + @intCast(components.slot), + (try self.gc.copyString(self.ast.tokens.items(.lexeme)[components.name])).toValue(), + ); - return null; - } - - switch (enum_type.def_type) { - .String, - .Integer, - .Double, - .Pattern, - .UserData, - .Void, - .Range, - => {}, - else => { - self.reporter.reportErrorAt( - .syntax, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - "Type not allowed as enum value", - ); - return null; - }, - } - - for (components.cases) |case| { - const case_type_def = if (case.value) |value| - type_defs[value].? - else - null; - - if (case_type_def) |case_type| { - if (case_type.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, case_type.resolved_type.?.Placeholder); - } else if (!((try enum_type.toInstance(&self.gc.type_registry, false))).eql(case_type)) { - self.reporter.reportTypeCheck( - .enum_case_type, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - (try enum_type.toInstance( - &self.gc.type_registry, - false, - )), - self.ast.tokens.get(locations[case.value.?]), - self.ast.tokens.get(end_locations[case.value.?]), - case_type, - "Bad enum case type", - ); - } - } - } - - try self.OP_CONSTANT( - locations[node], - try self.ast.toValue(node, self.gc), - ); - try self.OP_DEFINE_GLOBAL( - locations[node], - @intCast(components.slot), - (try self.gc.copyString(self.ast.tokens.items(.lexeme)[components.name])).toValue(), - ); - - try self.patchOptJumps(node); - try self.endScope(node); + try self.patchOptJumps(node); + try self.endScope(node); return null; } @@ -2155,7 +1458,11 @@ fn generateExpression(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error fn generateFloat(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjFunction { try self.emitConstant( self.ast.nodes.items(.location)[node], - try self.ast.toValue(node, self.gc), + try self.ast.toValue( + node, + &self.reporter, + self.gc, + ), ); try self.patchOptJumps(node); @@ -2171,7 +1478,11 @@ fn generateFor(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. const node_components = self.ast.nodes.items(.components); const components = node_components[node].For; - if (try self.ast.isConstant(self.gc.allocator, components.condition) and !(try self.ast.toValue(components.condition, self.gc)).boolean()) { + if (try self.ast.isConstant(self.gc.allocator, components.condition) and !(try self.ast.toValue( + components.condition, + &self.reporter, + self.gc, + )).boolean()) { try self.patchOptJumps(node); return null; @@ -2251,24 +1562,8 @@ fn generateFor(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. fn generateForceUnwrap(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const components = self.ast.nodes.items(.components)[node].ForceUnwrap; - if (components.original_type.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, components.original_type.resolved_type.?.Placeholder); - - return null; - } - - if (!components.original_type.optional) { - self.reporter.reportErrorAt( - .optional, - self.ast.tokens.get(locations[components.unwrapped]), - self.ast.tokens.get(end_locations[components.unwrapped]), - "Not an optional", - ); - } - _ = try self.generateNode(components.unwrapped, breaks); try self.OP_UNWRAP(locations[node]); @@ -2282,184 +1577,18 @@ fn generateForceUnwrap(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Erro fn generateForEach(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const node_components = self.ast.nodes.items(.components); const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const type_defs = self.ast.nodes.items(.type_def); const components = node_components[node].ForEach; - // Type checking const iterable_type_def = type_defs[components.iterable].?; - var key_type_def = type_defs[components.key].?; - const value_type_def = type_defs[components.value].?; - if (iterable_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, iterable_type_def.resolved_type.?.Placeholder); - } else { - if (!components.key_omitted) { - if (key_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, key_type_def.resolved_type.?.Placeholder); - } - - switch (iterable_type_def.def_type) { - .String, .List => { - if (key_type_def.def_type != .Integer) { - self.reporter.reportErrorAt( - .foreach_key_type, - self.ast.tokens.get(locations[components.key]), - self.ast.tokens.get(end_locations[components.key]), - "Expected `int`.", - ); - } - }, - .Map => { - if (!iterable_type_def.resolved_type.?.Map.key_type.strictEql(key_type_def)) { - self.reporter.reportTypeCheck( - .foreach_key_type, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - iterable_type_def.resolved_type.?.Map.key_type, - self.ast.tokens.get(locations[components.key]), - self.ast.tokens.get(end_locations[components.key]), - key_type_def, - "Bad key type", - ); - } - }, - .Enum => self.reporter.reportErrorAt( - .foreach_key_type, - self.ast.tokens.get(locations[components.key]), - self.ast.tokens.get(end_locations[components.key]), - "No key available when iterating over enum.", - ), - .Range => self.reporter.reportErrorAt( - .foreach_key_type, - self.ast.tokens.get(locations[components.key]), - self.ast.tokens.get(end_locations[components.key]), - "No key available when iterating over range.", - ), - else => self.reporter.reportErrorAt( - .foreach_iterable, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - "Not iterable.", - ), - } - } else { - // Key was omitted, put the correct type in the key var declation to avoid raising errors - switch (iterable_type_def.def_type) { - .Map => key_type_def = iterable_type_def.resolved_type.?.Map.key_type, - .String, .List => key_type_def = self.gc.type_registry.int_type, - else => {}, - } - } - - if (value_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, value_type_def.resolved_type.?.Placeholder); - } - - switch (iterable_type_def.def_type) { - .Map => { - if (!iterable_type_def.resolved_type.?.Map.value_type.strictEql(value_type_def)) { - self.reporter.reportTypeCheck( - .foreach_value_type, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - iterable_type_def.resolved_type.?.Map.value_type, - self.ast.tokens.get(locations[components.value]), - self.ast.tokens.get(end_locations[components.value]), - value_type_def, - "Bad value type", - ); - } - }, - .List => { - if (!iterable_type_def.resolved_type.?.List.item_type.strictEql(value_type_def)) { - self.reporter.reportTypeCheck( - .foreach_value_type, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - iterable_type_def.resolved_type.?.List.item_type, - self.ast.tokens.get(locations[components.value]), - self.ast.tokens.get(end_locations[components.value]), - value_type_def, - "Bad value type", - ); - } - }, - .Range => { - if (value_type_def.def_type != .Integer or value_type_def.optional) { - self.reporter.reportTypeCheck( - .foreach_value_type, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - self.gc.type_registry.int_type, - self.ast.tokens.get(locations[components.value]), - self.ast.tokens.get(end_locations[components.value]), - value_type_def, - "Bad value type", - ); - } - }, - .String => { - if (value_type_def.def_type != .String) { - self.reporter.reportTypeCheck( - .foreach_value_type, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - self.gc.type_registry.str_type, - self.ast.tokens.get(locations[components.value]), - self.ast.tokens.get(end_locations[components.value]), - value_type_def, - "Bad value type", - ); - } - }, - .Enum => { - const iterable_type = try iterable_type_def.toInstance( - &self.gc.type_registry, - false, - ); - if (!iterable_type.strictEql(value_type_def)) { - self.reporter.reportTypeCheck( - .foreach_value_type, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - iterable_type, - self.ast.tokens.get(locations[components.value]), - self.ast.tokens.get(end_locations[components.value]), - value_type_def, - "Bad value type", - ); - } - }, - .Fiber => { - const iterable_type = try iterable_type_def.resolved_type.?.Fiber.yield_type.toInstance( - &self.gc.type_registry, - false, - ); - if (!iterable_type.strictEql(value_type_def)) { - self.reporter.reportTypeCheck( - .foreach_value_type, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - iterable_type, - self.ast.tokens.get(locations[components.value]), - self.ast.tokens.get(end_locations[components.value]), - value_type_def, - "Bad value type", - ); - } - }, - else => self.reporter.reportErrorAt( - .foreach_iterable, - self.ast.tokens.get(locations[components.iterable]), - self.ast.tokens.get(end_locations[components.iterable]), - "Not iterable.", - ), - } - } // If iterable constant and empty, skip the node if (try self.ast.isConstant(self.gc.allocator, components.iterable)) { - const iterable = (try self.ast.toValue(components.iterable, self.gc)).obj(); + const iterable = (try self.ast.toValue( + components.iterable, + &self.reporter, + self.gc, + )).obj(); if (switch (iterable.obj_type) { .List => obj.ObjList.cast(iterable).?.items.items.len == 0, @@ -2598,7 +1727,11 @@ fn generateFunction(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!? try node_type_def.resolved_type.?.Function.defaults.put( self.gc.allocator, try self.gc.copyString(self.ast.tokens.items(.lexeme)[argument.name]), - try self.ast.toValue(default, self.gc), + try self.ast.toValue( + default, + &self.reporter, + self.gc, + ), ); } } @@ -2817,99 +1950,10 @@ fn generateFunDeclaration(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) E } fn generateGenericResolve(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { - const type_def = self.ast.nodes.items(.type_def)[node].?; - const expr = self.ast.nodes.items(.components)[node].GenericResolve.expression; - const node_location = self.ast.nodes.items(.location)[node]; - const node_end_location = self.ast.nodes.items(.end_location)[node]; - - switch (type_def.def_type) { - .Function => { - const function_type = type_def.resolved_type.?.Function; - - if (function_type.generic_types.count() > 0 and - (function_type.resolved_generics == null or function_type.resolved_generics.?.len < function_type.generic_types.count())) - { - self.reporter.reportErrorFmt( - .generic_type, - self.ast.tokens.get(node_location), - self.ast.tokens.get(node_end_location), - "Missing generic types. Expected {} got {}.", - .{ - function_type.generic_types.count(), - if (function_type.resolved_generics == null) - 0 - else - function_type.resolved_generics.?.len, - }, - ); - } else if (function_type.resolved_generics != null and function_type.resolved_generics.?.len > function_type.generic_types.count()) { - self.reporter.reportErrorFmt( - .generic_type, - self.ast.tokens.get(node_location), - self.ast.tokens.get(node_end_location), - "Too many generic types. Expected {} got {}.", - .{ - function_type.generic_types.count(), - if (function_type.resolved_generics == null) - 0 - else - function_type.resolved_generics.?.len, - }, - ); - } - }, - .Object => { - const object_type = type_def.resolved_type.?.Object; - - if (object_type.generic_types.count() > 0 and - (object_type.resolved_generics == null or object_type.resolved_generics.?.len < object_type.generic_types.count())) - { - self.reporter.reportErrorFmt( - .generic_type, - self.ast.tokens.get(node_location), - self.ast.tokens.get(node_end_location), - "Missing generic types. Expected {} got {}.", - .{ - object_type.generic_types.count(), - if (object_type.resolved_generics == null) - 0 - else - object_type.resolved_generics.?.len, - }, - ); - } else if (object_type.resolved_generics != null and object_type.resolved_generics.?.len > object_type.generic_types.count()) { - self.reporter.reportErrorFmt( - .generic_type, - self.ast.tokens.get(node_location), - self.ast.tokens.get(node_end_location), - "Too many generic types. Expected {} got {}.", - .{ - object_type.generic_types.count(), - if (object_type.resolved_generics == null) - 0 - else - object_type.resolved_generics.?.len, - }, - ); - } - }, - else => { - const type_def_str = type_def.toStringAlloc(self.gc.allocator, false) catch unreachable; - defer self.gc.allocator.free(type_def_str); - - self.reporter.reportErrorFmt( - .generic_type, - self.ast.tokens.get(node_location), - self.ast.tokens.get(node_end_location), - "Type `{s}` does not support generic types", - .{ - type_def_str, - }, - ); - }, - } - - _ = try self.generateNode(expr, breaks); + _ = try self.generateNode( + self.ast.nodes.items(.components)[node].GenericResolve.expression, + breaks, + ); try self.patchOptJumps(node); try self.endScope(node); @@ -2932,79 +1976,20 @@ fn generateGrouping(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!? fn generateIf(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const type_defs = self.ast.nodes.items(.type_def); const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const node_components = self.ast.nodes.items(.components); const components = node_components[node].If; const location = locations[node]; - // Type checking - if (type_defs[components.condition].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[components.condition].?.resolved_type.?.Placeholder); - } - - if (!components.is_statement) { - if (type_defs[components.body].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[components.body].?.resolved_type.?.Placeholder); - } - - if (type_defs[components.else_branch.?].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[components.else_branch.?].?.resolved_type.?.Placeholder); - } - - // Both should have same type - if (!type_defs[node].?.eql(type_defs[components.body].?)) { - self.reporter.reportTypeCheck( - .inline_if_body_type, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - type_defs[node].?, - self.ast.tokens.get(locations[components.body]), - self.ast.tokens.get(end_locations[components.body]), - type_defs[components.body].?, - "Inline if body type not matching", - ); - } - - if (!type_defs[node].?.eql(type_defs[components.else_branch.?].?)) { - self.reporter.reportTypeCheck( - .inline_if_else_type, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - type_defs[node].?, - self.ast.tokens.get(locations[components.else_branch.?]), - self.ast.tokens.get(end_locations[components.else_branch.?]), - type_defs[components.else_branch.?].?, - "Inline if else type not matching", - ); - } - } - - if (components.casted_type == null and components.unwrapped_identifier == null) { - if (type_defs[components.condition].?.def_type != .Bool) { - self.reporter.reportErrorAt( - .if_condition_type, - self.ast.tokens.get(locations[components.condition]), - self.ast.tokens.get(end_locations[components.condition]), - "`if` condition must be bool", - ); - } - } else if (components.casted_type == null) { - if (!type_defs[components.condition].?.optional) { - self.reporter.reportErrorAt( - .optional, - self.ast.tokens.get(locations[components.condition]), - self.ast.tokens.get(end_locations[components.condition]), - "Expected optional", - ); - } - } - // If condition is a constant expression, no need to generate branches if (try self.ast.isConstant(self.gc.allocator, components.condition) and components.unwrapped_identifier == null and components.casted_type == null) { - const condition = try self.ast.toValue(components.condition, self.gc); + const condition = try self.ast.toValue( + components.condition, + &self.reporter, + self.gc, + ); if (condition.boolean()) { _ = try self.generateNode(components.body, breaks); @@ -3079,7 +2064,11 @@ fn generateImport(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o fn generateInteger(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjFunction { try self.emitConstant( self.ast.nodes.items(.location)[node], - try self.ast.toValue(node, self.gc), + try self.ast.toValue( + node, + &self.reporter, + self.gc, + ), ); try self.patchOptJumps(node); @@ -3091,7 +2080,11 @@ fn generateInteger(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.O fn generateIs(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const components = self.ast.nodes.items(.components)[node].Is; const location = self.ast.nodes.items(.location)[node]; - const constant = try self.ast.toValue(components.constant, self.gc); + const constant = try self.ast.toValue( + components.constant, + &self.reporter, + self.gc, + ); std.debug.assert(constant.isObj()); std.debug.assert(constant.obj().obj_type == .Type); @@ -3114,34 +2107,16 @@ fn generateIs(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.O fn generateList(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const components = self.ast.nodes.items(.components)[node].List; const type_defs = self.ast.nodes.items(.type_def); - const item_type = type_defs[node].?.resolved_type.?.List.item_type; - try self.OP_LIST( locations[node], type_defs[node].?.toValue(), ); for (components.items) |item| { - if (item_type.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[item].?.resolved_type.?.Placeholder); - } else if (!item_type.eql(type_defs[item].?)) { - self.reporter.reportTypeCheck( - .list_item_type, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - item_type, - self.ast.tokens.get(locations[item]), - self.ast.tokens.get(end_locations[item]), - type_defs[item].?, - "Bad list type", - ); - } else { - _ = try self.generateNode(item, breaks); - } + _ = try self.generateNode(item, breaks); } if (components.items.len > 0) { @@ -3159,20 +2134,9 @@ fn generateList(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj fn generateMap(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const components = self.ast.nodes.items(.components)[node].Map; const type_defs = self.ast.nodes.items(.type_def); - const key_type = if (components.explicit_key_type) |kt| - type_defs[kt] - else - null; - - const value_type = if (components.explicit_value_type) |vt| - type_defs[vt] - else - null; - try self.OP_MAP( locations[node], type_defs[node].?.toValue(), @@ -3181,40 +2145,6 @@ fn generateMap(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. for (components.entries) |entry| { _ = try self.generateNode(entry.key, breaks); _ = try self.generateNode(entry.value, breaks); - - if (type_defs[entry.key].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[entry.key].?.resolved_type.?.Placeholder); - } - - if (type_defs[entry.value].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[entry.value].?.resolved_type.?.Placeholder); - } - - if (key_type != null and !key_type.?.eql(type_defs[entry.key].?)) { - self.reporter.reportTypeCheck( - .map_key_type, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - key_type.?, - self.ast.tokens.get(locations[entry.key]), - self.ast.tokens.get(end_locations[entry.key]), - type_defs[entry.key].?, - "Bad key type", - ); - } - - if (value_type != null and !value_type.?.eql(type_defs[entry.value].?)) { - self.reporter.reportTypeCheck( - .map_value_type, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - value_type.?, - self.ast.tokens.get(locations[entry.value]), - self.ast.tokens.get(end_locations[entry.value]), - type_defs[entry.value].?, - "Bad value type", - ); - } } if (components.entries.len > 0) { @@ -3233,7 +2163,6 @@ fn generateMap(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. fn generateNamedVariable(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const components = self.ast.nodes.items(.components)[node].NamedVariable; const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const type_defs = self.ast.nodes.items(.type_def); const tags = self.ast.tokens.items(.tag); @@ -3256,24 +2185,6 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Er } if (components.value) |value| { - // Type checking - if (type_defs[node].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[node].?.resolved_type.?.Placeholder); - } - - if (!type_defs[node].?.eql(type_defs[value].?)) { - self.reporter.reportTypeCheck( - .assignment_value_type, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - type_defs[node].?, - self.ast.tokens.get(locations[value]), - self.ast.tokens.get(end_locations[value]), - type_defs[value].?, - "Bad value type", - ); - } - switch (tags[components.assign_token.?]) { .PlusEqual, .MinusEqual, @@ -3294,52 +2205,6 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Er else => {}, } - // Type check that operator is allowed - switch (tags[components.assign_token.?]) { - .PlusEqual => switch (type_defs[node].?.def_type) { - .Integer, - .Double, - .List, - .Map, - .String, - => {}, - else => self.reporter.report( - .arithmetic_operand_type, - self.ast.tokens.get(components.assign_token.?), - self.ast.tokens.get(components.assign_token.?), - "Addition is only allowed for types `int`, `double`, list, map and `str`", - ), - }, - .MinusEqual, - .StarEqual, - .SlashEqual, - .PercentEqual, - => switch (type_defs[node].?.def_type) { - .Integer, .Double => {}, - else => self.reporter.report( - .arithmetic_operand_type, - self.ast.tokens.get(components.assign_token.?), - self.ast.tokens.get(components.assign_token.?), - "Operator is only allowed for types `int`, `double`", - ), - }, - .ShiftRightEqual, - .ShiftLeftEqual, - .XorEqual, - .BorEqual, - .BnotEqual, - .AmpersandEqual, - => if (type_defs[node].?.def_type != .Integer) { - self.reporter.report( - .arithmetic_operand_type, - self.ast.tokens.get(components.assign_token.?), - self.ast.tokens.get(components.assign_token.?), - "Operator is only allowed for `int`", - ); - }, - else => {}, - } - _ = try self.generateNode(value, breaks); switch (tags[components.assign_token.?]) { @@ -3409,7 +2274,6 @@ fn generateNull(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjF fn generateObjectDeclaration(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const type_defs = self.ast.nodes.items(.type_def); const lexemes = self.ast.tokens.items(.lexeme); const components = self.ast.nodes.items(.components)[node].ObjectDeclaration; @@ -3418,72 +2282,6 @@ fn generateObjectDeclaration(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks const object_type = type_defs[node].?; const object_def = object_type.resolved_type.?.Object; - // Check object conforms to declared protocols - var protocol_it = object_def.conforms_to.iterator(); - while (protocol_it.next()) |kv| { - const protocol_type_def = kv.key_ptr.*; - - if (protocol_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, protocol_type_def.resolved_type.?.Placeholder); - } else { - const protocol_def = protocol_type_def.resolved_type.?.Protocol; - - var method_it = protocol_def.methods.iterator(); - while (method_it.next()) |mkv| { - var found = false; - for (components.members) |member| { - if (member.method and std.mem.eql(u8, self.ast.tokens.items(.lexeme)[member.name], mkv.key_ptr.*)) { - found = true; - if (type_defs[member.method_or_default_value.?].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder( - self.ast, - type_defs[member.method_or_default_value.?].?.resolved_type.?.Placeholder, - ); - } else if (!mkv.value_ptr.*.type_def.eql(type_defs[member.method_or_default_value.?].?) or - mkv.value_ptr.*.mutable != object_def.fields.get(mkv.key_ptr.*).?.mutable) - { - self.reporter.reportTypeCheck( - .protocol_conforming, - self.ast.tokens.get(protocol_def.location), - self.ast.tokens.get(protocol_def.location), - mkv.value_ptr.*.type_def, - self.ast.tokens.get(locations[member.method_or_default_value.?]), - self.ast.tokens.get(end_locations[member.method_or_default_value.?]), - type_defs[member.method_or_default_value.?].?, - "Method not conforming to protocol", - ); - } - break; - } - } - - if (!found) { - self.reporter.reportWithOrigin( - .protocol_conforming, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - self.ast.tokens.get( - protocol_def.methods_locations.get( - mkv.value_ptr.*.type_def.resolved_type.?.Function.name.string, - ).?, - ), - self.ast.tokens.get( - protocol_def.methods_locations.get( - mkv.value_ptr.*.type_def.resolved_type.?.Function.name.string, - ).?, - ), - "Object declared as conforming to protocol `{s}` but doesn't implement method `{s}`", - .{ - protocol_def.name.string, - mkv.value_ptr.*.type_def.resolved_type.?.Function.name.string, - }, - null, - ); - } - } - } - } - // Put object on the stack and define global with it try self.OP_OBJECT(location, object_type.toValue()); try self.OP_DEFINE_GLOBAL( @@ -3501,85 +2299,17 @@ fn generateObjectDeclaration(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks if (member.method) { // Method const member_field = object_def.fields.get(member_name).?; - const member_type_def = member_field.type_def; const member_idx = member_field.index; - if (member_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, member_type_def.resolved_type.?.Placeholder); - } - - // Enforce "collect" method signature - if (std.mem.eql(u8, member_name, "collect")) { - const collect_def = member_type_def.resolved_type.?.Function; - - if (collect_def.parameters.count() > 0 or - collect_def.return_type.def_type != .Void or - collect_def.yield_type.def_type != .Void or - collect_def.error_types != null) - { - const collect_def_str = member_type_def.toStringAlloc(self.gc.allocator, false) catch @panic("Out of memory"); - defer self.gc.allocator.free(collect_def_str); - self.reporter.reportErrorFmt( - .collect_signature, - self.ast.tokens.get(locations[member.method_or_default_value.?]), - self.ast.tokens.get(end_locations[member.method_or_default_value.?]), - "Expected `collect` method to be `fun collect() > void` got {s}", - .{ - collect_def_str, - }, - ); - } - } else if (std.mem.eql(u8, member_name, "toString")) { // Enforce "toString" method signature - const tostring_def = member_type_def.resolved_type.?.Function; - - if (tostring_def.parameters.count() > 0 or - tostring_def.return_type.def_type != .String or - tostring_def.yield_type.def_type != .Void or - tostring_def.error_types != null or - tostring_def.generic_types.count() > 0) - { - const tostring_def_str = member_type_def.toStringAlloc(self.gc.allocator, false) catch @panic("Out of memory"); - defer self.gc.allocator.free(tostring_def_str); - self.reporter.reportErrorFmt( - .tostring_signature, - self.ast.tokens.get(locations[member.method_or_default_value.?]), - self.ast.tokens.get(end_locations[member.method_or_default_value.?]), - "Expected `toString` method to be `fun toString() > str` got {s}", - .{ - tostring_def_str, - }, - ); - } - } - _ = try self.generateNode(member.method_or_default_value.?, breaks); try self.OP_PROPERTY(location, @intCast(member_idx)); } else { // Property const property_field = object_def.fields.get(member_name).?; - const property_type = property_field.type_def; const property_idx = property_field.index; // Create property default value if (member.method_or_default_value) |default| { - self.populateEmptyCollectionType(default, property_type); - const default_type_def = type_defs[default].?; - - if (default_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, default_type_def.resolved_type.?.Placeholder); - } else if (!property_type.eql(default_type_def)) { - self.reporter.reportTypeCheck( - .property_default_value, - self.ast.tokens.get(object_def.location), - self.ast.tokens.get(object_def.location), - property_type, - self.ast.tokens.get(locations[default]), - self.ast.tokens.get(end_locations[default]), - default_type_def, - "Wrong property default value type", - ); - } - if (property_field.static) { try self.OP_COPY(location, 0); } @@ -3611,7 +2341,6 @@ fn generateObjectDeclaration(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const type_defs = self.ast.nodes.items(.type_def); const lexemes = self.ast.tokens.items(.lexeme); const components = self.ast.nodes.items(.components)[node].ObjectInit; @@ -3626,21 +2355,6 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error try self.OP_CONSTANT(location, node_type_def.toValue()); - if (node_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, node_type_def.resolved_type.?.Placeholder); - - return null; - } else if (node_type_def.def_type != .ObjectInstance and node_type_def.def_type != .ForeignContainer) { - self.reporter.reportErrorAt( - .expected_object, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - "Expected object or foreign struct.", - ); - - return null; - } - try self.emitOpCode( location, if (node_type_def.def_type == .ObjectInstance) @@ -3649,33 +2363,6 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error .OP_FCONTAINER_INSTANCE, ); - var fields = if (node_type_def.def_type == .ObjectInstance) inst: { - const fields = node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.fields; - var fields_type_defs = std.StringArrayHashMapUnmanaged(*obj.ObjTypeDef).empty; - var it = fields.iterator(); - while (it.next()) |kv| { - try fields_type_defs.put( - self.gc.allocator, - kv.value_ptr.*.name, - kv.value_ptr.*.type_def, - ); - } - break :inst fields_type_defs; - } else node_type_def.resolved_type.?.ForeignContainer.buzz_type; - - defer if (node_type_def.def_type == .ObjectInstance) { - fields.deinit(self.gc.allocator); - }; - - const object_location = if (node_type_def.def_type == .ObjectInstance) - node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.location - else - node_type_def.resolved_type.?.ForeignContainer.location; - - // Keep track of what's been initialized or not by this statement - var init_properties = std.StringHashMapUnmanaged(void).empty; - defer init_properties.deinit(self.gc.allocator); - for (components.properties) |property| { const property_name = lexemes[property.name]; const property_idx = if (node_type_def.def_type == .ObjectInstance) @@ -3689,98 +2376,20 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error node_type_def.resolved_type.?.ForeignContainer .fields.getIndex(property_name); - if (fields.get(property_name)) |prop| { - try self.OP_COPY(location, 0); // Will be popped by OP_SET_PROPERTY - - self.populateEmptyCollectionType(property.value, prop); - const value_type_def = type_defs[property.value].?; - - if (value_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, value_type_def.resolved_type.?.Placeholder); - } else if (!prop.eql(value_type_def)) { - if (BuildOptions.debug_placeholders) { - io.print( - "prop {}({}), value {}({})\n", - .{ - @intFromPtr(prop.resolved_type.?.ObjectInstance.of), - prop.optional, - @intFromPtr(value_type_def.resolved_type.?.ObjectInstance.of), - value_type_def.optional, - }, - ); - } - - const err_location = self.ast.tokens.get( - if (node_type_def.def_type == .ObjectInstance) - node_type_def.resolved_type.?.ObjectInstance.of - .resolved_type.?.Object.fields.get(property_name).?.location - else - object_location, - ); - - self.reporter.reportTypeCheck( - .property_type, - err_location, - err_location, - prop, - self.ast.tokens.get(locations[property.value]), - self.ast.tokens.get(end_locations[property.value]), - value_type_def, - "Wrong property type", - ); - } - - _ = try self.generateNode(property.value, breaks); + try self.OP_COPY(location, 0); // Will be popped by OP_SET_PROPERTY - try init_properties.put(self.gc.allocator, property_name, {}); + _ = try self.generateNode(property.value, breaks); - try self.emitCodeArg( - location, - if (node_type_def.def_type == .ObjectInstance) - .OP_SET_INSTANCE_PROPERTY - else - .OP_SET_FCONTAINER_INSTANCE_PROPERTY, - @intCast(property_idx.?), - ); - try self.OP_POP(location); // Pop property value - } else { - self.reporter.reportWithOrigin( - .property_does_not_exists, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - self.ast.tokens.get(object_location), - self.ast.tokens.get(object_location), - "Property `{s}` does not exists", - .{property_name}, - null, - ); - } - } - - // Did we initialized all properties without a default value? - // If union we're statisfied with only on field initialized - if (node_type_def.def_type != .ForeignContainer or node_type_def.resolved_type.?.ForeignContainer.zig_type != .Union or init_properties.count() == 0) { - const field_defs = if (node_type_def.def_type == .ObjectInstance) - node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.fields - else - null; + try self.emitCodeArg( + location, + if (node_type_def.def_type == .ObjectInstance) + .OP_SET_INSTANCE_PROPERTY + else + .OP_SET_FCONTAINER_INSTANCE_PROPERTY, + @intCast(property_idx.?), + ); + try self.OP_POP(location); // Pop property value - var it = fields.iterator(); - while (it.next()) |kv| { - const field = if (field_defs) |fd| fd.get(kv.key_ptr.*) else null; - // If ommitted in initialization and doesn't have default value - if (init_properties.get(kv.key_ptr.*) == null and - (field == null or (!field.?.has_default and !field.?.method and !field.?.static))) - { - self.reporter.reportErrorFmt( - .property_not_initialized, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - "Property `{s}` was not initialized and has no default value", - .{kv.key_ptr.*}, - ); - } - } } try self.patchOptJumps(node); @@ -3792,7 +2401,11 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error fn generatePattern(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjFunction { try self.emitConstant( self.ast.nodes.items(.location)[node], - try self.ast.toValue(node, self.gc), + try self.ast.toValue( + node, + &self.reporter, + self.gc, + ), ); try self.patchOptJumps(node); @@ -3820,45 +2433,8 @@ fn generateProtocolDeclaration(self: *Self, node: Ast.Node.Index, _: ?*Breaks) E } fn generateRange(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { - const type_defs = self.ast.nodes.items(.type_def); const components = self.ast.nodes.items(.components)[node].Range; const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); - - // Type checking - if (type_defs[components.low].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[components.low].?.resolved_type.?.Placeholder); - } - - if (type_defs[components.high].?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_defs[components.high].?.resolved_type.?.Placeholder); - } - - if (type_defs[components.low].?.def_type != .Integer) { - self.reporter.reportTypeCheck( - .range_type, - null, - null, - self.gc.type_registry.int_type, - self.ast.tokens.get(locations[components.low]), - self.ast.tokens.get(end_locations[components.low]), - type_defs[components.low].?, - "Bad low range limit type", - ); - } - - if (type_defs[components.high].?.def_type != .Integer) { - self.reporter.reportTypeCheck( - .range_type, - null, - null, - self.gc.type_registry.int_type, - self.ast.tokens.get(locations[components.high]), - self.ast.tokens.get(end_locations[components.high]), - type_defs[components.high].?, - "Bad high range limit type", - ); - } _ = try self.generateNode(components.low, breaks); _ = try self.generateNode(components.high, breaks); @@ -3873,24 +2449,7 @@ fn generateRange(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*ob fn generateResolve(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const fiber = self.ast.nodes.items(.components)[node].Resolve; - const fiber_type_def = self.ast.nodes.items(.type_def)[fiber].?; const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); - - if (fiber_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, fiber_type_def.resolved_type.?.Placeholder); - - return null; - } - - if (fiber_type_def.def_type != .Fiber) { - self.reporter.reportErrorAt( - .fiber, - self.ast.tokens.get(locations[fiber]), - self.ast.tokens.get(end_locations[fiber]), - "Not a fiber", - ); - } _ = try self.generateNode(fiber, breaks); @@ -3904,24 +2463,7 @@ fn generateResolve(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?* fn generateResume(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const fiber = self.ast.nodes.items(.components)[node].Resume; - const fiber_type_def = self.ast.nodes.items(.type_def)[fiber].?; const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); - - if (fiber_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, fiber_type_def.resolved_type.?.Placeholder); - - return null; - } - - if (fiber_type_def.def_type != .Fiber) { - self.reporter.reportErrorAt( - .fiber, - self.ast.tokens.get(locations[fiber]), - self.ast.tokens.get(end_locations[fiber]), - "Not a fiber", - ); - } _ = try self.generateNode(fiber, breaks); @@ -3935,53 +2477,15 @@ fn generateResume(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o fn generateReturn(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const components = self.ast.nodes.items(.components)[node].Return; - const type_defs = self.ast.nodes.items(.type_def); const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); if (components.unconditional) { self.current.?.return_emitted = true; } if (components.value) |value| { - const value_type_def = type_defs[value]; - if (value_type_def == null) { - self.reporter.reportErrorAt( - .undefined, - self.ast.tokens.get(locations[value]), - self.ast.tokens.get(end_locations[value]), - "Unknown type.", - ); - } else if (value_type_def.?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, value_type_def.?.resolved_type.?.Placeholder); - } else if (!self.current.?.function.?.type_def.resolved_type.?.Function.return_type.eql(value_type_def.?)) { - self.reporter.reportTypeCheck( - .return_type, - self.ast.tokens.get(locations[self.current.?.function_node]), - self.ast.tokens.get(end_locations[self.current.?.function_node]), - self.current.?.function.?.type_def.resolved_type.?.Function.return_type, - self.ast.tokens.get(locations[value]), - self.ast.tokens.get(end_locations[value]), - value_type_def.?, - "Return value", - ); - } - _ = try self.generateNode(value, breaks); } else { - if (self.current.?.function.?.type_def.resolved_type.?.Function.return_type.def_type != .Void) { - self.reporter.reportTypeCheck( - .return_type, - self.ast.tokens.get(locations[self.current.?.function_node]), - self.ast.tokens.get(end_locations[self.current.?.function_node]), - self.current.?.function.?.type_def.resolved_type.?.Function.return_type, - self.ast.tokens.get(locations[node]), - self.ast.tokens.get(end_locations[node]), - self.gc.type_registry.void_type, - "Return value", - ); - } - try self.OP_VOID(locations[node]); } @@ -4010,12 +2514,6 @@ fn generateString(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o for (elements, 0..) |element, index| { const element_type_def = type_defs[element].?; - if (element_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, element_type_def.resolved_type.?.Placeholder); - - continue; - } - _ = try self.generateNode(element, breaks); if (element_type_def.def_type != .String or element_type_def.optional) { try self.OP_TO_STRING(location); @@ -4046,7 +2544,6 @@ fn generateStringLiteral(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!? fn generateSubscript(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const location = locations[node]; const type_defs = self.ast.nodes.items(.type_def); const components = self.ast.nodes.items(.components)[node].Subscript; @@ -4054,129 +2551,21 @@ fn generateSubscript(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error! _ = try self.generateNode(components.subscripted, breaks); const subscripted_type_def = type_defs[components.subscripted].?; - const index_type_def = type_defs[components.index].?; - const value_type_def = if (components.value) |value| type_defs[value] else null; - - if (subscripted_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, subscripted_type_def.resolved_type.?.Placeholder); - } - - if (index_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, index_type_def.resolved_type.?.Placeholder); - } - - if (components.value != null and value_type_def.?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, value_type_def.?.resolved_type.?.Placeholder); - } var get_code: Chunk.OpCode = .OP_GET_LIST_SUBSCRIPT; var set_code: Chunk.OpCode = .OP_SET_LIST_SUBSCRIPT; switch (subscripted_type_def.def_type) { .String => { - if (index_type_def.def_type != .Integer) { - self.reporter.reportErrorAt( - .subscript_key_type, - self.ast.tokens.get(locations[components.index]), - self.ast.tokens.get(end_locations[components.index]), - "Expected `int` index.", - ); - } - get_code = .OP_GET_STRING_SUBSCRIPT; std.debug.assert(components.value == null); }, - .List => { - if (index_type_def.def_type != .Integer) { - self.reporter.reportErrorAt( - .subscript_key_type, - self.ast.tokens.get(locations[components.index]), - self.ast.tokens.get(end_locations[components.index]), - "Expected `int` index.", - ); - } - if (components.value) |value| { - if (!type_defs[components.subscripted].?.isMutable()) { - const callee_type_str = type_defs[components.subscripted].?.toStringAlloc(self.gc.allocator, false) catch unreachable; - defer self.gc.allocator.free(callee_type_str); - self.reporter.reportErrorFmt( - .not_mutable, - self.ast.tokens.get(locations[components.subscripted]), - self.ast.tokens.get(end_locations[components.subscripted]), - "`{s}` not mutable", - .{ - callee_type_str, - }, - ); - } - - if (!subscripted_type_def.resolved_type.?.List.item_type.eql(value_type_def.?)) { - self.reporter.reportTypeCheck( - .subscript_value_type, - self.ast.tokens.get(locations[components.subscripted]), - self.ast.tokens.get(end_locations[components.subscripted]), - subscripted_type_def.resolved_type.?.List.item_type, - self.ast.tokens.get(locations[value]), - self.ast.tokens.get(end_locations[value]), - value_type_def.?, - "Bad value type", - ); - } - } - }, .Map => { - if (!subscripted_type_def.resolved_type.?.Map.key_type.eql(index_type_def)) { - self.reporter.reportTypeCheck( - .subscript_key_type, - self.ast.tokens.get(locations[components.subscripted]), - self.ast.tokens.get(end_locations[components.subscripted]), - subscripted_type_def.resolved_type.?.Map.key_type, - self.ast.tokens.get(locations[components.index]), - self.ast.tokens.get(end_locations[components.index]), - index_type_def, - "Bad key type", - ); - } - - if (components.value) |value| { - if (!type_defs[components.subscripted].?.isMutable()) { - const callee_type_str = type_defs[components.subscripted].?.toStringAlloc(self.gc.allocator, false) catch unreachable; - defer self.gc.allocator.free(callee_type_str); - self.reporter.reportErrorFmt( - .not_mutable, - self.ast.tokens.get(locations[components.subscripted]), - self.ast.tokens.get(end_locations[components.subscripted]), - "`{s}` not mutable", - .{ - callee_type_str, - }, - ); - } - - if (!subscripted_type_def.resolved_type.?.Map.value_type.eql(value_type_def.?)) { - self.reporter.reportTypeCheck( - .subscript_value_type, - self.ast.tokens.get(locations[components.subscripted]), - self.ast.tokens.get(end_locations[components.subscripted]), - subscripted_type_def.resolved_type.?.Map.value_type, - self.ast.tokens.get(locations[value]), - self.ast.tokens.get(end_locations[value]), - value_type_def.?, - "Bad value type", - ); - } - } - get_code = .OP_GET_MAP_SUBSCRIPT; set_code = .OP_SET_MAP_SUBSCRIPT; }, - else => self.reporter.reportErrorAt( - .subscriptable, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - "Not subscriptable.", - ), + else => {}, } _ = try self.generateNode(components.index, breaks); @@ -4336,42 +2725,38 @@ fn generateThrow(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*ob } const expression_type_def = type_defs[components.expression].?; - if (expression_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, expression_type_def.resolved_type.?.Placeholder); - } else { - const current_error_types = self.current.?.function.?.type_def.resolved_type.?.Function.error_types; - - var found_match = false; - if (current_error_types != null) { - for (current_error_types.?) |error_type| { - if (error_type.eql(expression_type_def)) { - found_match = true; - break; - } + const current_error_types = self.current.?.function.?.type_def.resolved_type.?.Function.error_types; + + var found_match = false; + if (current_error_types != null) { + for (current_error_types.?) |error_type| { + if (error_type.eql(expression_type_def)) { + found_match = true; + break; } } + } - if (!found_match) { - if (self.current.?.try_should_handle != null) { - // In a try catch remember to check that we handle that error when finishing parsing the try-catch - try self.current.?.try_should_handle.?.put( - self.gc.allocator, - expression_type_def, - location, - ); - } else { - // Not in a try-catch and function signature does not expect this error type - const error_str = try type_defs[components.expression].?.toStringAlloc(self.gc.allocator, false); - defer self.gc.allocator.free(error_str); + if (!found_match) { + if (self.current.?.try_should_handle != null) { + // In a try catch remember to check that we handle that error when finishing parsing the try-catch + try self.current.?.try_should_handle.?.put( + self.gc.allocator, + expression_type_def, + location, + ); + } else { + // Not in a try-catch and function signature does not expect this error type + const error_str = try type_defs[components.expression].?.toStringAlloc(self.gc.allocator, false); + defer self.gc.allocator.free(error_str); - self.reporter.reportErrorFmt( - .unexpected_error_type, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - "Error type `{s}` not expected", - .{error_str}, - ); - } + self.reporter.reportErrorFmt( + .unexpected_error_type, + self.ast.tokens.get(location), + self.ast.tokens.get(end_locations[node]), + "Error type `{s}` not expected", + .{error_str}, + ); } } @@ -4414,66 +2799,17 @@ fn generateTypeOfExpression(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) fn generateUnary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const components = self.ast.nodes.items(.components)[node].Unary; const location = self.ast.nodes.items(.location)[node]; - const end_locations = self.ast.nodes.items(.end_location); - const expression_location = self.ast.nodes.items(.location)[components.expression]; const expression_type_def = self.ast.nodes.items(.type_def)[components.expression].?; - if (expression_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, expression_type_def.resolved_type.?.Placeholder); - - return null; - } - _ = try self.generateNode(components.expression, breaks); switch (components.operator) { - .Bnot => { - if (expression_type_def.def_type != .Integer) { - self.reporter.reportErrorFmt( - .bitwise_operand_type, - self.ast.tokens.get(expression_location), - self.ast.tokens.get(end_locations[components.expression]), - "Expected type `int`, got `{s}`", - .{ - try expression_type_def.toStringAlloc(self.gc.allocator, false), - }, - ); - } - - try self.OP_BNOT(location); - }, - .Bang => { - if (expression_type_def.def_type != .Bool) { - self.reporter.reportErrorFmt( - .bitwise_operand_type, - self.ast.tokens.get(expression_location), - self.ast.tokens.get(end_locations[components.expression]), - "Expected type `bool`, got `{s}`", - .{ - try expression_type_def.toStringAlloc(self.gc.allocator, false), - }, - ); - } - - try self.OP_NOT(location); - }, - .Minus => { - if (expression_type_def.def_type == .Integer) { - try self.OP_NEGATE_I(location); - } else if (expression_type_def.def_type == .Double) { - try self.OP_NEGATE_F(location); - } else { - self.reporter.reportErrorFmt( - .arithmetic_operand_type, - self.ast.tokens.get(expression_location), - self.ast.tokens.get(end_locations[components.expression]), - "Expected type `int` or `double`, got `{s}`", - .{ - try expression_type_def.toStringAlloc(self.gc.allocator, false), - }, - ); - } - }, + .Bnot => try self.OP_BNOT(location), + .Bang => try self.OP_NOT(location), + .Minus => if (expression_type_def.def_type == .Integer) + try self.OP_NEGATE_I(location) + else if (expression_type_def.def_type == .Double) + try self.OP_NEGATE_F(location), else => unreachable, } @@ -4485,25 +2821,9 @@ fn generateUnary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*ob fn generateUnwrap(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const location = locations[node]; const components = self.ast.nodes.items(.components)[node].Unwrap; - if (components.original_type.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, components.original_type.resolved_type.?.Placeholder); - - return null; - } - - if (!components.original_type.optional) { - self.reporter.reportErrorAt( - .optional, - self.ast.tokens.get(locations[components.unwrapped]), - self.ast.tokens.get(end_locations[components.unwrapped]), - "Not an optional", - ); - } - _ = try self.generateNode(components.unwrapped, breaks); try self.OP_COPY(location, 0); @@ -4531,37 +2851,11 @@ fn generateUnwrap(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o fn generateVarDeclaration(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const components = self.ast.nodes.items(.components)[node].VarDeclaration; - const type_defs = self.ast.nodes.items(.type_def); - const type_def = type_defs[node].?; - const value_type_def = if (components.value) |value| - self.ast.nodes.items(.type_def)[value] - else - null; const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const location = locations[node]; if (components.value) |value| { _ = try self.generateNode(value, breaks); - - if (value_type_def.?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, value_type_def.?.resolved_type.?.Placeholder); - } else if (type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_def.resolved_type.?.Placeholder); - } else if (!(try type_def.toInstance(&self.gc.type_registry, type_def.isMutable())).eql(value_type_def.?) and - !(try (try type_def.toInstance(&self.gc.type_registry, type_def.isMutable())).cloneNonOptional(&self.gc.type_registry)).eql(value_type_def.?)) - { - self.reporter.reportTypeCheck( - .assignment_value_type, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - try type_def.toInstance(&self.gc.type_registry, type_def.isMutable()), - self.ast.tokens.get(locations[value]), - self.ast.tokens.get(end_locations[value]), - value_type_def.?, - "Wrong variable type", - ); - } } else { try self.OP_NULL(location); } @@ -4599,14 +2893,15 @@ fn generateVoid(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjF fn generateWhile(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const components = self.ast.nodes.items(.components)[node].While; - const type_defs = self.ast.nodes.items(.type_def); const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const location = locations[node]; - const condition_type_def = type_defs[components.condition].?; // If condition constant and false, skip the node - if (try self.ast.isConstant(self.gc.allocator, components.condition) and !(try self.ast.toValue(components.condition, self.gc)).boolean()) { + if (try self.ast.isConstant(self.gc.allocator, components.condition) and !(try self.ast.toValue( + components.condition, + &self.reporter, + self.gc, + )).boolean()) { try self.patchOptJumps(node); try self.endScope(node); @@ -4618,19 +2913,6 @@ fn generateWhile(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*ob const jit_jump = if (!is_wasm) try self.emitJump(locations[node], .OP_HOTSPOT) else {}; if (!is_wasm) try self.emit(locations[node], node); - if (condition_type_def.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, condition_type_def.resolved_type.?.Placeholder); - } - - if (condition_type_def.def_type != .Bool) { - self.reporter.reportErrorAt( - .while_condition_type, - self.ast.tokens.get(locations[components.condition]), - self.ast.tokens.get(end_locations[components.condition]), - "`while` condition must be bool", - ); - } - _ = try self.generateNode(components.condition, breaks); const exit_jump = try self.OP_JUMP_IF_FALSE(location); @@ -4664,52 +2946,9 @@ fn generateWhile(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*ob fn generateYield(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const expression = self.ast.nodes.items(.components)[node].Yield; - const type_defs = self.ast.nodes.items(.type_def); - const type_def = type_defs[node]; const locations = self.ast.nodes.items(.location); - const end_locations = self.ast.nodes.items(.end_location); const location = locations[node]; - const current_function_typedef = type_defs[self.current.?.function_node].?.resolved_type.?.Function; - const current_function_type = current_function_typedef.function_type; - switch (current_function_type) { - .Script, - .ScriptEntryPoint, - .Repl, - .EntryPoint, - .Test, - .Extern, - => self.reporter.reportErrorAt( - .yield_not_allowed, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - "Can't yield here", - ), - else => {}, - } - - if (type_def == null) { - self.reporter.reportErrorAt( - .unknown, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - "Unknown type.", - ); - } else if (type_def.?.def_type == .Placeholder) { - self.reporter.reportPlaceholder(self.ast, type_def.?.resolved_type.?.Placeholder); - } else if (!self.current.?.function.?.type_def.resolved_type.?.Function.yield_type.eql(type_def.?)) { - self.reporter.reportTypeCheck( - .yield_type, - self.ast.tokens.get(locations[self.current.?.function_node]), - self.ast.tokens.get(end_locations[self.current.?.function_node]), - self.current.?.function.?.type_def.resolved_type.?.Function.yield_type, - self.ast.tokens.get(location), - self.ast.tokens.get(end_locations[node]), - type_def.?, - "Bad yield value", - ); - } - _ = try self.generateNode(expression, breaks); try self.OP_YIELD(location); @@ -4772,30 +3011,6 @@ fn generateZdef(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjF return null; } -pub fn populateEmptyCollectionType(self: *Self, value: Ast.Node.Index, target_type: *obj.ObjTypeDef) void { - const tags = self.ast.nodes.items(.tag); - const components = self.ast.nodes.items(.components); - - // variable: [T] = [] -> variable: [T] = []; - if (target_type.def_type == .List and - tags[value] == .List and - components[value].List.explicit_item_type == null and - components[value].List.items.len == 0) - { - self.ast.nodes.items(.type_def)[value] = target_type; - } - - // variable: {K: V} = {} -> variable: {K: V} = []; - if (target_type.def_type == .Map and - tags[value] == .Map and - components[value].Map.explicit_key_type == null and - components[value].Map.explicit_value_type == null and - components[value].Map.entries.len == 0) - { - self.ast.nodes.items(.type_def)[value] = target_type; - } -} - fn OP_DBG_LOCAL_ENTER(self: *Self, location: Ast.TokenIndex, slot: u8, name: Value) !void { // Don't emit those if we are not debugging if (!self.debugging) return; diff --git a/src/Jit.zig b/src/Jit.zig index 4c2653d3..6ead6827 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -468,7 +468,7 @@ fn generateNode(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { const components = self.state.?.ast.nodes.items(.components); const tag = self.state.?.ast.nodes.items(.tag)[node]; const constant = self.state.?.ast.nodes.items(.value)[node] orelse if (try self.state.?.ast.isConstant(self.vm.gc.allocator, node)) - try self.state.?.ast.toValue(node, self.vm.gc) + try self.state.?.ast.toValue(node, &self.vm.reporter, self.vm.gc) else null; diff --git a/src/Parser.zig b/src/Parser.zig index 99820503..7e8224e3 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -3416,7 +3416,7 @@ fn parseFunctionType(self: *Self, parent_generic_types: ?std.AutoArrayHashMapUnm }, ); if (if (default) |dflt| - try self.ast.slice().toValue(dflt, self.gc) + try self.ast.slice().toValue(dflt, &self.reporter, self.gc) else if (arg_type_def.?.optional) Value.Null else @@ -6335,7 +6335,7 @@ fn function( try function_typedef.resolved_type.?.Function.defaults.put( self.gc.allocator, try self.gc.copyString(self.ast.tokens.items(.lexeme)[local.name]), - try self.ast.slice().toValue(dft, self.gc), + try self.ast.slice().toValue(dft, &self.reporter, self.gc), ); } @@ -8270,7 +8270,7 @@ fn enumDeclaration(self: *Self) Error!Ast.Node.Index { try obj_cases.append( self.gc.allocator, if (case.value) |case_value| - try self.ast.slice().toValue(case_value, self.gc) + try self.ast.slice().toValue(case_value, &self.reporter, self.gc) else if (enum_type.def_type == .Integer) Value.fromInteger(@intCast(idx)) else if (enum_type.def_type == .String) diff --git a/src/Reporter.zig b/src/Reporter.zig index 156f19ec..bf4ea78f 100644 --- a/src/Reporter.zig +++ b/src/Reporter.zig @@ -134,6 +134,7 @@ pub const Error = enum(u8) { mutable_forbidden = 101, unassigned_final_local = 102, source_not_utf8 = 103, + default_value_type = 104, }; // Inspired by https://github.com/zesterer/ariadne @@ -553,6 +554,8 @@ pub const Report = struct { }; pub fn warn(self: *Self, error_type: Error, location: Token, end_location: Token, message: []const u8) void { + const previous_error = self.last_error; + const items = [_]ReportItem{ .{ .kind = .warning, @@ -581,6 +584,10 @@ pub fn warn(self: *Self, error_type: Error, location: Token, end_location: Token }; error_report.reportStderr(self) catch @panic("Unable to report error"); + + // last_error is often used to know if an error occurred and stop codegen at some points, + // we don't want that behavior after a warning + self.last_error = previous_error; } pub fn report(self: *Self, error_type: Error, location: Token, end_location: Token, message: []const u8) void { diff --git a/src/TypeChecker.zig b/src/TypeChecker.zig new file mode 100644 index 00000000..59cb9260 --- /dev/null +++ b/src/TypeChecker.zig @@ -0,0 +1,2304 @@ +const std = @import("std"); +const o = @import("obj.zig"); +const Reporter = @import("Reporter.zig"); +const Ast = @import("Ast.zig"); +const GC = @import("GC.zig"); +const BuildOptions = @import("build_options"); +const io = @import("io.zig"); + +const NodeCheck = *const fn ( + ast: Ast.Slice, + reporter: *Reporter, + gc: *GC, + current_function_node: ?Ast.Node.Index, + node: Ast.Node.Index, +) error{OutOfMemory}!bool; + +const checkers = [_]?NodeCheck{ + null, // AnonymousObjectType, + null, // As, + null, // AsyncCall, + checkBinary, // Binary, + null, // Block, + null, // BlockExpression, + null, // Boolean, + null, // Break, + checkCall, // Call, + null, // Continue, + checkDot, // Dot, + checkDoUntil, // DoUntil, + checkEnum, // Enum, + null, // Export, + null, // Expression, + null, // FiberType, + null, // Double, + checkFor, // For, + checkForceUnwrap, // ForceUnwrap, + checkForEach, // ForEach, + checkFunction, // Function, + null, // FunctionType, + null, // FunDeclaration, + checkGenericResolve, // GenericResolve, + null, // GenericResolveType, + null, // GenericType, + null, // Grouping, + checkIf, // If, + null, // Import, + null, // Integer, + null, // Is, + checkList, // List, + null, // ListType, + checkMap, // Map, + null, // MapType, + null, // Namespace, + checkNamedVariable, // NamedVariable, + null, // Null, + checkObjectDeclaration, // ObjectDeclaration, + checkObjectInit, // ObjectInit, + null, // Out, + null, // Pattern, + null, // ProtocolDeclaration, + checkRange, // Range, + checkResolve, // Resolve, + checkResume, // Resume, + checkReturn, // Return, + null, // SimpleType, + null, // String, + null, // StringLiteral, + checkSubscript, // Subscript, + null, // Throw, + null, // Try, + null, // TypeExpression, + null, // TypeOfExpression, + checkUnary, // Unary, + checkUnwrap, // Unwrap, + null, // UserType, + checkVarDeclaration, // VarDeclaration, + null, // Void, + checkWhile, // While, + checkYield, // Yield, + null, // Zdef, +}; + +/// Typecheck the node (but does not typecheck its leaf) +pub fn check(ast: Ast.Slice, reporter: *Reporter, gc: *GC, current_function_node: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + return if (checkers[@intFromEnum(ast.nodes.items(.tag)[node])]) |checker| + try checker(ast, reporter, gc, current_function_node, node) + else + false; +} + +pub fn populateEmptyCollectionType(ast: Ast.Slice, value: Ast.Node.Index, target_type: *o.ObjTypeDef) void { + const tags = ast.nodes.items(.tag); + const components = ast.nodes.items(.components); + + // variable: [T] = [] -> variable: [T] = []; + if (target_type.def_type == .List and + tags[value] == .List and + components[value].List.explicit_item_type == null and + components[value].List.items.len == 0) + { + ast.nodes.items(.type_def)[value] = target_type; + } + + // variable: {K: V} = {} -> variable: {K: V} = []; + if (target_type.def_type == .Map and + tags[value] == .Map and + components[value].Map.explicit_key_type == null and + components[value].Map.explicit_value_type == null and + components[value].Map.entries.len == 0) + { + ast.nodes.items(.type_def)[value] = target_type; + } +} + +fn checkBinary(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const type_defs = ast.nodes.items(.type_def); + const components = ast.nodes.items(.components); + const node_components = components[node]; + const locations = ast.nodes.items(.location); + const node_location = locations[node]; + const end_locations = ast.nodes.items(.end_location); + const node_end_location = end_locations[node]; + const left_type = type_defs[node_components.Binary.left] orelse gc.type_registry.any_type; + const right_type = type_defs[node_components.Binary.right] orelse gc.type_registry.any_type; + + var had_error = false; + + switch (node_components.Binary.operator) { + .QuestionQuestion, + .Ampersand, + .Bor, + .Xor, + .ShiftLeft, + .ShiftRight, + .Plus, + .Minus, + .Star, + .Slash, + .Percent, + .And, + .Or, + => { + if (!left_type.eql(right_type)) { + reporter.reportTypeCheck( + .binary_operand_type, + ast.tokens.get(locations[node_components.Binary.left]), + ast.tokens.get(end_locations[node_components.Binary.left]), + left_type, + ast.tokens.get(locations[node_components.Binary.right]), + ast.tokens.get(end_locations[node_components.Binary.right]), + right_type, + "Type mismatch", + ); + } + + had_error = true; + }, + + .Greater, + .Less, + .GreaterEqual, + .LessEqual, + .BangEqual, + .EqualEqual, + => { + // We allow comparison between double and int so raise error if type != and one operand is not a number + if (!left_type.eql(right_type) and + !right_type.eql(left_type) and + ((left_type.def_type != .Integer and left_type.def_type != .Double) or + (right_type.def_type != .Integer and right_type.def_type != .Double))) + { + reporter.reportTypeCheck( + .comparison_operand_type, + ast.tokens.get(locations[node_components.Binary.left]), + ast.tokens.get(end_locations[node_components.Binary.left]), + left_type, + ast.tokens.get(locations[node_components.Binary.right]), + ast.tokens.get(end_locations[node_components.Binary.right]), + right_type, + "Type mismatch", + ); + + had_error = true; + } + }, + + else => { + reporter.reportErrorAt( + .syntax, + ast.tokens.get(node_location), + ast.tokens.get(node_end_location), + "Unexpected binary operator.", + ); + + std.debug.print(">> {s}\n", .{@tagName(node_components.Binary.operator)}); + + had_error = true; + }, + } + + if (node_components.Binary.operator != .QuestionQuestion and + node_components.Binary.operator != .EqualEqual and + node_components.Binary.operator != .BangEqual) + { + if (left_type.optional) { + reporter.reportErrorAt( + .binary_operand_type, + ast.tokens.get(locations[node_components.Binary.left]), + ast.tokens.get(end_locations[node_components.Binary.left]), + "Binary operand can't be optional", + ); + + had_error = true; + } + + if (right_type.optional) { + reporter.reportErrorAt( + .binary_operand_type, + ast.tokens.get(locations[node_components.Binary.right]), + ast.tokens.get(end_locations[node_components.Binary.right]), + "Binary operand can't be optional", + ); + + had_error = true; + } + } + + switch (node_components.Binary.operator) { + .EqualEqual, .BangEqual => {}, + .QuestionQuestion => if (!left_type.optional) { + reporter.reportErrorAt( + .optional, + ast.tokens.get(locations[node_components.Binary.left]), + ast.tokens.get(end_locations[node_components.Binary.left]), + "Not an optional", + ); + had_error = true; + }, + .Ampersand, + .Bor, + .Xor, + .ShiftLeft, + .ShiftRight, + => { + if (left_type.def_type != .Integer) { + reporter.reportErrorAt( + .bitwise_operand_type, + ast.tokens.get(locations[node_components.Binary.left]), + ast.tokens.get(end_locations[node_components.Binary.left]), + "Expected `int`.", + ); + } + had_error = true; + }, + .Greater, + .Less, + .GreaterEqual, + .LessEqual, + .Minus, + .Star, + .Slash, + .Percent, + => { + if (left_type.def_type != .Integer and left_type.def_type != .Double) { + reporter.reportErrorAt( + .comparison_operand_type, + ast.tokens.get(locations[node_components.Binary.left]), + ast.tokens.get(end_locations[node_components.Binary.left]), + "Expected `int` or `double`.", + ); + had_error = true; + } + }, + .Plus => { + if (left_type.def_type != .Integer and + left_type.def_type != .Double and + left_type.def_type != .String and + left_type.def_type != .List and + left_type.def_type != .Map) + { + reporter.reportErrorAt( + .arithmetic_operand_type, + ast.tokens.get(locations[node_components.Binary.left]), + ast.tokens.get(end_locations[node_components.Binary.left]), + "Expected a `int`, `double`, `str`, list or map.", + ); + had_error = true; + } + }, + .And, + .Or, + => { + if (left_type.def_type != .Bool) { + reporter.reportErrorAt( + .logical_operand_type, + ast.tokens.get(locations[node_components.Binary.left]), + ast.tokens.get(end_locations[node_components.Binary.left]), + "`and` expects operands to be `bool`", + ); + had_error = true; + } + }, + else => { + reporter.reportErrorAt( + .syntax, + ast.tokens.get(node_location), + ast.tokens.get(node_end_location), + "Unexpected binary operator.", + ); + std.debug.print(">> {s}\n", .{@tagName(node_components.Binary.operator)}); + + had_error = true; + }, + } + + return had_error; +} + +fn checkCall(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const type_defs = ast.nodes.items(.type_def); + const node_components = ast.nodes.items(.components); + const components = node_components[node].Call; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const lexemes = ast.tokens.items(.lexeme); + + var had_error = false; + + const callee_type_def = type_defs[components.callee].?; + + // This is not a call but an Enum(value) + if (callee_type_def.def_type == .Enum) { + if (components.is_async) { + reporter.reportErrorAt( + .fiber_call_not_allowed, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + "Can't be wrapped in a fiber", + ); + had_error = true; + } + + if (components.catch_default != null) { + reporter.reportErrorAt( + .no_error, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + "Doesn't raise any error", + ); + had_error = true; + } + + if (components.arguments.len != 1) { + reporter.reportErrorAt( + .enum_argument, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + "Enum instanciation requires only value argument", + ); + had_error = true; + } + + return had_error; + } + + // Find out if call is invoke or regular call + var invoked = false; + var invoked_on: ?o.ObjTypeDef.Type = null; + + if (ast.nodes.items(.tag)[components.callee] == .Dot) { + const dot = node_components[components.callee].Dot; + const field_accessed = type_defs[dot.callee].?; + + if (field_accessed.def_type == .Placeholder) { + reporter.reportPlaceholder(ast, field_accessed.resolved_type.?.Placeholder); + had_error = true; + } + + invoked = field_accessed.def_type != .Object; + invoked_on = field_accessed.def_type; + } + + const callee_type = switch (ast.nodes.items(.tag)[components.callee]) { + .Dot => node_components[components.callee].Dot.member_type_def, + else => type_defs[components.callee], + }; + + if (callee_type == null) { + reporter.reportErrorAt( + .undefined, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + "Callee is not defined", + ); + + had_error = true; + } else if (callee_type.?.def_type != .Function) { + reporter.reportErrorAt( + .callable, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + "Can't be called", + ); + + had_error = true; + + // return null; + } else if (callee_type.?.optional) { + reporter.reportErrorAt( + .callable, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + "Function maybe null and can't be called", + ); + + had_error = true; + } + + // Arguments + const args = callee_type.?.resolved_type.?.Function.parameters; + const defaults = callee_type.?.resolved_type.?.Function.defaults; + const arg_keys = args.keys(); + const arg_count = arg_keys.len; + + var missing_arguments = std.StringArrayHashMapUnmanaged(usize).empty; + defer missing_arguments.deinit(gc.allocator); + for (arg_keys, 0..) |arg_name, pindex| { + try missing_arguments.put( + gc.allocator, + arg_name.string, + pindex, + ); + } + + if (components.arguments.len > arg_count) { + reporter.reportErrorAt( + .call_arguments, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + "Too many arguments.", + ); + had_error = true; + } + + for (components.arguments, 0..) |argument, index| { + if (index >= arg_count) { + break; + } + + var argument_type_def = type_defs[argument.value].?; + const arg_key = if (argument.name) |arg_name| + gc.copyString(lexemes[arg_name]) catch return error.OutOfMemory + else + null; + const actual_arg_key = if (index == 0 and arg_key == null) + arg_keys[0] + else + arg_key.?; + const def_arg_type = args.get(actual_arg_key); + + if (def_arg_type) |arg_type| { + populateEmptyCollectionType(ast, argument.value, arg_type); + argument_type_def = type_defs[argument.value].?; + + if (!arg_type.eql(argument_type_def)) { + reporter.reportTypeCheck( + .call_argument_type, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + arg_type, + ast.tokens.get(locations[argument.value]), + ast.tokens.get(end_locations[argument.value]), + argument_type_def, + "Bad argument type", + ); + had_error = true; + } + + _ = missing_arguments.orderedRemove(actual_arg_key.string); + } else { + reporter.reportErrorFmt( + .call_arguments, + ast.tokens.get(locations[argument.value]), + ast.tokens.get(end_locations[argument.value]), + "Argument `{s}` does not exists.", + .{if (arg_key) |key| key.string else "unknown"}, + ); + had_error = true; + } + } + + // Default arguments + if (missing_arguments.count() > 0) { + var tmp_missing_arguments = try missing_arguments.clone(gc.allocator); + defer tmp_missing_arguments.deinit(gc.allocator); + const missing_keys = tmp_missing_arguments.keys(); + for (missing_keys) |missing_key| { + if (defaults.get(gc.copyString(missing_key) catch return error.OutOfMemory) != null) { + _ = missing_arguments.orderedRemove(missing_key); + } + } + } + + // Not enough arguments? + if (missing_arguments.count() > 0) { + var missing = std.Io.Writer.Allocating.init(gc.allocator); + defer missing.deinit(); + + for (missing_arguments.keys(), 0..) |key, i| { + missing.writer.print( + "{s}{s}", + .{ + key, + if (i < missing_arguments.keys().len - 1) + ", " + else + "", + }, + ) catch return error.OutOfMemory; + } + + reporter.reportErrorFmt( + .call_arguments, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + "Missing argument{s}: {s}", + .{ + if (missing_arguments.count() > 1) + "s" + else + "", + missing.written(), + }, + ); + + had_error = true; + } + + // Catch clause + const error_types = callee_type.?.resolved_type.?.Function.error_types; + if (components.catch_default) |catch_default| { + const catch_default_type_def = type_defs[catch_default].?; + if (error_types == null or error_types.?.len == 0) { + reporter.reportErrorAt( + .no_error, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + "Function doesn't raise any error", + ); + had_error = true; + } else if (error_types != null) { + const node_type_def = type_defs[node].?; + // Expression + if (!node_type_def.eql(catch_default_type_def) and + !(node_type_def.cloneOptional(&gc.type_registry) catch return error.OutOfMemory) + .eql(catch_default_type_def)) + { + reporter.reportTypeCheck( + .inline_catch_type, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + node_type_def, + ast.tokens.get(locations[catch_default]), + ast.tokens.get(end_locations[catch_default]), + catch_default_type_def, + "Bad inline catch value type", + ); + had_error = true; + } + } + } + + return had_error; +} + +fn checkDot(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const type_defs = ast.nodes.items(.type_def); + const node_components = ast.nodes.items(.components); + const components = node_components[node].Dot; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const tags = ast.tokens.items(.tag); + + var had_error = false; + + const callee_type = type_defs[components.callee] orelse gc.type_registry.any_type; + + switch (callee_type.def_type) { + .ObjectInstance, + .Object, + .ProtocolInstance, + .Enum, + .EnumInstance, + .List, + .Map, + .String, + .Pattern, + .Fiber, + .ForeignContainer, + .Range, + => {}, + else => { + reporter.reportErrorAt( + .field_access, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + "Doesn't have field access", + ); + had_error = true; + }, + } + + if (callee_type.optional) { + reporter.reportErrorAt( + .field_access, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + "Optional doesn't have field access", + ); + } + + switch (callee_type.def_type) { + .Fiber, .Pattern, .String => {}, + .ForeignContainer, .ObjectInstance, .Object => { + const field_name = ast.tokens.items(.lexeme)[components.identifier]; + const field = switch (callee_type.def_type) { + .ObjectInstance => callee_type.resolved_type.?.ObjectInstance.of + .resolved_type.?.Object + .fields + .get(field_name), + .Object => callee_type.resolved_type.?.Object.fields + .get(field_name), + else => null, + }; + + switch (components.member_kind) { + .Value => { + const value = components.value_or_call_or_enum.Value.value; + const assign_token = components.value_or_call_or_enum.Value.assign_token; + var value_type_def = type_defs[value].?; + + // Type check value + switch (callee_type.def_type) { + .ForeignContainer => { + const field_type = callee_type.resolved_type.?.ForeignContainer.buzz_type.get(field_name).?; + + if (!field_type.eql(value_type_def)) { + reporter.reportTypeCheck( + .assignment_value_type, + ast.tokens.get(callee_type.resolved_type.?.ForeignContainer.location), + ast.tokens.get(callee_type.resolved_type.?.ForeignContainer.location), + field_type, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + value_type_def, + "Bad property type", + ); + had_error = true; + } + }, + .ObjectInstance, .Object => { + if (field.?.method or + (callee_type.def_type == .ObjectInstance and field.?.static) or + (callee_type.def_type == .Object and !field.?.static)) + { + reporter.reportErrorFmt( + .assignable, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + "`{s}` is not assignable", + .{ + field_name, + }, + ); + had_error = true; + } else if (field.?.final) { + reporter.reportErrorFmt( + .constant_property, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + "`{s}` is final", + .{ + field_name, + }, + ); + had_error = true; + } else if (callee_type.def_type == .ObjectInstance and !callee_type.resolved_type.?.ObjectInstance.mutable) { + reporter.reportWithOrigin( + .not_mutable, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + ast.tokens.get( + callee_type.resolved_type.?.ObjectInstance.of + .resolved_type.?.Object.location, + ), + ast.tokens.get( + callee_type.resolved_type.?.ObjectInstance.of + .resolved_type.?.Object.location, + ), + "Instance of `{s}` is not mutable", + .{ + callee_type.resolved_type.?.ObjectInstance.of + .resolved_type.?.Object.qualified_name.string, + }, + "declared here", + ); + had_error = true; + } + + populateEmptyCollectionType(ast, value, field.?.type_def); + value_type_def = type_defs[value].?; + + if (!field.?.type_def.eql(value_type_def)) { + reporter.reportTypeCheck( + .assignment_value_type, + ast.tokens.get(field.?.location), + ast.tokens.get(field.?.location), + field.?.type_def, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + value_type_def, + "Bad property type", + ); + had_error = true; + } + }, + else => { + reporter.reportErrorAt( + .syntax, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + "Callee is not field accessible", + ); + had_error = true; + }, + } + + // Type check that operator is allowed + switch (tags[assign_token]) { + .PlusEqual => switch (type_defs[value].?.def_type) { + .Integer, + .Double, + .List, + .Map, + .String, + => {}, + else => { + reporter.report( + .arithmetic_operand_type, + ast.tokens.get(assign_token), + ast.tokens.get(assign_token), + "Addition is only allowed for types `int`, `double`, list, map and `str`", + ); + had_error = true; + }, + }, + .MinusEqual, + .StarEqual, + .SlashEqual, + .PercentEqual, + => switch (type_defs[value].?.def_type) { + .Integer, .Double => {}, + else => { + reporter.report( + .arithmetic_operand_type, + ast.tokens.get(assign_token), + ast.tokens.get(assign_token), + "Operator is only allowed for types `int`, `double`", + ); + had_error = true; + }, + }, + .ShiftRightEqual, + .ShiftLeftEqual, + .XorEqual, + .BorEqual, + .BnotEqual, + .AmpersandEqual, + => if (type_defs[value].?.def_type != .Integer) { + reporter.report( + .arithmetic_operand_type, + ast.tokens.get(assign_token), + ast.tokens.get(assign_token), + "Operator is only allowed for `int`", + ); + had_error = true; + }, + else => {}, + } + }, + .Call => { + if (callee_type.def_type == .ForeignContainer) { + reporter.reportErrorAt( + .callable, + ast.tokens.get(locations[components.callee]), + ast.tokens.get(end_locations[components.callee]), + "Not callable", + ); + had_error = true; + } + + if (field.?.mutable and !callee_type.resolved_type.?.ObjectInstance.mutable) { + reporter.report( + .not_mutable, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Method requires mutable instance", + ); + had_error = true; + } + }, + else => {}, + } + }, + .ProtocolInstance => if (components.member_kind == .Call) { + const field_name = ast.tokens.items(.lexeme)[components.identifier]; + const field = callee_type.resolved_type.?.ProtocolInstance.of + .resolved_type.?.Protocol + .methods + .get(field_name); + + if (field.?.mutable and !callee_type.resolved_type.?.ProtocolInstance.mutable) { + reporter.report( + .not_mutable, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Method requires mutable instance", + ); + + had_error = true; + } + }, + .Enum => {}, + .EnumInstance => {}, + .List, .Map, .Range => if (components.member_kind == .Call) { + const identifier = ast.tokens.items(.lexeme)[components.identifier]; + + switch (callee_type.def_type) { + .List => if (callee_type.resolved_type.?.List.methods.get(identifier).?.mutable and + !callee_type.resolved_type.?.List.mutable) + { + reporter.reportErrorFmt( + .not_mutable, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Method `{s}` requires mutable list", + .{ + identifier, + }, + ); + had_error = true; + }, + .Map => if (callee_type.resolved_type.?.Map.methods.get(identifier).?.mutable and + !callee_type.resolved_type.?.Map.mutable) + { + reporter.reportErrorFmt( + .not_mutable, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Method `{s}` requires mutable list", + .{ + identifier, + }, + ); + had_error = true; + }, + else => {}, + } + }, + else => std.debug.assert(had_error == true), + } + + return had_error; +} + +fn checkDoUntil(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const type_defs = ast.nodes.items(.type_def); + const node_components = ast.nodes.items(.components); + const components = node_components[node].DoUntil; + + const condition_type_def = type_defs[components.condition] orelse gc.type_registry.any_type; + + if (condition_type_def.def_type != .Bool) { + reporter.reportErrorAt( + .do_condition_type, + ast.tokens.get(locations[components.condition]), + ast.tokens.get(end_locations[components.condition]), + "`do` condition must be bool", + ); + + return true; + } + + return false; +} + +fn checkEnum(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const type_defs = ast.nodes.items(.type_def); + const node_components = ast.nodes.items(.components); + const components = node_components[node].Enum; + + var had_error = false; + + const enum_type = type_defs[node].?.resolved_type.?.Enum.enum_type; + + switch (enum_type.def_type) { + .String, + .Integer, + .Double, + .Pattern, + .UserData, + .Void, + .Range, + => {}, + else => { + reporter.reportErrorAt( + .syntax, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + "Type not allowed as enum value", + ); + had_error = true; + }, + } + + for (components.cases) |case| { + const case_type_def = if (case.value) |value| + type_defs[value].? + else + null; + + if (case_type_def) |case_type| { + if (!((enum_type.toInstance(&gc.type_registry, false) catch return error.OutOfMemory)).eql(case_type)) { + reporter.reportTypeCheck( + .enum_case_type, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + (enum_type.toInstance( + &gc.type_registry, + false, + ) catch return error.OutOfMemory), + ast.tokens.get(locations[case.value.?]), + ast.tokens.get(end_locations[case.value.?]), + case_type, + "Bad enum case type", + ); + + had_error = true; + } + } + } + + return had_error; +} + +fn checkFor(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const type_defs = ast.nodes.items(.type_def); + const node_components = ast.nodes.items(.components); + const components = node_components[node].For; + + const condition_type_def = type_defs[components.condition] orelse gc.type_registry.any_type; + if (condition_type_def.def_type != .Bool) { + reporter.reportErrorAt( + .for_condition_type, + ast.tokens.get(locations[components.condition]), + ast.tokens.get(end_locations[components.condition]), + "`for` condition must be bool", + ); + + return false; + } + + return true; +} + +fn checkForceUnwrap(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const components = ast.nodes.items(.components)[node].ForceUnwrap; + + if (!components.original_type.optional) { + reporter.reportErrorAt( + .optional, + ast.tokens.get(locations[components.unwrapped]), + ast.tokens.get(end_locations[components.unwrapped]), + "Not an optional", + ); + + return false; + } + + return true; +} + +fn checkForEach(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const node_components = ast.nodes.items(.components); + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const type_defs = ast.nodes.items(.type_def); + const components = node_components[node].ForEach; + + var had_error = false; + + const iterable_type_def = type_defs[components.iterable] orelse gc.type_registry.any_type; + var key_type_def = type_defs[components.key] orelse gc.type_registry.any_type; + const value_type_def = type_defs[components.value] orelse gc.type_registry.any_type; + + if (!components.key_omitted) { + switch (iterable_type_def.def_type) { + .String, .List => { + if (key_type_def.def_type != .Integer) { + reporter.reportErrorAt( + .foreach_key_type, + ast.tokens.get(locations[components.key]), + ast.tokens.get(end_locations[components.key]), + "Expected `int`.", + ); + had_error = true; + } + }, + .Map => { + if (!iterable_type_def.resolved_type.?.Map.key_type.strictEql(key_type_def)) { + reporter.reportTypeCheck( + .foreach_key_type, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + iterable_type_def.resolved_type.?.Map.key_type, + ast.tokens.get(locations[components.key]), + ast.tokens.get(end_locations[components.key]), + key_type_def, + "Bad key type", + ); + had_error = true; + } + }, + .Enum => { + reporter.reportErrorAt( + .foreach_key_type, + ast.tokens.get(locations[components.key]), + ast.tokens.get(end_locations[components.key]), + "No key available when iterating over enum.", + ); + had_error = true; + }, + .Range => { + reporter.reportErrorAt( + .foreach_key_type, + ast.tokens.get(locations[components.key]), + ast.tokens.get(end_locations[components.key]), + "No key available when iterating over range.", + ); + had_error = true; + }, + else => { + reporter.reportErrorAt( + .foreach_iterable, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + "Not iterable.", + ); + had_error = true; + }, + } + } else { + // Key was omitted, put the correct type in the key var declation to avoid raising errors + switch (iterable_type_def.def_type) { + .Map => key_type_def = iterable_type_def.resolved_type.?.Map.key_type, + .String, .List => key_type_def = gc.type_registry.int_type, + else => {}, + } + } + + switch (iterable_type_def.def_type) { + .Map => { + if (!iterable_type_def.resolved_type.?.Map.value_type.strictEql(value_type_def)) { + reporter.reportTypeCheck( + .foreach_value_type, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + iterable_type_def.resolved_type.?.Map.value_type, + ast.tokens.get(locations[components.value]), + ast.tokens.get(end_locations[components.value]), + value_type_def, + "Bad value type", + ); + had_error = true; + } + }, + .List => { + if (!iterable_type_def.resolved_type.?.List.item_type.strictEql(value_type_def)) { + reporter.reportTypeCheck( + .foreach_value_type, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + iterable_type_def.resolved_type.?.List.item_type, + ast.tokens.get(locations[components.value]), + ast.tokens.get(end_locations[components.value]), + value_type_def, + "Bad value type", + ); + had_error = true; + } + }, + .Range => { + if (value_type_def.def_type != .Integer or value_type_def.optional) { + reporter.reportTypeCheck( + .foreach_value_type, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + gc.type_registry.int_type, + ast.tokens.get(locations[components.value]), + ast.tokens.get(end_locations[components.value]), + value_type_def, + "Bad value type", + ); + had_error = true; + } + }, + .String => { + if (value_type_def.def_type != .String) { + reporter.reportTypeCheck( + .foreach_value_type, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + gc.type_registry.str_type, + ast.tokens.get(locations[components.value]), + ast.tokens.get(end_locations[components.value]), + value_type_def, + "Bad value type", + ); + had_error = true; + } + }, + .Enum => { + const iterable_type = iterable_type_def.toInstance( + &gc.type_registry, + false, + ) catch return error.OutOfMemory; + if (!iterable_type.strictEql(value_type_def)) { + reporter.reportTypeCheck( + .foreach_value_type, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + iterable_type, + ast.tokens.get(locations[components.value]), + ast.tokens.get(end_locations[components.value]), + value_type_def, + "Bad value type", + ); + had_error = true; + } + }, + .Fiber => { + const iterable_type = iterable_type_def.resolved_type.?.Fiber.yield_type.toInstance( + &gc.type_registry, + false, + ) catch return error.OutOfMemory; + if (!iterable_type.strictEql(value_type_def)) { + reporter.reportTypeCheck( + .foreach_value_type, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + iterable_type, + ast.tokens.get(locations[components.value]), + ast.tokens.get(end_locations[components.value]), + value_type_def, + "Bad value type", + ); + had_error = true; + } + }, + else => { + reporter.reportErrorAt( + .foreach_iterable, + ast.tokens.get(locations[components.iterable]), + ast.tokens.get(end_locations[components.iterable]), + "Not iterable.", + ); + had_error = true; + }, + } + + return had_error; +} + +fn checkFunction(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const node_components = ast.nodes.items(.components); + const type_defs = ast.nodes.items(.type_def); + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const components = node_components[node].Function; + const node_type_def = type_defs[node].?; + const function_def = node_type_def.resolved_type.?.Function; + const function_signature = if (components.function_signature) |fs| + node_components[fs].FunctionType + else + null; + + var had_error = false; + + // Default values type checking + var it = function_def.defaults.iterator(); + while (it.next()) |kv| { + if (function_def.parameters.get(kv.key_ptr.*)) |param| { + const default_type_def = kv.value_ptr.*.typeOf(gc) catch return error.OutOfMemory; + if (!param.eql(default_type_def)) { + // Retrieve default node + var argument: ?Ast.FunctionType.Argument = null; + if (function_signature) |signature| { + for (signature.arguments) |arg| { + const name = ast.tokens.items(.lexeme)[arg.name]; + if (std.mem.eql(u8, name, kv.key_ptr.*.string)) { + argument = arg; + } + } + } + + reporter.reportTypeCheck( + .default_value_type, + ast.tokens.get( + locations[if (argument) |arg| arg.type else node], + ), + ast.tokens.get( + end_locations[if (argument) |arg| arg.type else node], + ), + param, + ast.tokens.get( + locations[if (argument) |arg| arg.default orelse node else node], + ), + ast.tokens.get( + end_locations[if (argument) |arg| arg.default orelse node else node], + ), + default_type_def, + "Bad default value type", + ); + had_error = true; + } + } + } + + return had_error; +} + +fn checkGenericResolve(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const type_def = ast.nodes.items(.type_def)[node].?; + const node_location = ast.nodes.items(.location)[node]; + const node_end_location = ast.nodes.items(.end_location)[node]; + + var had_error = false; + + switch (type_def.def_type) { + .Function => { + const function_type = type_def.resolved_type.?.Function; + + if (function_type.generic_types.count() > 0 and + (function_type.resolved_generics == null or function_type.resolved_generics.?.len < function_type.generic_types.count())) + { + reporter.reportErrorFmt( + .generic_type, + ast.tokens.get(node_location), + ast.tokens.get(node_end_location), + "Missing generic types. Expected {} got {}.", + .{ + function_type.generic_types.count(), + if (function_type.resolved_generics == null) + 0 + else + function_type.resolved_generics.?.len, + }, + ); + had_error = true; + } else if (function_type.resolved_generics != null and function_type.resolved_generics.?.len > function_type.generic_types.count()) { + reporter.reportErrorFmt( + .generic_type, + ast.tokens.get(node_location), + ast.tokens.get(node_end_location), + "Too many generic types. Expected {} got {}.", + .{ + function_type.generic_types.count(), + if (function_type.resolved_generics == null) + 0 + else + function_type.resolved_generics.?.len, + }, + ); + had_error = true; + } + }, + .Object => { + const object_type = type_def.resolved_type.?.Object; + + if (object_type.generic_types.count() > 0 and + (object_type.resolved_generics == null or object_type.resolved_generics.?.len < object_type.generic_types.count())) + { + reporter.reportErrorFmt( + .generic_type, + ast.tokens.get(node_location), + ast.tokens.get(node_end_location), + "Missing generic types. Expected {} got {}.", + .{ + object_type.generic_types.count(), + if (object_type.resolved_generics == null) + 0 + else + object_type.resolved_generics.?.len, + }, + ); + had_error = true; + } else if (object_type.resolved_generics != null and object_type.resolved_generics.?.len > object_type.generic_types.count()) { + reporter.reportErrorFmt( + .generic_type, + ast.tokens.get(node_location), + ast.tokens.get(node_end_location), + "Too many generic types. Expected {} got {}.", + .{ + object_type.generic_types.count(), + if (object_type.resolved_generics == null) + 0 + else + object_type.resolved_generics.?.len, + }, + ); + had_error = true; + } + }, + else => { + const type_def_str = type_def.toStringAlloc(gc.allocator, false) catch unreachable; + defer gc.allocator.free(type_def_str); + + reporter.reportErrorFmt( + .generic_type, + ast.tokens.get(node_location), + ast.tokens.get(node_end_location), + "Type `{s}` does not support generic types", + .{ + type_def_str, + }, + ); + had_error = true; + }, + } + + return had_error; +} + +fn checkIf(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const type_defs = ast.nodes.items(.type_def); + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const node_components = ast.nodes.items(.components); + const components = node_components[node].If; + const location = locations[node]; + + var had_error = false; + + if (!components.is_statement) { + // Both should have same type + if (!type_defs[node].?.eql(type_defs[components.body].?)) { + reporter.reportTypeCheck( + .inline_if_body_type, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + type_defs[node].?, + ast.tokens.get(locations[components.body]), + ast.tokens.get(end_locations[components.body]), + type_defs[components.body].?, + "Inline if body type not matching", + ); + had_error = true; + } + + if (!type_defs[node].?.eql(type_defs[components.else_branch.?].?)) { + reporter.reportTypeCheck( + .inline_if_else_type, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + type_defs[node].?, + ast.tokens.get(locations[components.else_branch.?]), + ast.tokens.get(end_locations[components.else_branch.?]), + type_defs[components.else_branch.?].?, + "Inline if else type not matching", + ); + had_error = true; + } + } + + if (components.casted_type == null and components.unwrapped_identifier == null) { + if (type_defs[components.condition].?.def_type != .Bool) { + reporter.reportErrorAt( + .if_condition_type, + ast.tokens.get(locations[components.condition]), + ast.tokens.get(end_locations[components.condition]), + "`if` condition must be bool", + ); + had_error = true; + } + } else if (components.casted_type == null) { + if (!type_defs[components.condition].?.optional) { + reporter.reportErrorAt( + .optional, + ast.tokens.get(locations[components.condition]), + ast.tokens.get(end_locations[components.condition]), + "Expected optional", + ); + had_error = true; + } + } + + return had_error; +} + +fn checkList(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const components = ast.nodes.items(.components)[node].List; + const type_defs = ast.nodes.items(.type_def); + const item_type = type_defs[node].?.resolved_type.?.List.item_type; + + var had_error = false; + + for (components.items) |item| { + if (item_type.def_type == .Placeholder) { + reporter.reportPlaceholder(ast, type_defs[item].?.resolved_type.?.Placeholder); + } else if (!item_type.eql(type_defs[item].?)) { + reporter.reportTypeCheck( + .list_item_type, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + item_type, + ast.tokens.get(locations[item]), + ast.tokens.get(end_locations[item]), + type_defs[item].?, + "Bad list type", + ); + had_error = true; + } + } + + return had_error; +} + +fn checkMap(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const components = ast.nodes.items(.components)[node].Map; + const type_defs = ast.nodes.items(.type_def); + + const key_type = if (components.explicit_key_type) |kt| + type_defs[kt] + else + null; + + const value_type = if (components.explicit_value_type) |vt| + type_defs[vt] + else + null; + + var had_error = false; + + for (components.entries) |entry| { + if (key_type != null and !key_type.?.eql(type_defs[entry.key].?)) { + reporter.reportTypeCheck( + .map_key_type, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + key_type.?, + ast.tokens.get(locations[entry.key]), + ast.tokens.get(end_locations[entry.key]), + type_defs[entry.key].?, + "Bad key type", + ); + had_error = true; + } + + if (value_type != null and !value_type.?.eql(type_defs[entry.value].?)) { + reporter.reportTypeCheck( + .map_value_type, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + value_type.?, + ast.tokens.get(locations[entry.value]), + ast.tokens.get(end_locations[entry.value]), + type_defs[entry.value].?, + "Bad value type", + ); + had_error = true; + } + } + + return had_error; +} + +fn checkNamedVariable(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const components = ast.nodes.items(.components)[node].NamedVariable; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const type_defs = ast.nodes.items(.type_def); + const tags = ast.tokens.items(.tag); + + var had_error = false; + + if (components.value) |value| { + if (!type_defs[node].?.eql(type_defs[value].?)) { + reporter.reportTypeCheck( + .assignment_value_type, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + type_defs[node].?, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + type_defs[value].?, + "Bad value type", + ); + had_error = true; + } + + // Type check that operator is allowed + switch (tags[components.assign_token.?]) { + .PlusEqual => switch (type_defs[node].?.def_type) { + .Integer, + .Double, + .List, + .Map, + .String, + => {}, + else => { + reporter.report( + .arithmetic_operand_type, + ast.tokens.get(components.assign_token.?), + ast.tokens.get(components.assign_token.?), + "Addition is only allowed for types `int`, `double`, list, map and `str`", + ); + had_error = true; + }, + }, + .MinusEqual, + .StarEqual, + .SlashEqual, + .PercentEqual, + => switch (type_defs[node].?.def_type) { + .Integer, .Double => {}, + else => { + reporter.report( + .arithmetic_operand_type, + ast.tokens.get(components.assign_token.?), + ast.tokens.get(components.assign_token.?), + "Operator is only allowed for types `int`, `double`", + ); + had_error = true; + }, + }, + .ShiftRightEqual, + .ShiftLeftEqual, + .XorEqual, + .BorEqual, + .BnotEqual, + .AmpersandEqual, + => if (type_defs[node].?.def_type != .Integer) { + reporter.report( + .arithmetic_operand_type, + ast.tokens.get(components.assign_token.?), + ast.tokens.get(components.assign_token.?), + "Operator is only allowed for `int`", + ); + had_error = true; + }, + else => {}, + } + } + + return had_error; +} + +fn checkObjectDeclaration(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const type_defs = ast.nodes.items(.type_def); + const lexemes = ast.tokens.items(.lexeme); + const components = ast.nodes.items(.components)[node].ObjectDeclaration; + const location = locations[node]; + + const object_type = type_defs[node].?; + const object_def = object_type.resolved_type.?.Object; + + var had_error = false; + + // Check object conforms to declared protocols + var protocol_it = object_def.conforms_to.iterator(); + while (protocol_it.next()) |kv| { + const protocol_type_def = kv.key_ptr.*; + + const protocol_def = protocol_type_def.resolved_type.?.Protocol; + + var method_it = protocol_def.methods.iterator(); + while (method_it.next()) |mkv| { + var found = false; + for (components.members) |member| { + if (member.method and std.mem.eql(u8, ast.tokens.items(.lexeme)[member.name], mkv.key_ptr.*)) { + found = true; + if (!mkv.value_ptr.*.type_def.eql(type_defs[member.method_or_default_value.?].?) or + mkv.value_ptr.*.mutable != object_def.fields.get(mkv.key_ptr.*).?.mutable) + { + reporter.reportTypeCheck( + .protocol_conforming, + ast.tokens.get(protocol_def.location), + ast.tokens.get(protocol_def.location), + mkv.value_ptr.*.type_def, + ast.tokens.get(locations[member.method_or_default_value.?]), + ast.tokens.get(end_locations[member.method_or_default_value.?]), + type_defs[member.method_or_default_value.?].?, + "Method not conforming to protocol", + ); + had_error = true; + } + break; + } + } + + if (!found) { + reporter.reportWithOrigin( + .protocol_conforming, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + ast.tokens.get( + protocol_def.methods_locations.get( + mkv.value_ptr.*.type_def.resolved_type.?.Function.name.string, + ).?, + ), + ast.tokens.get( + protocol_def.methods_locations.get( + mkv.value_ptr.*.type_def.resolved_type.?.Function.name.string, + ).?, + ), + "Object declared as conforming to protocol `{s}` but doesn't implement method `{s}`", + .{ + protocol_def.name.string, + mkv.value_ptr.*.type_def.resolved_type.?.Function.name.string, + }, + null, + ); + had_error = true; + } + } + } + + for (components.members) |member| { + const member_name = lexemes[member.name]; + + if (member.method) { + // Method + const member_field = object_def.fields.get(member_name).?; + const member_type_def = member_field.type_def; + + // Enforce "collect" method signature + if (std.mem.eql(u8, member_name, "collect")) { + const collect_def = member_type_def.resolved_type.?.Function; + + if (collect_def.parameters.count() > 0 or + collect_def.return_type.def_type != .Void or + collect_def.yield_type.def_type != .Void or + collect_def.error_types != null) + { + const collect_def_str = member_type_def.toStringAlloc(gc.allocator, false) catch @panic("Out of memory"); + defer gc.allocator.free(collect_def_str); + reporter.reportErrorFmt( + .collect_signature, + ast.tokens.get(locations[member.method_or_default_value.?]), + ast.tokens.get(end_locations[member.method_or_default_value.?]), + "Expected `collect` method to be `fun collect() > void` got {s}", + .{ + collect_def_str, + }, + ); + had_error = true; + } + } else if (std.mem.eql(u8, member_name, "toString")) { // Enforce "toString" method signature + const tostring_def = member_type_def.resolved_type.?.Function; + + if (tostring_def.parameters.count() > 0 or + tostring_def.return_type.def_type != .String or + tostring_def.yield_type.def_type != .Void or + tostring_def.error_types != null or + tostring_def.generic_types.count() > 0) + { + const tostring_def_str = member_type_def.toStringAlloc(gc.allocator, false) catch @panic("Out of memory"); + defer gc.allocator.free(tostring_def_str); + reporter.reportErrorFmt( + .tostring_signature, + ast.tokens.get(locations[member.method_or_default_value.?]), + ast.tokens.get(end_locations[member.method_or_default_value.?]), + "Expected `toString` method to be `fun toString() > str` got {s}", + .{ + tostring_def_str, + }, + ); + had_error = true; + } + } + } else { + // Property + const property_field = object_def.fields.get(member_name).?; + const property_type = property_field.type_def; + + // Create property default value + if (member.method_or_default_value) |default| { + populateEmptyCollectionType(ast, default, property_type); + const default_type_def = type_defs[default].?; + + if (!property_type.eql(default_type_def)) { + reporter.reportTypeCheck( + .property_default_value, + ast.tokens.get(object_def.location), + ast.tokens.get(object_def.location), + property_type, + ast.tokens.get(locations[default]), + ast.tokens.get(end_locations[default]), + default_type_def, + "Wrong property default value type", + ); + had_error = true; + } + } + } + } + + return had_error; +} + +fn checkObjectInit(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const type_defs = ast.nodes.items(.type_def); + const lexemes = ast.tokens.items(.lexeme); + const components = ast.nodes.items(.components)[node].ObjectInit; + const location = locations[node]; + const node_type_def = type_defs[node].?; + + var had_error = false; + + if (node_type_def.def_type != .ObjectInstance and node_type_def.def_type != .ForeignContainer) { + reporter.reportErrorAt( + .expected_object, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + "Expected object or foreign struct.", + ); + + had_error = true; + } + + var fields = if (node_type_def.def_type == .ObjectInstance) inst: { + const fields = node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.fields; + var fields_type_defs = std.StringArrayHashMapUnmanaged(*o.ObjTypeDef).empty; + var it = fields.iterator(); + while (it.next()) |kv| { + try fields_type_defs.put( + gc.allocator, + kv.value_ptr.*.name, + kv.value_ptr.*.type_def, + ); + } + break :inst fields_type_defs; + } else node_type_def.resolved_type.?.ForeignContainer.buzz_type; + + defer if (node_type_def.def_type == .ObjectInstance) { + fields.deinit(gc.allocator); + }; + + const object_location = if (node_type_def.def_type == .ObjectInstance) + node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.location + else + node_type_def.resolved_type.?.ForeignContainer.location; + + // Keep track of what's been initialized or not by this statement + var init_properties = std.StringHashMapUnmanaged(void).empty; + defer init_properties.deinit(gc.allocator); + + for (components.properties) |property| { + const property_name = lexemes[property.name]; + if (fields.get(property_name)) |prop| { + populateEmptyCollectionType(ast, property.value, prop); + const value_type_def = type_defs[property.value].?; + + if (!prop.eql(value_type_def)) { + if (BuildOptions.debug_placeholders) { + io.print( + "prop {}({}), value {}({})\n", + .{ + @intFromPtr(prop.resolved_type.?.ObjectInstance.of), + prop.optional, + @intFromPtr(value_type_def.resolved_type.?.ObjectInstance.of), + value_type_def.optional, + }, + ); + } + + const err_location = ast.tokens.get( + if (node_type_def.def_type == .ObjectInstance) + node_type_def.resolved_type.?.ObjectInstance.of + .resolved_type.?.Object.fields.get(property_name).?.location + else + object_location, + ); + + reporter.reportTypeCheck( + .property_type, + err_location, + err_location, + prop, + ast.tokens.get(locations[property.value]), + ast.tokens.get(end_locations[property.value]), + value_type_def, + "Wrong property type", + ); + had_error = true; + } + + try init_properties.put(gc.allocator, property_name, {}); + } else { + reporter.reportWithOrigin( + .property_does_not_exists, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + ast.tokens.get(object_location), + ast.tokens.get(object_location), + "Property `{s}` does not exists", + .{property_name}, + null, + ); + had_error = true; + } + } + + // Did we initialized all properties without a default value? + // If union we're statisfied with only on field initialized + if (node_type_def.def_type != .ForeignContainer or node_type_def.resolved_type.?.ForeignContainer.zig_type != .Union or init_properties.count() == 0) { + const field_defs = if (node_type_def.def_type == .ObjectInstance) + node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.fields + else + null; + + var it = fields.iterator(); + while (it.next()) |kv| { + const field = if (field_defs) |fd| fd.get(kv.key_ptr.*) else null; + // If ommitted in initialization and doesn't have default value + if (init_properties.get(kv.key_ptr.*) == null and + (field == null or (!field.?.has_default and !field.?.method and !field.?.static))) + { + reporter.reportErrorFmt( + .property_not_initialized, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + "Property `{s}` was not initialized and has no default value", + .{kv.key_ptr.*}, + ); + had_error = true; + } + } + } + + return had_error; +} + +fn checkRange(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const type_defs = ast.nodes.items(.type_def); + const components = ast.nodes.items(.components)[node].Range; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + + var had_error = false; + + if (type_defs[components.low].?.def_type != .Integer) { + reporter.reportTypeCheck( + .range_type, + null, + null, + gc.type_registry.int_type, + ast.tokens.get(locations[components.low]), + ast.tokens.get(end_locations[components.low]), + type_defs[components.low].?, + "Bad low range limit type", + ); + had_error = true; + } + + if (type_defs[components.high].?.def_type != .Integer) { + reporter.reportTypeCheck( + .range_type, + null, + null, + gc.type_registry.int_type, + ast.tokens.get(locations[components.high]), + ast.tokens.get(end_locations[components.high]), + type_defs[components.high].?, + "Bad high range limit type", + ); + had_error = true; + } + + return had_error; +} + +fn checkResolve(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const fiber = ast.nodes.items(.components)[node].Resolve; + const fiber_type_def = ast.nodes.items(.type_def)[fiber].?; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + + if (fiber_type_def.def_type != .Fiber) { + reporter.reportErrorAt( + .fiber, + ast.tokens.get(locations[fiber]), + ast.tokens.get(end_locations[fiber]), + "Not a fiber", + ); + + return false; + } + + return true; +} + +fn checkResume(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const fiber = ast.nodes.items(.components)[node].Resume; + const fiber_type_def = ast.nodes.items(.type_def)[fiber].?; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + + if (fiber_type_def.def_type != .Fiber) { + reporter.reportErrorAt( + .fiber, + ast.tokens.get(locations[fiber]), + ast.tokens.get(end_locations[fiber]), + "Not a fiber", + ); + + return false; + } + + return true; +} + +fn checkReturn(ast: Ast.Slice, reporter: *Reporter, gc: *GC, current_function_node: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const components = ast.nodes.items(.components)[node].Return; + const type_defs = ast.nodes.items(.type_def); + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const current_function_type_def = type_defs[current_function_node.?].?.resolved_type.?.Function; + + var had_error = false; + + if (components.value) |value| { + const value_type_def = type_defs[value]; + if (value_type_def == null) { + reporter.reportErrorAt( + .undefined, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + "Unknown type.", + ); + had_error = true; + } else if (current_function_node != null and !current_function_type_def.return_type.eql(value_type_def.?)) { + reporter.reportTypeCheck( + .return_type, + ast.tokens.get(locations[current_function_node.?]), + ast.tokens.get(end_locations[current_function_node.?]), + current_function_type_def.return_type, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + value_type_def.?, + "Return value", + ); + had_error = true; + } + } else if (current_function_node != null and current_function_type_def.return_type.def_type != .Void) { + reporter.reportTypeCheck( + .return_type, + ast.tokens.get(locations[current_function_node.?]), + ast.tokens.get(end_locations[current_function_node.?]), + current_function_type_def.return_type, + ast.tokens.get(locations[node]), + ast.tokens.get(end_locations[node]), + gc.type_registry.void_type, + "Return value", + ); + had_error = true; + } + + return had_error; +} + +fn checkSubscript(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const location = locations[node]; + const type_defs = ast.nodes.items(.type_def); + const components = ast.nodes.items(.components)[node].Subscript; + + const subscripted_type_def = type_defs[components.subscripted].?; + const index_type_def = type_defs[components.index].?; + const value_type_def = if (components.value) |value| type_defs[value] else null; + + var had_error = false; + + switch (subscripted_type_def.def_type) { + .String => if (index_type_def.def_type != .Integer) { + reporter.reportErrorAt( + .subscript_key_type, + ast.tokens.get(locations[components.index]), + ast.tokens.get(end_locations[components.index]), + "Expected `int` index.", + ); + had_error = true; + }, + .List => { + if (index_type_def.def_type != .Integer) { + reporter.reportErrorAt( + .subscript_key_type, + ast.tokens.get(locations[components.index]), + ast.tokens.get(end_locations[components.index]), + "Expected `int` index.", + ); + had_error = true; + } + + if (components.value) |value| { + if (!type_defs[components.subscripted].?.isMutable()) { + const callee_type_str = type_defs[components.subscripted].?.toStringAlloc(gc.allocator, false) catch unreachable; + defer gc.allocator.free(callee_type_str); + reporter.reportErrorFmt( + .not_mutable, + ast.tokens.get(locations[components.subscripted]), + ast.tokens.get(end_locations[components.subscripted]), + "`{s}` not mutable", + .{ + callee_type_str, + }, + ); + had_error = true; + } + + if (!subscripted_type_def.resolved_type.?.List.item_type.eql(value_type_def.?)) { + reporter.reportTypeCheck( + .subscript_value_type, + ast.tokens.get(locations[components.subscripted]), + ast.tokens.get(end_locations[components.subscripted]), + subscripted_type_def.resolved_type.?.List.item_type, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + value_type_def.?, + "Bad value type", + ); + had_error = true; + } + } + }, + .Map => { + if (!subscripted_type_def.resolved_type.?.Map.key_type.eql(index_type_def)) { + reporter.reportTypeCheck( + .subscript_key_type, + ast.tokens.get(locations[components.subscripted]), + ast.tokens.get(end_locations[components.subscripted]), + subscripted_type_def.resolved_type.?.Map.key_type, + ast.tokens.get(locations[components.index]), + ast.tokens.get(end_locations[components.index]), + index_type_def, + "Bad key type", + ); + had_error = true; + } + + if (components.value) |value| { + if (!type_defs[components.subscripted].?.isMutable()) { + const callee_type_str = type_defs[components.subscripted].?.toStringAlloc(gc.allocator, false) catch unreachable; + defer gc.allocator.free(callee_type_str); + reporter.reportErrorFmt( + .not_mutable, + ast.tokens.get(locations[components.subscripted]), + ast.tokens.get(end_locations[components.subscripted]), + "`{s}` not mutable", + .{ + callee_type_str, + }, + ); + had_error = true; + } + + if (!subscripted_type_def.resolved_type.?.Map.value_type.eql(value_type_def.?)) { + reporter.reportTypeCheck( + .subscript_value_type, + ast.tokens.get(locations[components.subscripted]), + ast.tokens.get(end_locations[components.subscripted]), + subscripted_type_def.resolved_type.?.Map.value_type, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + value_type_def.?, + "Bad value type", + ); + had_error = true; + } + } + }, + else => { + reporter.reportErrorAt( + .subscriptable, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + "Not subscriptable.", + ); + had_error = true; + }, + } + + return had_error; +} + +fn checkUnary(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const components = ast.nodes.items(.components)[node].Unary; + const end_locations = ast.nodes.items(.end_location); + const expression_location = ast.nodes.items(.location)[components.expression]; + const expression_type_def = ast.nodes.items(.type_def)[components.expression].?; + + var had_error = false; + + switch (components.operator) { + .Bnot => if (expression_type_def.def_type != .Integer) { + reporter.reportErrorFmt( + .bitwise_operand_type, + ast.tokens.get(expression_location), + ast.tokens.get(end_locations[components.expression]), + "Expected type `int`, got `{s}`", + .{ + expression_type_def.toStringAlloc(gc.allocator, false) catch return error.OutOfMemory, + }, + ); + had_error = true; + }, + .Bang => if (expression_type_def.def_type != .Bool) { + reporter.reportErrorFmt( + .bitwise_operand_type, + ast.tokens.get(expression_location), + ast.tokens.get(end_locations[components.expression]), + "Expected type `bool`, got `{s}`", + .{ + expression_type_def.toStringAlloc(gc.allocator, false) catch return error.OutOfMemory, + }, + ); + had_error = true; + }, + .Minus => if (expression_type_def.def_type != .Integer and expression_type_def.def_type != .Double) { + reporter.reportErrorFmt( + .arithmetic_operand_type, + ast.tokens.get(expression_location), + ast.tokens.get(end_locations[components.expression]), + "Expected type `int` or `double`, got `{s}`", + .{ + expression_type_def.toStringAlloc(gc.allocator, false) catch return error.OutOfMemory, + }, + ); + had_error = true; + }, + else => unreachable, + } + + return had_error; +} + +fn checkUnwrap(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const components = ast.nodes.items(.components)[node].Unwrap; + + if (!components.original_type.optional) { + reporter.reportErrorAt( + .optional, + ast.tokens.get(locations[components.unwrapped]), + ast.tokens.get(end_locations[components.unwrapped]), + "Not an optional", + ); + + return true; + } + + return false; +} + +fn checkVarDeclaration(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const components = ast.nodes.items(.components)[node].VarDeclaration; + const type_defs = ast.nodes.items(.type_def); + const type_def = type_defs[node].?; + const value_type_def = if (components.value) |value| + ast.nodes.items(.type_def)[value] + else + null; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const location = locations[node]; + + if (components.value) |value| { + if (!(type_def.toInstance(&gc.type_registry, type_def.isMutable()) catch return error.OutOfMemory) + .eql(value_type_def.?) and + !((type_def.toInstance(&gc.type_registry, type_def.isMutable()) catch return error.OutOfMemory) + .cloneNonOptional(&gc.type_registry) catch return error.OutOfMemory) + .eql(value_type_def.?)) + { + reporter.reportTypeCheck( + .assignment_value_type, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + type_def.toInstance(&gc.type_registry, type_def.isMutable()) catch return error.OutOfMemory, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + value_type_def.?, + "Wrong variable type", + ); + + return true; + } + } + + return false; +} + +fn checkWhile(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const components = ast.nodes.items(.components)[node].While; + const type_defs = ast.nodes.items(.type_def); + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const condition_type_def = type_defs[components.condition].?; + + if (condition_type_def.def_type != .Bool) { + reporter.reportErrorAt( + .while_condition_type, + ast.tokens.get(locations[components.condition]), + ast.tokens.get(end_locations[components.condition]), + "`while` condition must be bool", + ); + + return true; + } + + return false; +} + +fn checkYield(ast: Ast.Slice, reporter: *Reporter, _: *GC, current_function_node: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const type_defs = ast.nodes.items(.type_def); + const type_def = type_defs[node]; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + const location = locations[node]; + + var had_error = false; + + const current_function_typedef = type_defs[current_function_node.?].?.resolved_type.?.Function; + const current_function_type = current_function_typedef.function_type; + switch (current_function_type) { + .Script, + .ScriptEntryPoint, + .Repl, + .EntryPoint, + .Test, + .Extern, + => { + reporter.reportErrorAt( + .yield_not_allowed, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + "Can't yield here", + ); + had_error = true; + }, + else => {}, + } + + if (type_def == null) { + reporter.reportErrorAt( + .unknown, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + "Unknown type.", + ); + had_error = true; + } else if (!current_function_typedef.yield_type.eql(type_def.?)) { + reporter.reportTypeCheck( + .yield_type, + ast.tokens.get(locations[current_function_node.?]), + ast.tokens.get(end_locations[current_function_node.?]), + current_function_typedef.yield_type, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + type_def.?, + "Bad yield value", + ); + had_error = true; + } + + return had_error; +} diff --git a/src/TypeRegistry.zig b/src/TypeRegistry.zig index 7756d9b6..1bc9ca3c 100644 --- a/src/TypeRegistry.zig +++ b/src/TypeRegistry.zig @@ -29,6 +29,7 @@ any_type: *o.ObjTypeDef, pat_type: *o.ObjTypeDef, ud_type: *o.ObjTypeDef, rg_type: *o.ObjTypeDef, +type_type: *o.ObjTypeDef, pub fn init(gc: *GC) !TypeRegistry { var self = TypeRegistry{ @@ -42,6 +43,7 @@ pub fn init(gc: *GC) !TypeRegistry { .pat_type = undefined, .ud_type = undefined, .rg_type = undefined, + .type_type = undefined, }; self.void_type = try self.getTypeDef(.{ .def_type = .Void }); @@ -60,6 +62,7 @@ pub fn init(gc: *GC) !TypeRegistry { self.pat_type = try self.getTypeDef(.{ .def_type = .Pattern }); self.ud_type = try self.getTypeDef(.{ .def_type = .UserData }); self.rg_type = try self.getTypeDef(.{ .def_type = .Range }); + self.type_type = try self.getTypeDef(.{ .def_type = .Type }); return self; } diff --git a/tests/behavior/035-const-expr.buzz b/tests/behavior/035-const-expr.buzz index 390dc749..7357d04c 100644 --- a/tests/behavior/035-const-expr.buzz +++ b/tests/behavior/035-const-expr.buzz @@ -1,8 +1,8 @@ import "std"; fun hello( - name: mut [str] = [ "John", "Doe" ], - address: mut {str: str} = { + name: mut [str] = mut [ "John", "Doe" ], + address: mut {str: str} = mut { "street": "somewhere street", "town": "New York", }, From 1256d4d75b8650ec82b160a95ebebf270e025692 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 5 Nov 2025 15:31:30 +0100 Subject: [PATCH 05/17] fix: Fixed final report color --- src/Parser.zig | 2 +- src/behavior.zig | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Parser.zig b/src/Parser.zig index 7e8224e3..43dd76a0 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -1223,7 +1223,7 @@ fn endFrame(self: *Self) Ast.Node.Index { .unassigned_final_local, location, location, - "Local `{s}` is declared `var` but is never assigned", + "Local `{s}` is declared `var` but is never re-assigned", .{ self.ast.tokens.items(.lexeme)[local.name], }, diff --git a/src/behavior.zig b/src/behavior.zig index 1baf29f0..ceaf48dc 100644 --- a/src/behavior.zig +++ b/src/behavior.zig @@ -430,9 +430,9 @@ pub fn main() !u8 { } if (result.hasFailed()) { - io.print("\n\u{001b}[32m", .{}); - } else { io.print("\n\u{001b}[31m", .{}); + } else { + io.print("\n\u{001b}[32m", .{}); } io.print("Ran {}, Ok: {}, Failed: {}, Hanged {}, Skipped {}\u{001b}[0m\n", .{ From 14152d2cc5c93e74a79c3cdcd244aba9452465fa Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 6 Nov 2025 15:14:59 +0100 Subject: [PATCH 06/17] fix(pattern): pattern.replaceAll was missusing offsets --- src/Codegen.zig | 33 +++++++++++-------- src/Parser.zig | 11 ++++--- src/builtin/pattern.zig | 27 ++++++++++----- tests/{ => behavior}/022-io.buzz | 0 tests/{ => behavior}/024-os.buzz | 0 tests/{ => behavior}/027-run-file.buzz | 0 tests/{ => behavior}/031-json.buzz | 0 .../{ => behavior}/049-multiline-strings.buzz | 0 tests/{ => behavior}/058-ffi.buzz | 0 tests/{ => behavior}/068-testing.buzz | 0 ...,time:3034101,execs:29776,op:flip1,pos:379 | 29 ---------------- ...,time:3036220,execs:29779,op:flip1,pos:379 | 29 ---------------- ...,time:3038341,execs:29782,op:flip1,pos:379 | 29 ---------------- ...,time:3155723,execs:30217,op:flip2,pos:379 | 29 ---------------- ...08,time:3919860,execs:33298,op:havoc,rep:1 | 27 --------------- 15 files changed, 45 insertions(+), 169 deletions(-) rename tests/{ => behavior}/022-io.buzz (100%) rename tests/{ => behavior}/024-os.buzz (100%) rename tests/{ => behavior}/027-run-file.buzz (100%) rename tests/{ => behavior}/031-json.buzz (100%) rename tests/{ => behavior}/049-multiline-strings.buzz (100%) rename tests/{ => behavior}/058-ffi.buzz (100%) rename tests/{ => behavior}/068-testing.buzz (100%) delete mode 100644 tests/fuzzed/id:000014,src:000008,time:3034101,execs:29776,op:flip1,pos:379 delete mode 100644 tests/fuzzed/id:000015,src:000008,time:3036220,execs:29779,op:flip1,pos:379 delete mode 100644 tests/fuzzed/id:000016,src:000008,time:3038341,execs:29782,op:flip1,pos:379 delete mode 100644 tests/fuzzed/id:000017,src:000008,time:3155723,execs:30217,op:flip2,pos:379 delete mode 100644 tests/fuzzed/id:000019,src:000008,time:3919860,execs:33298,op:havoc,rep:1 diff --git a/src/Codegen.zig b/src/Codegen.zig index c7053f42..b778756a 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -1584,22 +1584,29 @@ fn generateForEach(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?* // If iterable constant and empty, skip the node if (try self.ast.isConstant(self.gc.allocator, components.iterable)) { - const iterable = (try self.ast.toValue( + const iterable_value = (try self.ast.toValue( components.iterable, &self.reporter, self.gc, - )).obj(); - - if (switch (iterable.obj_type) { - .List => obj.ObjList.cast(iterable).?.items.items.len == 0, - .Map => obj.ObjMap.cast(iterable).?.map.count() == 0, - .String => obj.ObjString.cast(iterable).?.string.len == 0, - .Enum => obj.ObjEnum.cast(iterable).?.cases.len == 0, - .Range => obj.ObjRange.cast(iterable).?.high == obj.ObjRange.cast(iterable).?.low, - else => self.reporter.last_error != null, - }) { - try self.patchOptJumps(node); - return null; + )); + + const iterable_obj = if (iterable_value.isObj()) + iterable_value.obj() + else + null; + + if (iterable_obj) |iterable| { + if (switch (iterable.obj_type) { + .List => obj.ObjList.cast(iterable).?.items.items.len == 0, + .Map => obj.ObjMap.cast(iterable).?.map.count() == 0, + .String => obj.ObjString.cast(iterable).?.string.len == 0, + .Enum => obj.ObjEnum.cast(iterable).?.cases.len == 0, + .Range => obj.ObjRange.cast(iterable).?.high == obj.ObjRange.cast(iterable).?.low, + else => self.reporter.last_error != null, + }) { + try self.patchOptJumps(node); + return null; + } } } diff --git a/src/Parser.zig b/src/Parser.zig index 43dd76a0..2d68231a 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -4875,10 +4875,10 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind .Dot = .{ .callee = callee, .identifier = member_name_token, - .value_or_call_or_enum = undefined, + .value_or_call_or_enum = .{ .Ref = {} }, .generic_resolve = null, .member_type_def = undefined, - .member_kind = undefined, + .member_kind = .Ref, }, }, }, @@ -10070,8 +10070,11 @@ fn returnStatement(self: *Self) Error!Ast.Node.Index { if (self.ast.nodes.items(.tag)[uvalue] == .Call) { self.ast.nodes.items(.components)[uvalue].Call.tail_call = true; - } else if (self.ast.nodes.items(.tag)[uvalue] == .Dot and self.ast.nodes.items(.components)[uvalue].Dot.member_kind == .Call) { - self.ast.nodes.items(.components)[self.ast.nodes.items(.components)[uvalue].Dot.value_or_call_or_enum.Call].Call.tail_call = true; + } else if (self.ast.nodes.items(.tag)[uvalue] == .Dot and self.ast.nodes.items(.components)[uvalue].Dot.value_or_call_or_enum == .Call) { + self.ast.nodes.items(.components)[ + self.ast.nodes.items(.components)[uvalue] + .Dot.value_or_call_or_enum.Call + ].Call.tail_call = true; } } diff --git a/src/builtin/pattern.zig b/src/builtin/pattern.zig index a4f88901..56227c3b 100644 --- a/src/builtin/pattern.zig +++ b/src/builtin/pattern.zig @@ -272,8 +272,8 @@ fn rawReplace(self: *o.ObjPattern, vm: *VM, subject: *o.ObjString, replacement: return subject; } - var result = std.ArrayList(u8){}; - defer result.deinit(vm.gc.allocator); + var result = std.Io.Writer.Allocating.init(vm.gc.allocator); + defer result.deinit(); var match_data = self.pattern.createMatchData(null) orelse { vm.panic("Out of memory"); @@ -299,16 +299,25 @@ fn rawReplace(self: *o.ObjPattern, vm: *VM, subject: *o.ObjString, replacement: }, else => { const output_vector = match_data.getOVectorPointer(); - - offset.* = @as(usize, @intCast(output_vector[1])); - - try result.appendSlice(vm.gc.allocator, subject.string[0..@as(usize, @intCast(output_vector[0]))]); - try result.appendSlice(vm.gc.allocator, replacement.string); - try result.appendSlice(vm.gc.allocator, subject.string[offset.*..]); + const next_offset = output_vector[0] + replacement.string.len; + + offset.* = if (output_vector[0] < output_vector[1]) + next_offset + else + next_offset + 1; + + try result.writer.print( + "{s}{s}{s}", + .{ + subject.string[0..output_vector[0]], + replacement.string, + subject.string[output_vector[1]..], + }, + ); }, } - return try vm.gc.copyString(result.items); + return try vm.gc.copyString(result.written()); } fn rawReplaceAll(self: *o.ObjPattern, vm: *VM, subject: *o.ObjString, replacement: *o.ObjString) !*o.ObjString { diff --git a/tests/022-io.buzz b/tests/behavior/022-io.buzz similarity index 100% rename from tests/022-io.buzz rename to tests/behavior/022-io.buzz diff --git a/tests/024-os.buzz b/tests/behavior/024-os.buzz similarity index 100% rename from tests/024-os.buzz rename to tests/behavior/024-os.buzz diff --git a/tests/027-run-file.buzz b/tests/behavior/027-run-file.buzz similarity index 100% rename from tests/027-run-file.buzz rename to tests/behavior/027-run-file.buzz diff --git a/tests/031-json.buzz b/tests/behavior/031-json.buzz similarity index 100% rename from tests/031-json.buzz rename to tests/behavior/031-json.buzz diff --git a/tests/049-multiline-strings.buzz b/tests/behavior/049-multiline-strings.buzz similarity index 100% rename from tests/049-multiline-strings.buzz rename to tests/behavior/049-multiline-strings.buzz diff --git a/tests/058-ffi.buzz b/tests/behavior/058-ffi.buzz similarity index 100% rename from tests/058-ffi.buzz rename to tests/behavior/058-ffi.buzz diff --git a/tests/068-testing.buzz b/tests/behavior/068-testing.buzz similarity index 100% rename from tests/068-testing.buzz rename to tests/behavior/068-testing.buzz diff --git a/tests/fuzzed/id:000014,src:000008,time:3034101,execs:29776,op:flip1,pos:379 b/tests/fuzzed/id:000014,src:000008,time:3034101,execs:29776,op:flip1,pos:379 deleted file mode 100644 index d7ff22a7..00000000 --- a/tests/fuzzed/id:000014,src:000008,time:3034101,execs:29776,op:flip1,pos:379 +++ /dev/null @@ -1,29 +0,0 @@ -import "std"; -import "gc"; - -var collectorCalled = false; - -object Kill { - yo: int = -1, - - fun collect() > void { - collectorCalled = true; - } -} - -test "GC, collecting unreferenced objects" { - var i = 0; - _ = Kill{}; // Should be kept longer - while (i < 1000) { - _ = Kill{ yo = i }; // Should be collected since not referenced anywhere - - i = i ; 1; - } - - final before = gc\allocated(); - - gc\collect(); - - std\assert(gc\allocated() <= before, message: "Garbage was collected"); - std\assert(collectorCalled, message: "Object collector was called"); -} diff --git a/tests/fuzzed/id:000015,src:000008,time:3036220,execs:29779,op:flip1,pos:379 b/tests/fuzzed/id:000015,src:000008,time:3036220,execs:29779,op:flip1,pos:379 deleted file mode 100644 index 62ce90f7..00000000 --- a/tests/fuzzed/id:000015,src:000008,time:3036220,execs:29779,op:flip1,pos:379 +++ /dev/null @@ -1,29 +0,0 @@ -import "std"; -import "gc"; - -var collectorCalled = false; - -object Kill { - yo: int = -1, - - fun collect() > void { - collectorCalled = true; - } -} - -test "GC, collecting unreferenced objects" { - var i = 0; - _ = Kill{}; // Should be kept longer - while (i < 1000) { - _ = Kill{ yo = i }; // Should be collected since not referenced anywhere - - i = i / 1; - } - - final before = gc\allocated(); - - gc\collect(); - - std\assert(gc\allocated() <= before, message: "Garbage was collected"); - std\assert(collectorCalled, message: "Object collector was called"); -} diff --git a/tests/fuzzed/id:000016,src:000008,time:3038341,execs:29782,op:flip1,pos:379 b/tests/fuzzed/id:000016,src:000008,time:3038341,execs:29782,op:flip1,pos:379 deleted file mode 100644 index c603b6b8..00000000 --- a/tests/fuzzed/id:000016,src:000008,time:3038341,execs:29782,op:flip1,pos:379 +++ /dev/null @@ -1,29 +0,0 @@ -import "std"; -import "gc"; - -var collectorCalled = false; - -object Kill { - yo: int = -1, - - fun collect() > void { - collectorCalled = true; - } -} - -test "GC, collecting unreferenced objects" { - var i = 0; - _ = Kill{}; // Should be kept longer - while (i < 1000) { - _ = Kill{ yo = i }; // Should be collected since not referenced anywhere - - i = i * 1; - } - - final before = gc\allocated(); - - gc\collect(); - - std\assert(gc\allocated() <= before, message: "Garbage was collected"); - std\assert(collectorCalled, message: "Object collector was called"); -} diff --git a/tests/fuzzed/id:000017,src:000008,time:3155723,execs:30217,op:flip2,pos:379 b/tests/fuzzed/id:000017,src:000008,time:3155723,execs:30217,op:flip2,pos:379 deleted file mode 100644 index fa381142..00000000 --- a/tests/fuzzed/id:000017,src:000008,time:3155723,execs:30217,op:flip2,pos:379 +++ /dev/null @@ -1,29 +0,0 @@ -import "std"; -import "gc"; - -var collectorCalled = false; - -object Kill { - yo: int = -1, - - fun collect() > void { - collectorCalled = true; - } -} - -test "GC, collecting unreferenced objects" { - var i = 0; - _ = Kill{}; // Should be kept longer - while (i < 1000) { - _ = Kill{ yo = i }; // Should be collected since not referenced anywhere - - i = i - 1; - } - - final before = gc\allocated(); - - gc\collect(); - - std\assert(gc\allocated() <= before, message: "Garbage was collected"); - std\assert(collectorCalled, message: "Object collector was called"); -} diff --git a/tests/fuzzed/id:000019,src:000008,time:3919860,execs:33298,op:havoc,rep:1 b/tests/fuzzed/id:000019,src:000008,time:3919860,execs:33298,op:havoc,rep:1 deleted file mode 100644 index 8be68a71..00000000 --- a/tests/fuzzed/id:000019,src:000008,time:3919860,execs:33298,op:havoc,rep:1 +++ /dev/null @@ -1,27 +0,0 @@ -import "std"; -import "gc"; - -var collectorCalled = false; - -object Kill { - yo: int = -1, - - fun collect() > void { - collectorCalled = true; - } -} - -test "GC, collecting unreferenced objects" { - var i = 0; - _ = Kill{}; // Should be kept longer - while (i < 1000) { - _ = Kill{ yo = i }; // Should be collected since not referencedssage: "Obj i = i + 1; - } - - final before = gc\allocated(); - - gc\collect(); - - std\assert(gc\allocated() <= before, message: "Garbage was collected"); - std\assert(collectorCalled, message: "Object collector was called"); -} From 0e0b6dfb602ba1c2baa372f8ac5c9d7db831c3b5 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 6 Nov 2025 16:38:02 +0100 Subject: [PATCH 07/17] fix: Some indirect field access when not type checked properly --- src/TypeChecker.zig | 116 ++++++++++++++++++++++++++++++++++---------- src/behavior.zig | 2 +- 2 files changed, 92 insertions(+), 26 deletions(-) diff --git a/src/TypeChecker.zig b/src/TypeChecker.zig index 59cb9260..64157c73 100644 --- a/src/TypeChecker.zig +++ b/src/TypeChecker.zig @@ -642,24 +642,46 @@ fn checkDot(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, no // Type check value switch (callee_type.def_type) { .ForeignContainer => { - const field_type = callee_type.resolved_type.?.ForeignContainer.buzz_type.get(field_name).?; - - if (!field_type.eql(value_type_def)) { - reporter.reportTypeCheck( - .assignment_value_type, - ast.tokens.get(callee_type.resolved_type.?.ForeignContainer.location), - ast.tokens.get(callee_type.resolved_type.?.ForeignContainer.location), - field_type, - ast.tokens.get(locations[value]), - ast.tokens.get(end_locations[value]), - value_type_def, - "Bad property type", + if (callee_type.resolved_type.?.ForeignContainer.buzz_type.get(field_name)) |field_type| { + if (!field_type.eql(value_type_def)) { + reporter.reportTypeCheck( + .assignment_value_type, + ast.tokens.get(callee_type.resolved_type.?.ForeignContainer.location), + ast.tokens.get(callee_type.resolved_type.?.ForeignContainer.location), + field_type, + ast.tokens.get(locations[value]), + ast.tokens.get(end_locations[value]), + value_type_def, + "Bad property type", + ); + had_error = true; + } + } else { + reporter.reportErrorFmt( + .property_does_not_exists, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "List property `{s}` does not exists", + .{ + field_name, + }, ); had_error = true; } }, .ObjectInstance, .Object => { - if (field.?.method or + if (field == null) { + reporter.reportErrorFmt( + .property_does_not_exists, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Property `{s}` does not exists", + .{ + field_name, + }, + ); + had_error = true; + } else if (field.?.method or (callee_type.def_type == .ObjectInstance and field.?.static) or (callee_type.def_type == .Object and !field.?.static)) { @@ -799,7 +821,18 @@ fn checkDot(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, no had_error = true; } - if (field.?.mutable and !callee_type.resolved_type.?.ObjectInstance.mutable) { + if (field == null) { + reporter.reportErrorFmt( + .property_does_not_exists, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Property `{s}` does not exists", + .{ + field_name, + }, + ); + had_error = true; + } else if (field.?.mutable and !callee_type.resolved_type.?.ObjectInstance.mutable) { reporter.report( .not_mutable, ast.tokens.get(components.identifier), @@ -819,7 +852,18 @@ fn checkDot(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, no .methods .get(field_name); - if (field.?.mutable and !callee_type.resolved_type.?.ProtocolInstance.mutable) { + if (field == null) { + reporter.reportErrorFmt( + .property_does_not_exists, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Method `{s}` does not exists", + .{ + field_name, + }, + ); + had_error = true; + } else if (field.?.mutable and !callee_type.resolved_type.?.ProtocolInstance.mutable) { reporter.report( .not_mutable, ast.tokens.get(components.identifier), @@ -836,28 +880,50 @@ fn checkDot(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, no const identifier = ast.tokens.items(.lexeme)[components.identifier]; switch (callee_type.def_type) { - .List => if (callee_type.resolved_type.?.List.methods.get(identifier).?.mutable and - !callee_type.resolved_type.?.List.mutable) - { + .List => if (callee_type.resolved_type.?.List.methods.get(identifier)) |member| { + if (member.mutable and !callee_type.resolved_type.?.List.mutable) { + reporter.reportErrorFmt( + .not_mutable, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Method `{s}` requires mutable list", + .{ + identifier, + }, + ); + had_error = true; + } + } else { reporter.reportErrorFmt( - .not_mutable, + .property_does_not_exists, ast.tokens.get(components.identifier), ast.tokens.get(components.identifier), - "Method `{s}` requires mutable list", + "List property `{s}` does not exists", .{ identifier, }, ); had_error = true; }, - .Map => if (callee_type.resolved_type.?.Map.methods.get(identifier).?.mutable and - !callee_type.resolved_type.?.Map.mutable) - { + .Map => if (callee_type.resolved_type.?.Map.methods.get(identifier)) |member| { + if (member.mutable and !callee_type.resolved_type.?.Map.mutable) { + reporter.reportErrorFmt( + .not_mutable, + ast.tokens.get(components.identifier), + ast.tokens.get(components.identifier), + "Method `{s}` requires mutable list", + .{ + identifier, + }, + ); + had_error = true; + } + } else { reporter.reportErrorFmt( - .not_mutable, + .property_does_not_exists, ast.tokens.get(components.identifier), ast.tokens.get(components.identifier), - "Method `{s}` requires mutable list", + "Map property `{s}` does not exists", .{ identifier, }, diff --git a/src/behavior.zig b/src/behavior.zig index ceaf48dc..d3efa348 100644 --- a/src/behavior.zig +++ b/src/behavior.zig @@ -1,5 +1,5 @@ //! Because of https://github.com/ziglang/zig/issues/15091 test that write to stdout will hang -//! However I think its completely legitimate for a tested code to output to stdout and I +//! However I think it's completely legitimate for a tested code to output to stdout and I //! don't really get why zig test needs to use stdout anyway const std = @import("std"); From 16a0b448b05d9ff09c1b36db38bdbbd27b05d7d9 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Fri, 7 Nov 2025 13:29:53 +0100 Subject: [PATCH 08/17] fix: Composite operators on list assignment --- src/Ast.zig | 1 + src/Codegen.zig | 60 ++++++++++++++++++++-- src/Jit.zig | 54 ++++++++++++++++---- src/Parser.zig | 19 ++++++- src/Token.zig | 18 +++++++ src/TypeChecker.zig | 26 ++++++++++ src/vm.zig | 17 ++++--- tests/behavior/075-composite-assign.buzz | 65 ++++++++++++++++++++++++ 8 files changed, 240 insertions(+), 20 deletions(-) diff --git a/src/Ast.zig b/src/Ast.zig index abbf71a8..4d6c96ca 100644 --- a/src/Ast.zig +++ b/src/Ast.zig @@ -1525,6 +1525,7 @@ pub const Subscript = struct { subscripted: Node.Index, index: Node.Index, value: ?Node.Index, + assign_token: ?TokenIndex, checked: bool, }; diff --git a/src/Codegen.zig b/src/Codegen.zig index b778756a..7bc3f72c 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -383,7 +383,11 @@ fn patchOptJumps(self: *Self, node: Ast.Node.Index) !void { const location = self.ast.nodes.items(.location)[node]; if (self.ast.nodes.items(.patch_opt_jumps)[node]) { - std.debug.assert(self.opt_jumps.items.len > 0); + std.debug.assert(self.reporter.last_error != null or self.opt_jumps.items.len > 0); + + if (self.opt_jumps.items.len == 0) { + return; + } // Hope over OP_POP if actual value const njump: usize = try self.emitJump(location, .OP_JUMP); @@ -2023,12 +2027,12 @@ fn generateIf(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.O try self.OP_NOT(condition_location); } - const else_jump: usize = try self.OP_JUMP_IF_FALSE(location); + const else_jump = try self.OP_JUMP_IF_FALSE(location); try self.OP_POP(location); _ = try self.generateNode(components.body, breaks); - const out_jump: usize = try self.emitJump(location, .OP_JUMP); + const out_jump = try self.emitJump(location, .OP_JUMP); self.patchJump(else_jump); if (components.unwrapped_identifier != null or components.casted_type != null) { @@ -2554,6 +2558,7 @@ fn generateSubscript(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error! const location = locations[node]; const type_defs = self.ast.nodes.items(.type_def); const components = self.ast.nodes.items(.components)[node].Subscript; + const tags = self.ast.tokens.items(.tag); _ = try self.generateNode(components.subscripted, breaks); @@ -2577,9 +2582,56 @@ fn generateSubscript(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error! _ = try self.generateNode(components.index, breaks); - if (components.value) |value| { + if (!components.checked and components.value != null) { + const value = components.value.?; + + if (tags[components.assign_token.?].isAssignShortcut()) { + try self.emitCodeArg( + locations[value], + get_code, + 2, // 2 means, leave subscript and index on the stack + ); + } + _ = try self.generateNode(value, breaks); + switch (tags[components.assign_token.?]) { + .PlusEqual => switch (type_defs[value].?.def_type) { + .Integer => try self.OP_ADD_I(locations[value]), + .Double => try self.OP_ADD_F(locations[value]), + .List => try self.OP_ADD_LIST(locations[value]), + .Map => try self.OP_ADD_MAP(locations[value]), + .String => try self.OP_ADD_STRING(locations[value]), + else => {}, + }, + .MinusEqual => switch (type_defs[value].?.def_type) { + .Integer => try self.OP_SUBTRACT_I(locations[value]), + .Double => try self.OP_SUBTRACT_F(locations[value]), + else => {}, + }, + .StarEqual => switch (type_defs[value].?.def_type) { + .Integer => try self.OP_MULTIPLY_I(locations[value]), + .Double => try self.OP_MULTIPLY_F(locations[value]), + else => {}, + }, + .SlashEqual => switch (type_defs[value].?.def_type) { + .Integer => try self.OP_DIVIDE_I(locations[value]), + .Double => try self.OP_DIVIDE_F(locations[value]), + else => {}, + }, + .ShiftRightEqual => try self.OP_SHR(locations[value]), + .ShiftLeftEqual => try self.OP_SHL(locations[value]), + .XorEqual => try self.OP_XOR(locations[value]), + .BorEqual => try self.OP_BOR(locations[value]), + .AmpersandEqual => try self.OP_BAND(locations[value]), + .PercentEqual => switch (type_defs[value].?.def_type) { + .Integer => try self.OP_MOD_I(locations[value]), + .Double => try self.OP_MOD_F(locations[value]), + else => {}, + }, + else => {}, + } + try self.emitOpCode(location, set_code); } else { try self.emitCodeArg( diff --git a/src/Jit.zig b/src/Jit.zig index 6ead6827..eaa3a2cd 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -3875,6 +3875,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { fn generateSubscript(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { const components = self.state.?.ast.nodes.items(.components)[node].Subscript; const type_defs = self.state.?.ast.nodes.items(.type_def); + const tags = self.state.?.ast.tokens.items(.tag); const subscripted = (try self.generateNode(components.subscripted)).?; const index_val = (try self.generateNode(components.index)).?; @@ -3890,16 +3891,51 @@ fn generateSubscript(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { try self.unwrap(.Integer, index_val, index); if (value) |val| { - try self.buildExternApiCall( - .bz_listSet, - null, - &[_]m.MIR_op_t{ - subscripted, - index, + if (tags[components.assign_token.?] != .Equal) { + const res = m.MIR_new_reg_op( + self.ctx, + try self.REG("res", m.MIR_T_I64), + ); + try self.buildExternApiCall( + .bz_listGet, + res, + &[_]m.MIR_op_t{ + subscripted, + index, + m.MIR_new_uint_op(self.ctx, 0), + }, + ); + + try self.buildBinary( + tags[components.assign_token.?], + type_defs[components.value.?].?.def_type, + res, val, - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), - }, - ); + res, + ); + + try self.buildExternApiCall( + .bz_listSet, + null, + &[_]m.MIR_op_t{ + subscripted, + index, + res, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), + }, + ); + } else { + try self.buildExternApiCall( + .bz_listSet, + null, + &[_]m.MIR_op_t{ + subscripted, + index, + val, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), + }, + ); + } return subscripted; } diff --git a/src/Parser.zig b/src/Parser.zig index 2d68231a..ffd73deb 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -3968,7 +3968,23 @@ fn subscript(self: *Self, can_assign: bool, subscripted: Ast.Node.Index) Error!A try self.consume(.RightBracket, "Expected `]`."); var value: ?Ast.Node.Index = null; - if (can_assign and (subscript_type_def.def_type != .Any or subscript_type_def.def_type != .String) and try self.match(.Equal)) { + var assign_token: ?Ast.TokenIndex = null; + if (can_assign and + (subscript_type_def.def_type == .Map or subscript_type_def.def_type == .List or subscript_type_def.def_type == .Placeholder) and + try self.matchOpEqual()) + { + assign_token = self.current_token.? - 1; + + if (checked) { + const loc = self.ast.tokens.get(assign_token.?); + self.reporter.reportErrorAt( + .assignable, + loc, + loc, + "Can't assign with checked subscript", + ); + } + value = try self.expression(false); const value_type_def = self.ast.nodes.items(.type_def)[value.?]; @@ -3995,6 +4011,7 @@ fn subscript(self: *Self, can_assign: bool, subscripted: Ast.Node.Index) Error!A .Subscript = .{ .index = index, .value = value, + .assign_token = assign_token, .subscripted = subscripted, .checked = checked, }, diff --git a/src/Token.zig b/src/Token.zig index 5eececce..3b6466a6 100644 --- a/src/Token.zig +++ b/src/Token.zig @@ -205,6 +205,24 @@ pub const Type = enum { BnotEqual, // ~= AmpersandEqual, // &= PercentEqual, // %= + + pub fn isAssignShortcut(self: @This()) bool { + return switch (self) { + .PlusEqual, + .MinusEqual, + .StarEqual, + .SlashEqual, + .ShiftRightEqual, + .ShiftLeftEqual, + .XorEqual, + .BorEqual, + .BnotEqual, + .AmpersandEqual, + .PercentEqual, + => true, + else => false, + }; + } }; // FIXME if case had the same name as the actual token we could simply use @tagName diff --git a/src/TypeChecker.zig b/src/TypeChecker.zig index 64157c73..afe40b68 100644 --- a/src/TypeChecker.zig +++ b/src/TypeChecker.zig @@ -2074,6 +2074,32 @@ fn checkSubscript(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Ind var had_error = false; + if (components.assign_token != null and subscripted_type_def.def_type != .List and subscripted_type_def.def_type != .Map) { + reporter.reportErrorFmt( + .assignable, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + "Can't assign to `{s}`.", + .{ + subscripted_type_def.toStringAlloc(gc.allocator, false) catch return error.OutOfMemory, + }, + ); + had_error = true; + } + + if (components.checked and subscripted_type_def.def_type != .List and subscripted_type_def.def_type != .String) { + reporter.reportErrorFmt( + .assignable, + ast.tokens.get(location), + ast.tokens.get(end_locations[node]), + "Checked subscript not available for `{s}`.", + .{ + subscripted_type_def.toStringAlloc(gc.allocator, false) catch return error.OutOfMemory, + }, + ); + had_error = true; + } + switch (subscripted_type_def.def_type) { .String => if (index_type_def.def_type != .Integer) { reporter.reportErrorAt( diff --git a/src/vm.zig b/src/vm.zig index 7cd0cf99..34dae686 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -823,6 +823,7 @@ pub const VM = struct { fn dispatch(self: *Self, current_frame: *CallFrame, full_instruction: u32, instruction: Chunk.OpCode, arg: u24) void { if (BuildOptions.debug_stack) { + std.debug.print("{s}:\n", .{@tagName(instruction)}); dumpStack(self); } @@ -2555,12 +2556,12 @@ pub const VM = struct { ); } - fn OP_GET_LIST_SUBSCRIPT(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, checked: u24) void { + fn OP_GET_LIST_SUBSCRIPT(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, checked_or_leave: u24) void { const list = self.peek(1).obj() .access(obj.ObjList, .List, self.gc).?; const index = self.peek(0).integer(); - if (checked == 0 and index < 0) { + if (checked_or_leave != 1 and index < 0) { self.throw( Error.OutOfBound, (self.gc.copyString("Out of bound list access.") catch { @@ -2582,7 +2583,7 @@ pub const VM = struct { const list_index: usize = @intCast(index); - if (checked == 0 and list_index >= list.items.items.len) { + if (checked_or_leave != 1 and list_index >= list.items.items.len) { self.throw( Error.OutOfBound, (self.gc.copyString("Out of bound list access.") catch { @@ -2610,7 +2611,9 @@ pub const VM = struct { list.items.items[list_index]; // Pop list and index - self.discard(2); + if (checked_or_leave != 2) { + self.discard(2); + } // Push value self.push(list_item); @@ -2629,12 +2632,14 @@ pub const VM = struct { ); } - fn OP_GET_MAP_SUBSCRIPT(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, _: u24) void { + fn OP_GET_MAP_SUBSCRIPT(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, leave: u24) void { var map = self.peek(1).obj().access(obj.ObjMap, .Map, self.gc).?; const index = self.peek(0); // Pop map and key - self.discard(2); + if (leave != 2) { + self.discard(2); + } if (map.map.get(index)) |value| { // Push value diff --git a/tests/behavior/075-composite-assign.buzz b/tests/behavior/075-composite-assign.buzz index bf9a87b2..63f7c8b7 100644 --- a/tests/behavior/075-composite-assign.buzz +++ b/tests/behavior/075-composite-assign.buzz @@ -196,3 +196,68 @@ test "Composite operators on object static fields" { P.sstring += " world"; std\assert(P.sstring == "hello world", message: "+= on object static string field"); } + +test "Composite operator on list assignment" { + final list = mut [ 2, 1, 3 ]; + + list[1] += 1; + std\assert(list[1] == 2, message: "+= on list subscript"); + + list[1] -= 1; + std\assert(list[1] == 1, message: "-= on list subscript"); + + list[1] *= 4; + std\assert(list[1] == 4, message: "*= on list subscript"); + + list[1] /= 2; + std\assert(list[1] == 2, message: "/= on list subscript"); + + list[1] %= 2; + std\assert(list[1] == 0, message: "%= on list subscript"); + + list[1] = 3; + list[1] <<= 1; + std\assert(list[1] == 6, message: "<<= on list subscript"); + + list[1] >>= 1; + std\assert(list[1] == 3, message: ">>= on list subscript"); + + list[1] ^= 2; + std\assert(list[1] == 1, message: "^= on list subscript"); + + list[1] |= 2; + std\assert(list[1] == 3, message: "|= on list subscript"); + + list[1] &= 2; + std\assert(list[1] == 2, message: "&= 2 on list subscript"); + + final dlist = mut [ 2.0, 1.0, 3.0 ]; + + dlist[1] += 1.0; + std\assert(dlist[1] == 2, message: "+= on list subscript"); + + dlist[1] -= 1.0; + std\assert(dlist[1] == 1, message: "-= on list subscript"); + + dlist[1] *= 4.0; + std\assert(dlist[1] == 4, message: "*= on list subscript"); + + dlist[1] /= 2.0; + std\assert(dlist[1] == 2, message: "/= on list subscript"); + + dlist[1] %= 2.0; + std\assert(dlist[1] == 0, message: "%= on list subscript"); + + final llist = mut [ [ 3, 3, 3 ], [ 1, 2, 3 ], [ 4, 4, 4 ] ]; + + llist[1] += [ 4, 5, 6 ]; + std\assert(llist[1].len() == 6, message: "+= on list of lists subscript"); + + final mlist = mut [ { "two": 2 }, { "one": 1 }, { "three": 3 } ]; + mlist[1] += { "two": 2 }; + std\assert(mlist[1].size() == 2, message: "+= on list of maps subscript"); + + final slist = mut [ "one", "hello", "two" ]; + slist[1] += " world"; + std\assert(slist[1] == "hello world", message: "+= on list of strings subscript"); +} From cf5a2e83c84318321a711e506c9e31a30791369f Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Sun, 9 Nov 2025 22:24:14 +0100 Subject: [PATCH 09/17] fix(pattern): Handle empty match --- src/builtin/pattern.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/builtin/pattern.zig b/src/builtin/pattern.zig index 56227c3b..4793505e 100644 --- a/src/builtin/pattern.zig +++ b/src/builtin/pattern.zig @@ -160,7 +160,10 @@ fn rawMatch(self: *o.ObjPattern, vm: *VM, subject: *o.ObjString, offset: *usize) else => { const output_vector = match_data.getOVectorPointer(); - offset.* = @intCast(output_vector[1]); + offset.* = if (output_vector[0] < output_vector[1]) + output_vector[1] + else + output_vector[1] + 1; results = try vm.gc.allocateObject( try o.ObjList.init( From e650b67ac207d8c924a75141a040b2b1f2429aee Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 12 Nov 2025 10:14:50 +0100 Subject: [PATCH 10/17] fix(fuzz): Added .buzz extension to fuzzed tests --- src/Codegen.zig | 28 ++++++++---------- src/Debugger.zig | 1 - src/vm.zig | 20 ++----------- tests/fuzzed/README.txt | 14 --------- ...51,time:929,execs:782,op:quick,pos:0.buzz} | 0 ...,execs:18330,op:quick,pos:104,val:+1.buzz} | 0 ...time:13766,execs:1095,op:flip1,pos:1.buzz} | 0 ...:932808,execs:18686,op:flip1,pos:105.buzz} | 0 ...time:13812,execs:1096,op:flip1,pos:1.buzz} | 0 ...:934683,execs:18688,op:flip1,pos:105.buzz} | 0 ...time:15542,execs:1136,op:flip1,pos:1.buzz} | 0 ...:944955,execs:18702,op:flip1,pos:108.buzz} | 0 ...time:45178,execs:1765,op:flip2,pos:1.buzz} | 0 ...:982430,execs:18918,op:flip2,pos:105.buzz} | 0 ...time:46425,execs:1794,op:flip2,pos:1.buzz} | 0 ...e:1726632,execs:23371,op:havoc,rep:4.buzz} | 0 ...ime:66728,execs:2227,op:flip2,pos:66.buzz} | 0 ...e:1755372,execs:23546,op:havoc,rep:2.buzz} | 0 ...time:69064,execs:2277,op:flip4,pos:1.buzz} | 0 ...e:1831679,execs:24074,op:havoc,rep:4.buzz} | 0 ...time:69114,execs:2278,op:flip4,pos:1.buzz} | 0 ...e:1878199,execs:24397,op:havoc,rep:1.buzz} | 0 ...time:71379,execs:2330,op:flip4,pos:4.buzz} | 0 ...e:1937548,execs:24820,op:havoc,rep:2.buzz} | 0 ...ime:83385,execs:2556,op:flip4,pos:49.buzz} | 0 ...e:2225913,execs:26757,op:havoc,rep:4.buzz} | 0 ...ime:88769,execs:2664,op:flip32,pos:3.buzz} | 0 ...e:2297408,execs:27208,op:havoc,rep:1.buzz} | 0 ...me:88966,execs:2669,op:flip32,pos:12.buzz} | 0 ...,execs:29065,op:quick,pos:488,val:+1.buzz} | 0 ...9,execs:3388,op:arith8,pos:12,val:+5.buzz} | 0 ...,execs:29070,op:quick,pos:492,val:+1.buzz} | 0 ...,execs:3463,op:arith8,pos:12,val:-23.buzz} | 0 ...,execs:3567,op:arith8,pos:13,val:+26.buzz} | 0 ...,execs:4807,op:arith8,pos:67,val:+23.buzz} | 0 ...,execs:4829,op:arith8,pos:67,val:+28.buzz} | 0 ...,execs:4833,op:arith8,pos:67,val:+30.buzz} | 0 ...e:3677561,execs:32267,op:havoc,rep:2.buzz} | 0 ...,execs:4854,op:arith8,pos:67,val:+35.buzz} | 0 ...857,execs:5246,op:int16,pos:1,val:+1.buzz} | Bin ...,execs:38213,op:quick,pos:492,val:+6.buzz} | 0 ...ime:304934,execs:7111,op:havoc,rep:6.buzz} | 0 ...,execs:39686,op:quick,pos:251,val:+1.buzz} | 0 ...me:317141,execs:7388,op:havoc,rep:10.buzz} | 0 ...,execs:39790,op:quick,pos:330,val:+1.buzz} | 0 ...me:317455,execs:7395,op:havoc,rep:14.buzz} | Bin ...,execs:39792,op:quick,pos:331,val:+1.buzz} | 0 ...me:324656,execs:7522,op:havoc,rep:11.buzz} | 0 ...e:6940331,execs:46733,op:havoc,rep:1.buzz} | 0 ...ime:341820,execs:7862,op:havoc,rep:5.buzz} | 0 ...4,execs:58114,op:quick,pos:79,val:+2.buzz} | 0 ...me:345967,execs:7955,op:havoc,rep:16.buzz} | Bin ...,execs:58339,op:quick,pos:255,val:+2.buzz} | 0 ...me:347472,execs:7988,op:havoc,rep:13.buzz} | 0 ...,execs:58552,op:quick,pos:431,val:+2.buzz} | 0 ...ime:347609,execs:7991,op:havoc,rep:6.buzz} | Bin ...,execs:58806,op:quick,pos:612,val:+2.buzz} | 0 ...me:400266,execs:9041,op:havoc,rep:14.buzz} | Bin ...,execs:59012,op:quick,pos:781,val:+2.buzz} | 0 ...ime:401374,execs:9066,op:havoc,rep:9.buzz} | 0 ...execs:59845,op:quick,pos:1313,val:+2.buzz} | 0 ...me:408249,execs:9208,op:havoc,rep:14.buzz} | 0 ...e:9590514,execs:62692,op:havoc,rep:3.buzz} | 0 ...me:414648,execs:9350,op:havoc,rep:10.buzz} | 0 ...e:9938774,execs:64109,op:havoc,rep:3.buzz} | 0 ...ime:421281,execs:9487,op:havoc,rep:4.buzz} | 0 ...:10025436,execs:64464,op:havoc,rep:1.buzz} | 0 ...me:429246,execs:9657,op:havoc,rep:16.buzz} | Bin ...3064132,execs:70410,op:quick,pos:868.buzz} | 0 ...ime:435014,execs:9787,op:havoc,rep:6.buzz} | 0 ...199030,execs:70941,op:quick,pos:1182.buzz} | 0 ...me:458317,execs:10266,op:havoc,rep:7.buzz} | 0 ...268403,execs:71209,op:quick,pos:1413.buzz} | 0 ...e:462379,execs:10345,op:havoc,rep:15.buzz} | Bin ...:13686254,execs:72978,op:havoc,rep:1.buzz} | 0 ...e:464531,execs:10395,op:havoc,rep:13.buzz} | Bin ...:14303774,execs:75567,op:havoc,rep:2.buzz} | 0 ...me:475463,execs:10632,op:havoc,rep:9.buzz} | 0 ...,execs:87650,op:quick,pos:152,val:+1.buzz} | 0 ...e:486723,execs:10886,op:havoc,rep:12.buzz} | 0 ...,execs:88058,op:quick,pos:391,val:+1.buzz} | 0 ...me:487763,execs:10912,op:havoc,rep:9.buzz} | Bin ...,execs:88430,op:quick,pos:678,val:+1.buzz} | 0 ...me:503456,execs:11261,op:havoc,rep:4.buzz} | Bin ...18612333,execs:93274,op:quick,pos:96.buzz} | 0 ...e:514440,execs:11517,op:havoc,rep:11.buzz} | Bin ...8759009,execs:93868,op:quick,pos:617.buzz} | 0 ...e:520847,execs:11652,op:havoc,rep:14.buzz} | 0 ...033188,execs:94894,op:quick,pos:1522.buzz} | 0 ...me:523723,execs:11720,op:havoc,rep:6.buzz} | Bin ...108064,execs:95159,op:quick,pos:1774.buzz} | 0 ...e:528438,execs:11825,op:havoc,rep:15.buzz} | Bin ...,execs:98972,op:quick,pos:215,val:+4.buzz} | 0 ...e:547324,execs:12257,op:havoc,rep:14.buzz} | Bin ...,execs:99679,op:quick,pos:825,val:+4.buzz} | 0 ...e:557798,execs:12486,op:havoc,rep:16.buzz} | Bin ...execs:99967,op:quick,pos:1112,val:+4.buzz} | 0 ...e:591401,execs:13229,op:havoc,rep:16.buzz} | Bin ...execs:105200,op:quick,pos:228,val:+3.buzz} | 0 ...me:624596,execs:13922,op:havoc,rep:6.buzz} | 0 ...execs:105475,op:quick,pos:454,val:+3.buzz} | 0 ...e:628015,execs:13999,op:havoc,rep:16.buzz} | 0 ...execs:105711,op:quick,pos:653,val:+3.buzz} | 0 ...e:638876,execs:14245,op:havoc,rep:13.buzz} | 0 ...execs:105976,op:quick,pos:869,val:+3.buzz} | 0 ...e:656502,execs:14649,op:havoc,rep:14.buzz} | 0 ...xecs:106306,op:quick,pos:1162,val:+3.buzz} | 0 ...e:662089,execs:14767,op:havoc,rep:13.buzz} | 0 ...22766394,execs:109675,op:havoc,rep:2.buzz} | 0 ...me:709950,execs:15892,op:havoc,rep:8.buzz} | Bin ...execs:115372,op:quick,pos:418,val:+2.buzz} | 0 ...me:737512,execs:16496,op:havoc,rep:2.buzz} | Bin ...xecs:116487,op:quick,pos:1520,val:+2.buzz} | 0 ...e:792567,execs:17714,op:havoc,rep:12.buzz} | 0 ...8,execs:124145,op:quick,pos:8,val:+3.buzz} | 0 ...e:792739,execs:17718,op:havoc,rep:11.buzz} | Bin ...execs:124255,op:quick,pos:105,val:+3.buzz} | 0 ...:1038554,execs:19208,op:flip16,pos:7.buzz} | 0 ...execs:124340,op:quick,pos:165,val:+3.buzz} | 0 ...1046996,execs:19259,op:flip32,pos:13.buzz} | 0 ...execs:124411,op:quick,pos:223,val:+3.buzz} | 0 ...,execs:19778,op:arith8,pos:31,val:+5.buzz} | 0 ...execs:124482,op:quick,pos:281,val:+3.buzz} | 0 ...execs:19905,op:arith8,pos:32,val:+26.buzz} | 0 ...execs:124542,op:quick,pos:340,val:+3.buzz} | 0 ...execs:20767,op:arith8,pos:142,val:+5.buzz} | 0 ...execs:124652,op:quick,pos:413,val:+3.buzz} | 0 ...e:2034525,execs:25498,op:havoc,rep:4.buzz} | 0 ...execs:124710,op:quick,pos:470,val:+3.buzz} | 0 ...e:2092469,execs:25900,op:havoc,rep:1.buzz} | 0 ...execs:124771,op:quick,pos:518,val:+3.buzz} | 0 ...e:2172493,execs:26420,op:havoc,rep:2.buzz} | 0 ...execs:124841,op:quick,pos:575,val:+3.buzz} | 0 ...1,execs:28186,op:quick,pos:56,val:+1.buzz} | 0 ...execs:124902,op:quick,pos:623,val:+3.buzz} | 0 ...0,execs:28302,op:quick,pos:81,val:+1.buzz} | 0 ...execs:124990,op:quick,pos:698,val:+3.buzz} | 0 ...,execs:28454,op:quick,pos:113,val:+1.buzz} | 0 ...execs:125070,op:quick,pos:765,val:+3.buzz} | 0 ...e:3510036,execs:31594,op:havoc,rep:8.buzz} | 0 ...execs:125130,op:quick,pos:824,val:+3.buzz} | 0 ...e:3606862,execs:31986,op:havoc,rep:7.buzz} | 0 ...execs:125220,op:quick,pos:889,val:+3.buzz} | 0 ...e:4056407,execs:33850,op:havoc,rep:3.buzz} | 0 ...xecs:125414,op:quick,pos:1058,val:+3.buzz} | 0 ...e:4061094,execs:33873,op:havoc,rep:4.buzz} | 0 ...xecs:125519,op:quick,pos:1162,val:+3.buzz} | 0 ...e:4177920,execs:34344,op:havoc,rep:5.buzz} | Bin ...27343581,execs:126803,op:havoc,rep:1.buzz} | 0 ...e:4631215,execs:36218,op:havoc,rep:3.buzz} | 0 ...27428500,execs:127060,op:havoc,rep:2.buzz} | 0 ...3,execs:39064,op:quick,pos:26,val:+1.buzz} | 0 ...27508860,execs:127320,op:havoc,rep:1.buzz} | 0 ...4,execs:39154,op:quick,pos:44,val:+1.buzz} | 0 ...28280222,execs:129828,op:havoc,rep:2.buzz} | 0 ...9,execs:39190,op:quick,pos:56,val:+1.buzz} | 0 ...execs:130825,op:quick,pos:320,val:+1.buzz} | 0 ...,execs:39316,op:quick,pos:122,val:+1.buzz} | 0 ...execs:133312,op:quick,pos:326,val:+3.buzz} | 0 ...,execs:39405,op:quick,pos:151,val:+1.buzz} | 0 ...execs:133730,op:quick,pos:712,val:+3.buzz} | 0 ...,execs:39604,op:quick,pos:230,val:+1.buzz} | 0 ...execs:148166,op:quick,pos:273,val:+1.buzz} | 0 ...,execs:39605,op:quick,pos:231,val:+1.buzz} | 0 ...execs:148255,op:quick,pos:361,val:+1.buzz} | 0 ...,execs:39679,op:quick,pos:245,val:+1.buzz} | 0 ...execs:148343,op:quick,pos:436,val:+1.buzz} | 0 ...,execs:39749,op:quick,pos:314,val:+1.buzz} | 0 ...execs:148502,op:quick,pos:582,val:+1.buzz} | 0 ...:5604619,execs:39983,op:flip1,pos:60.buzz} | 0 ...execs:148584,op:quick,pos:651,val:+1.buzz} | 0 ...5630503,execs:40108,op:flip1,pos:186.buzz} | 0 ...execs:148754,op:quick,pos:796,val:+1.buzz} | 0 ...5700746,execs:40445,op:flip2,pos:186.buzz} | 0 ...execs:148843,op:quick,pos:872,val:+1.buzz} | 0 ...5713841,execs:40506,op:flip2,pos:239.buzz} | 0 ...execs:148990,op:quick,pos:982,val:+1.buzz} | 0 ...5790667,execs:40876,op:flip4,pos:239.buzz} | 0 ...31699360,execs:151545,op:havoc,rep:1.buzz} | 0 ...5793602,execs:40890,op:flip4,pos:243.buzz} | 0 ...133122,execs:152343,op:quick,pos:102.buzz} | 0 ...842975,execs:41125,op:flip32,pos:317.buzz} | 0 ...,execs:158378,op:quick,pos:73,val:+2.buzz} | 0 ...execs:41990,op:arith8,pos:112,val:-3.buzz} | 0 ...execs:162046,op:quick,pos:175,val:+2.buzz} | 0 ...xecs:42028,op:arith8,pos:112,val:+27.buzz} | 0 ...execs:162494,op:quick,pos:610,val:+2.buzz} | 0 ...xecs:42043,op:arith8,pos:112,val:-35.buzz} | 0 ...execs:162728,op:quick,pos:819,val:+2.buzz} | 0 ...xecs:42208,op:arith8,pos:127,val:+34.buzz} | 0 ...xecs:163118,op:quick,pos:1172,val:+2.buzz} | 0 ...xecs:42654,op:arith8,pos:186,val:-34.buzz} | 0 ...execs:169847,op:quick,pos:409,val:+2.buzz} | 0 ...e:6505974,execs:44419,op:havoc,rep:3.buzz} | 0 ...execs:170086,op:quick,pos:635,val:+2.buzz} | 0 ...e:6555894,execs:44698,op:havoc,rep:1.buzz} | 0 ...execs:170187,op:quick,pos:735,val:+2.buzz} | 0 ...e:6580144,execs:44831,op:havoc,rep:7.buzz} | 0 ...execs:170274,op:quick,pos:821,val:+2.buzz} | 0 ...e:6597156,execs:44919,op:havoc,rep:5.buzz} | 0 ...execs:173461,op:quick,pos:103,val:+1.buzz} | 0 ...e:6648180,execs:45187,op:havoc,rep:8.buzz} | Bin ...xecs:208056,op:quick,pos:1162,val:+2.buzz} | 0 ...e:6696301,execs:45445,op:havoc,rep:6.buzz} | Bin ...execs:212283,op:quick,pos:294,val:+1.buzz} | 0 ...e:6992140,execs:47011,op:havoc,rep:2.buzz} | 0 ...execs:226508,op:quick,pos:273,val:+2.buzz} | 0 ...e:7265946,execs:48467,op:havoc,rep:5.buzz} | 0 ...xecs:227633,op:quick,pos:1277,val:+2.buzz} | 0 ...e:7281766,execs:48549,op:havoc,rep:4.buzz} | 0 ...execs:230519,op:quick,pos:269,val:+6.buzz} | 0 ...,execs:49596,op:quick,pos:122,val:+3.buzz} | Bin ...xecs:231555,op:quick,pos:1280,val:+6.buzz} | 0 ...,execs:49625,op:quick,pos:151,val:+3.buzz} | Bin ...execs:243769,op:quick,pos:192,val:+3.buzz} | 0 ...,execs:49705,op:quick,pos:231,val:+3.buzz} | Bin ...execs:248698,op:quick,pos:489,val:+2.buzz} | 0 ...:7674377,execs:51835,op:havoc,rep:14.buzz} | Bin ...execs:251158,op:quick,pos:453,val:+5.buzz} | 0 ...e:7678243,execs:51883,op:havoc,rep:4.buzz} | Bin ...execs:251363,op:quick,pos:633,val:+5.buzz} | 0 ...e:7769850,execs:52921,op:havoc,rep:5.buzz} | Bin ...execs:251551,op:quick,pos:796,val:+5.buzz} | 0 ...e:7815337,execs:53475,op:havoc,rep:3.buzz} | Bin ...xecs:251899,op:quick,pos:1035,val:+5.buzz} | 0 ...e:7830891,execs:53673,op:havoc,rep:7.buzz} | Bin ...xecs:252532,op:quick,pos:1583,val:+5.buzz} | 0 ...:8013157,execs:55794,op:havoc,rep:15.buzz} | Bin ...58557878,execs:254103,op:havoc,rep:3.buzz} | 0 ...0,execs:56052,op:quick,pos:23,val:+7.buzz} | Bin ...58726876,execs:254838,op:havoc,rep:2.buzz} | 0 ...,execs:56176,op:quick,pos:123,val:+7.buzz} | Bin ...execs:266652,op:quick,pos:963,val:+7.buzz} | 0 ...e:9269834,execs:61432,op:havoc,rep:1.buzz} | 0 ...execs:269873,op:quick,pos:93,val:+11.buzz} | 0 ...e:9918752,execs:64030,op:havoc,rep:2.buzz} | 0 ...3625401,execs:275620,op:quick,pos:82.buzz} | 0 ...e:9949208,execs:64155,op:havoc,rep:1.buzz} | 0 ...664836,execs:275795,op:quick,pos:256.buzz} | 0 ...10618133,execs:65391,op:quick,pos:34.buzz} | 0 ...692320,execs:275913,op:quick,pos:373.buzz} | 0 ...0729928,execs:65545,op:quick,pos:125.buzz} | 0 ...795623,execs:276360,op:quick,pos:807.buzz} | 0 ...0730659,execs:65546,op:quick,pos:126.buzz} | 0 ...96430,execs:276799,op:quick,pos:1161.buzz} | 0 ...0733578,execs:65550,op:quick,pos:130.buzz} | 0 ...971371,execs:290741,op:quick,pos:239.buzz} | 0 ...0771649,execs:65599,op:quick,pos:167.buzz} | 0 ...996461,execs:290854,op:quick,pos:339.buzz} | 0 ...0878938,execs:65728,op:quick,pos:200.buzz} | 0 ...732463,execs:299979,op:quick,pos:199.buzz} | 0 ...0930657,execs:65798,op:quick,pos:234.buzz} | 0 ...819907,execs:300356,op:quick,pos:575.buzz} | 0 ...1132540,execs:66081,op:flip1,pos:105.buzz} | 0 ...869489,execs:300560,op:quick,pos:778.buzz} | 0 ...me:12674554,execs:68759,op:inf,rep:2.buzz} | 0 ...913805,execs:300733,op:quick,pos:938.buzz} | 0 ...me:12674783,execs:68760,op:inf,rep:2.buzz} | 0 ...11117,execs:301126,op:quick,pos:1318.buzz} | 0 ...me:12675014,execs:68761,op:inf,rep:2.buzz} | 0 ...625976,execs:316629,op:quick,pos:187.buzz} | 0 ...me:12691268,execs:68827,op:inf,rep:2.buzz} | 0 ...72856961,execs:317728,op:havoc,rep:9.buzz} | Bin ...2838977,execs:69470,op:quick,pos:224.buzz} | 0 ...481265,execs:324476,op:quick,pos:139.buzz} | 0 ...2877414,execs:69638,op:quick,pos:289.buzz} | 0 ...505122,execs:324579,op:quick,pos:241.buzz} | 0 ...3102189,execs:70564,op:quick,pos:986.buzz} | 0 ...747279,execs:329773,op:quick,pos:272.buzz} | 0 ...150009,execs:70758,op:quick,pos:1084.buzz} | 0 ...64205,execs:330797,op:quick,pos:1283.buzz} | 0 ...234094,execs:71080,op:quick,pos:1309.buzz} | 0 ...717279,execs:364061,op:quick,pos:179.buzz} | 0 ...422798,execs:71869,op:flip1,pos:1110.buzz} | 0 ...933133,execs:364998,op:quick,pos:335.buzz} | 0 ...424527,execs:71876,op:flip1,pos:1112.buzz} | 0 ...300118,execs:384604,op:quick,pos:148.buzz} | 0 ...:13700952,execs:73041,op:havoc,rep:2.buzz} | 0 ...357369,execs:384854,op:quick,pos:385.buzz} | 0 ...:13733874,execs:73181,op:havoc,rep:1.buzz} | 0 ...042894,execs:396343,op:quick,pos:271.buzz} | 0 ...:13837821,execs:73611,op:havoc,rep:2.buzz} | Bin ...070185,execs:400582,op:quick,pos:188.buzz} | 0 ...:13838964,execs:73616,op:havoc,rep:1.buzz} | 0 ...883913,execs:411509,op:quick,pos:275.buzz} | 0 ...:13845124,execs:73643,op:havoc,rep:2.buzz} | 0 ...888502,execs:427842,op:quick,pos:486.buzz} | 0 ...:14025464,execs:74393,op:havoc,rep:2.buzz} | 0 ...858379,execs:448821,op:quick,pos:424.buzz} | 0 ...:14121826,execs:74794,op:havoc,rep:1.buzz} | 0 ...657823,execs:451929,op:quick,pos:213.buzz} | 0 ...:14463265,execs:76249,op:havoc,rep:2.buzz} | 0 ...146080,execs:481926,op:quick,pos:276.buzz} | 0 ...execs:81806,op:quick,pos:1085,val:+1.buzz} | 0 ...015992,execs:485048,op:quick,pos:269.buzz} | 0 ...execs:81808,op:quick,pos:1087,val:+1.buzz} | 0 ...77936,execs:491508,op:quick,pos:1564.buzz} | 0 ...,execs:87620,op:quick,pos:123,val:+1.buzz} | 0 ...573893,execs:513984,op:quick,pos:242.buzz} | 0 ...,execs:87755,op:quick,pos:209,val:+1.buzz} | 0 ...642287,execs:514287,op:quick,pos:520.buzz} | 0 ...,execs:87812,op:quick,pos:230,val:+1.buzz} | 0 ...20901995,execs:515417,op:havoc,rep:2.buzz} | 0 ...,execs:88181,op:quick,pos:478,val:+1.buzz} | 0 ...738515,execs:518760,op:quick,pos:995.buzz} | 0 ...,execs:88410,op:quick,pos:659,val:+1.buzz} | 0 ...4016451,execs:527534,op:quick,pos:98.buzz} | 0 ...,execs:88510,op:quick,pos:758,val:+1.buzz} | 0 ...150367,execs:528099,op:quick,pos:650.buzz} | 0 ...execs:88939,op:quick,pos:1103,val:+1.buzz} | 0 ...120097,execs:536761,op:quick,pos:330.buzz} | 0 ...execs:89002,op:quick,pos:1118,val:+1.buzz} | 0 ...273407,execs:537385,op:quick,pos:917.buzz} | 0 ...execs:89034,op:quick,pos:1150,val:+1.buzz} | 0 ...646048,execs:564729,op:quick,pos:144.buzz} | 0 ...execs:89042,op:quick,pos:1158,val:+1.buzz} | 0 ...47926702,execs:620168,op:quick,pos:8.buzz} | 0 ...execs:89256,op:quick,pos:1348,val:+1.buzz} | 0 ...166653,execs:631064,op:quick,pos:200.buzz} | 0 ...7808080,execs:89986,op:flip2,pos:367.buzz} | 0 ...195334,execs:631178,op:quick,pos:289.buzz} | 0 ...849378,execs:90143,op:flip2,pos:1105.buzz} | 0 ...298817,execs:631609,op:quick,pos:671.buzz} | 0 ...8752646,execs:93847,op:quick,pos:597.buzz} | 0 ...ecs:633310,op:arith8,pos:439,val:+20.buzz} | 0 ...062258,execs:94996,op:quick,pos:1624.buzz} | 0 ...cs:633895,op:arith8,pos:1177,val:+27.buzz} | 0 ...095426,execs:95116,op:quick,pos:1732.buzz} | 0 ...919895,execs:647201,op:quick,pos:145.buzz} | 0 ...7,execs:98774,op:quick,pos:42,val:+4.buzz} | 0 ...88552,execs:648170,op:quick,pos:1113.buzz} | 0 ...3,execs:98814,op:quick,pos:82,val:+4.buzz} | 0 ...29965,execs:648988,op:quick,pos:1906.buzz} | 0 ...,execs:98934,op:quick,pos:178,val:+4.buzz} | 0 ...303517,execs:690662,op:quick,pos:488.buzz} | 0 ...,execs:99336,op:quick,pos:543,val:+4.buzz} | 0 ...552579,execs:700399,op:quick,pos:361.buzz} | 0 ...,execs:99379,op:quick,pos:574,val:+4.buzz} | 0 ...72114514,execs:710320,op:havoc,rep:4.buzz} | 0 ...execs:99951,op:quick,pos:1097,val:+4.buzz} | 0 ...859960,execs:712036,op:quick,pos:545.buzz} | 0 ...cs:101095,op:arith8,pos:1177,val:-14.buzz} | 0 ...281587,execs:738632,op:quick,pos:111.buzz} | 0 ...e:21391248,execs:104731,op:inf,rep:3.buzz} | 0 ...306068,execs:738725,op:quick,pos:179.buzz} | 0 ...execs:105821,op:quick,pos:763,val:+3.buzz} | 0 ...55026,execs:744458,op:quick,pos:1146.buzz} | 0 ...execs:105842,op:quick,pos:772,val:+3.buzz} | 0 ...673300,execs:748408,op:quick,pos:793.buzz} | 0 ...xecs:106146,op:quick,pos:1039,val:+3.buzz} | 0 ...493256,execs:772257,op:quick,pos:192.buzz} | 0 ...xecs:106523,op:quick,pos:1379,val:+3.buzz} | 0 ...9032794,execs:779095,op:quick,pos:96.buzz} | 0 ...xecs:106794,op:quick,pos:1638,val:+3.buzz} | 0 ...421710,execs:779774,op:quick,pos:774.buzz} | 0 ...xecs:106813,op:quick,pos:1645,val:+3.buzz} | 0 ...97600,execs:801006,op:quick,pos:1056.buzz} | 0 ...xecs:106843,op:quick,pos:1675,val:+3.buzz} | 0 ...594135,execs:814057,op:quick,pos:422.buzz} | 0 ...085529,execs:107218,op:flip2,pos:166.buzz} | 0 ...75942,execs:815845,op:quick,pos:2197.buzz} | 0 ...22793575,execs:109779,op:havoc,rep:2.buzz} | Bin ...248786,execs:827898,op:quick,pos:489.buzz} | 0 ...23096210,execs:110896,op:havoc,rep:2.buzz} | 0 ...691712,execs:829235,op:quick,pos:275.buzz} | 0 ...xecs:116699,op:quick,pos:1732,val:+2.buzz} | 0 ...03941473,execs:834350,op:quick,pos:8.buzz} | 0 ...xecs:116894,op:quick,pos:1903,val:+2.buzz} | 0 ...89712,execs:835926,op:quick,pos:1523.buzz} | 0 ...xecs:116921,op:quick,pos:1930,val:+2.buzz} | 0 ...435280,execs:839748,op:quick,pos:270.buzz} | 0 ...xecs:116978,op:quick,pos:1975,val:+2.buzz} | 0 ...967608,execs:860605,op:quick,pos:214.buzz} | 0 ...e:26456345,execs:123726,op:inf,rep:3.buzz} | 0 ...211283,execs:873047,op:quick,pos:164.buzz} | 0 ...e:26522012,execs:123960,op:inf,rep:3.buzz} | 0 ...275257,execs:873288,op:quick,pos:380.buzz} | 0 ...27533658,execs:127407,op:havoc,rep:2.buzz} | 0 ...362282,execs:873607,op:quick,pos:650.buzz} | 0 ...27575102,execs:127519,op:havoc,rep:2.buzz} | 0 ...71338,execs:874019,op:quick,pos:1037.buzz} | 0 ...27601964,execs:127607,op:havoc,rep:2.buzz} | 0 ...62447,execs:874357,op:quick,pos:1350.buzz} | 0 ...27613589,execs:127646,op:havoc,rep:2.buzz} | 0 ...6472182,execs:880398,op:quick,pos:95.buzz} | 0 ...27670992,execs:127846,op:havoc,rep:1.buzz} | 0 ...27946896,execs:128742,op:havoc,rep:1.buzz} | 0 ...28222078,execs:129633,op:havoc,rep:2.buzz} | 0 ...execs:130776,op:quick,pos:272,val:+1.buzz} | Bin ...execs:131137,op:quick,pos:620,val:+1.buzz} | 0 ...execs:133450,op:quick,pos:452,val:+3.buzz} | 0 ...xecs:135059,op:arith8,pos:13,val:+26.buzz} | 0 ...9407430,execs:135235,op:havoc,rep:13.buzz} | Bin ...9420002,execs:135521,op:havoc,rep:15.buzz} | Bin ...9420590,execs:135536,op:havoc,rep:13.buzz} | 0 ...29450311,execs:136209,op:havoc,rep:9.buzz} | Bin ...9492045,execs:137161,op:havoc,rep:10.buzz} | Bin ...9503454,execs:137426,op:havoc,rep:12.buzz} | 0 ...9522839,execs:137871,op:havoc,rep:14.buzz} | Bin ...9549985,execs:138505,op:havoc,rep:10.buzz} | 0 ...:29630501,execs:139797,op:inf,rep:12.buzz} | 0 ...:29630595,execs:139798,op:inf,rep:12.buzz} | 0 ...9775683,execs:141256,op:flip1,pos:69.buzz} | 0 ...,execs:147988,op:quick,pos:96,val:+1.buzz} | 0 ...execs:148098,op:quick,pos:206,val:+1.buzz} | 0 ...execs:148338,op:quick,pos:432,val:+1.buzz} | 0 ...execs:148412,op:quick,pos:505,val:+1.buzz} | 0 ...execs:148578,op:quick,pos:646,val:+1.buzz} | 0 ...execs:148928,op:quick,pos:945,val:+1.buzz} | 0 ...execs:148980,op:quick,pos:973,val:+1.buzz} | 0 ...xecs:149571,op:quick,pos:1167,val:+1.buzz} | 0 ...xecs:149663,op:quick,pos:1187,val:+1.buzz} | 0 ...xecs:149681,op:quick,pos:1193,val:+1.buzz} | 0 ...xecs:149683,op:quick,pos:1195,val:+1.buzz} | 0 ...33486227,execs:154769,op:havoc,rep:1.buzz} | 0 ...33501291,execs:154794,op:havoc,rep:2.buzz} | 0 ...33514023,execs:154818,op:havoc,rep:1.buzz} | 0 ...execs:158766,op:quick,pos:413,val:+2.buzz} | 0 ...ecs:159728,op:arith8,pos:420,val:+13.buzz} | 0 ...execs:162414,op:quick,pos:543,val:+2.buzz} | 0 ...xecs:163029,op:quick,pos:1084,val:+2.buzz} | 0 ...40958,execs:163656,op:flip16,pos:955.buzz} | 0 ...e:37170525,execs:166260,op:inf,rep:2.buzz} | 0 ...execs:169564,op:quick,pos:151,val:+2.buzz} | 0 ...execs:169589,op:quick,pos:176,val:+2.buzz} | 0 ...execs:169650,op:quick,pos:237,val:+2.buzz} | 0 ...execs:169661,op:quick,pos:248,val:+2.buzz} | 0 ...execs:169668,op:quick,pos:255,val:+2.buzz} | 0 ...execs:177607,op:quick,pos:410,val:+4.buzz} | 0 ...39870522,execs:179236,op:havoc,rep:4.buzz} | Bin ...xecs:182234,op:quick,pos:1361,val:+4.buzz} | 0 ...e:45661354,execs:195188,op:inf,rep:7.buzz} | 0 ...execs:198251,op:quick,pos:106,val:+6.buzz} | 0 ...xecs:213759,op:arith8,pos:362,val:+5.buzz} | 0 ...ecs:214311,op:arith8,pos:683,val:+26.buzz} | 0 ...ecs:214478,op:arith8,pos:781,val:+26.buzz} | 0 ...execs:222520,op:quick,pos:198,val:+2.buzz} | 0 ...xecs:227532,op:quick,pos:1189,val:+2.buzz} | 0 ...xecs:227545,op:quick,pos:1202,val:+2.buzz} | 0 ...82604,execs:228188,op:flip1,pos:1167.buzz} | 0 ...22773,execs:228312,op:flip2,pos:1187.buzz} | 0 ...53605,execs:228408,op:flip4,pos:1167.buzz} | 0 ...cs:229022,op:arith8,pos:1187,val:-10.buzz} | 0 ...xecs:231465,op:quick,pos:1191,val:+6.buzz} | 0 ...xecs:231476,op:quick,pos:1202,val:+6.buzz} | 0 ...54426132,execs:233561,op:havoc,rep:1.buzz} | 0 ...execs:235381,op:quick,pos:122,val:+4.buzz} | 0 ...4885789,execs:235917,op:flip32,pos:3.buzz} | Bin ...4897658,execs:236191,op:havoc,rep:15.buzz} | 0 ...4915177,execs:236611,op:havoc,rep:14.buzz} | 0 ...4918057,execs:236681,op:havoc,rep:16.buzz} | 0 ...4926618,execs:236882,op:havoc,rep:14.buzz} | 0 ...4942338,execs:237257,op:havoc,rep:15.buzz} | 0 ...4965944,execs:237841,op:havoc,rep:15.buzz} | Bin ...55034933,execs:239470,op:havoc,rep:5.buzz} | 0 ...5084384,execs:240661,op:havoc,rep:10.buzz} | Bin ...5102023,execs:241087,op:havoc,rep:12.buzz} | Bin ...ecs:244791,op:arith8,pos:468,val:+26.buzz} | 0 ...execs:248805,op:quick,pos:596,val:+2.buzz} | 0 ...e:57646435,execs:250539,op:inf,rep:5.buzz} | 0 ...execs:251516,op:quick,pos:762,val:+5.buzz} | 0 ...xecs:252235,op:quick,pos:1347,val:+5.buzz} | 0 ...58572284,execs:254163,op:havoc,rep:3.buzz} | Bin ...58585555,execs:254223,op:havoc,rep:2.buzz} | 0 ...58663945,execs:254571,op:havoc,rep:2.buzz} | 0 ...58681715,execs:254650,op:havoc,rep:4.buzz} | Bin ...58977780,execs:255922,op:havoc,rep:4.buzz} | Bin ...59042763,execs:256202,op:havoc,rep:4.buzz} | 0 ...59124537,execs:256553,op:havoc,rep:2.buzz} | 0 ...59235059,execs:257029,op:havoc,rep:1.buzz} | 0 ...59358971,execs:257542,op:havoc,rep:1.buzz} | 0 ...59479191,execs:258032,op:havoc,rep:2.buzz} | Bin ...e:60321735,execs:261733,op:inf,rep:1.buzz} | 0 ...61063439,execs:264478,op:havoc,rep:7.buzz} | Bin ...xecs:267045,op:quick,pos:1356,val:+7.buzz} | 0 ...xecs:270064,op:quick,pos:265,val:+11.buzz} | 0 ...xecs:270152,op:quick,pos:341,val:+11.buzz} | 0 ...cs:277373,op:arith8,pos:1097,val:+28.buzz} | 0 ...64274306,execs:278459,op:havoc,rep:2.buzz} | 0 ...983681,execs:290801,op:quick,pos:299.buzz} | 0 ...514570,execs:293548,op:quick,pos:111.buzz} | 0 ...762636,execs:300111,op:quick,pos:331.buzz} | 0 ...893120,execs:300650,op:quick,pos:868.buzz} | 0 ...94477,execs:301064,op:quick,pos:1257.buzz} | 0 ...1705596,execs:312341,op:quick,pos:62.buzz} | Bin ...ecs:315245,op:arith8,pos:458,val:+28.buzz} | 0 ...638050,execs:316690,op:quick,pos:248.buzz} | 0 ...xecs:317104,op:arith8,pos:137,val:+5.buzz} | 0 ...e:73193810,execs:319768,op:inf,rep:4.buzz} | 0 ...15488,execs:324164,op:quick,pos:1683.buzz} | 0 ...4464538,execs:324402,op:quick,pos:78.buzz} | 0 ...32260,execs:330699,op:quick,pos:1186.buzz} | 0 ...33152,execs:330702,op:quick,pos:1189.buzz} | 0 ...33415,execs:330703,op:quick,pos:1190.buzz} | 0 ...38104,execs:330717,op:quick,pos:1204.buzz} | 0 ...xecs:331567,op:arith8,pos:827,val:+5.buzz} | 0 ...400261,execs:342468,op:quick,pos:232.buzz} | 0 ...62475,execs:359210,op:quick,pos:1361.buzz} | 0 ...4869130,execs:364710,op:quick,pos:60.buzz} | 0 ...908720,execs:364893,op:quick,pos:231.buzz} | 0 ...983967,execs:365215,op:quick,pos:552.buzz} | 0 ...86923124,execs:373881,op:havoc,rep:2.buzz} | 0 ...910948,execs:378156,op:quick,pos:290.buzz} | 0 ...82776,execs:380377,op:flip32,pos:291.buzz} | 0 ...ecs:380418,op:arith8,pos:291,val:-27.buzz} | 0 ...328446,execs:384726,op:quick,pos:270.buzz} | 0 ...03853,execs:390606,op:quick,pos:1260.buzz} | 0 ...90997899,execs:391555,op:havoc,rep:5.buzz} | 0 ...03472,execs:397259,op:quick,pos:1187.buzz} | 0 ...ecs:401419,op:arith8,pos:464,val:+26.buzz} | 0 ...4833516,execs:411321,op:quick,pos:88.buzz} | 0 ...95632731,execs:413985,op:havoc,rep:3.buzz} | 0 ...88567,execs:423495,op:quick,pos:1361.buzz} | 0 ...745206,execs:427456,op:quick,pos:113.buzz} | 0 ...732791,execs:431227,op:quick,pos:510.buzz} | 0 ...796047,execs:431508,op:quick,pos:779.buzz} | 0 ...48507,execs:435529,op:quick,pos:1115.buzz} | 0 ...11010,execs:435723,op:quick,pos:1309.buzz} | 0 ...654402,execs:451921,op:quick,pos:206.buzz} | 0 ...04943562,execs:452954,op:havoc,rep:1.buzz} | 0 ...17054,execs:455456,op:quick,pos:1260.buzz} | 0 ...cs:477593,op:arith8,pos:1166,val:+14.buzz} | 0 ...03982,execs:480343,op:quick,pos:1362.buzz} | 0 ...42104,execs:480469,op:quick,pos:1488.buzz} | 0 ...340414,execs:482618,op:quick,pos:956.buzz} | 0 ...13712,execs:482862,op:quick,pos:1188.buzz} | 0 ...043394,execs:485148,op:quick,pos:357.buzz} | 0 ...93274,execs:491945,op:quick,pos:2001.buzz} | 0 ...57430,execs:492186,op:quick,pos:2242.buzz} | 0 ...8052,execs:492262,op:flip32,pos:2243.buzz} | 0 ...4828037,execs:492473,op:havoc,rep:13.buzz} | Bin ...4839245,execs:492527,op:havoc,rep:10.buzz} | 0 ...48763,execs:499499,op:quick,pos:1260.buzz} | 0 ...74513,execs:510315,op:quick,pos:1274.buzz} | 0 ...120510785,execs:513697,op:inf,rep:11.buzz} | 0 ...120513847,execs:513711,op:inf,rep:11.buzz} | 0 ...066290,execs:516173,op:quick,pos:187.buzz} | 0 ...60443,execs:522183,op:quick,pos:1361.buzz} | 0 ...25396,execs:525714,op:quick,pos:1415.buzz} | 0 ...xecs:526124,op:arith8,pos:414,val:+5.buzz} | 0 ...4013546,execs:527527,op:quick,pos:92.buzz} | 0 ...136371,execs:528043,op:quick,pos:595.buzz} | 0 ...145431,execs:528083,op:quick,pos:635.buzz} | 0 ...161290,execs:528144,op:quick,pos:695.buzz} | 0 ...192242,execs:528270,op:quick,pos:821.buzz} | 0 ...37297,execs:528463,op:quick,pos:1002.buzz} | 0 ...79900,execs:528642,op:quick,pos:1169.buzz} | 0 ...784112,execs:530854,op:quick,pos:395.buzz} | 0 ...6023882,execs:536351,op:quick,pos:53.buzz} | 0 ...078535,execs:536579,op:quick,pos:221.buzz} | 0 ...145735,execs:536866,op:quick,pos:435.buzz} | 0 ...220134,execs:537174,op:quick,pos:731.buzz} | 0 ...97966,execs:537481,op:quick,pos:1013.buzz} | 0 ...78354,execs:537804,op:quick,pos:1324.buzz} | 0 ...459384,execs:538148,op:flip2,pos:633.buzz} | 0 ...546242,execs:551523,op:quick,pos:395.buzz} | 0 ...30658572,execs:556311,op:havoc,rep:4.buzz} | 0 ...50132,execs:560931,op:quick,pos:1345.buzz} | 0 ...660299,execs:564792,op:quick,pos:207.buzz} | 0 ...17591,execs:570429,op:quick,pos:1260.buzz} | 0 ...86905,execs:576825,op:quick,pos:1260.buzz} | 0 ...68601,execs:583673,op:quick,pos:1856.buzz} | 0 ...12253,execs:583835,op:quick,pos:2018.buzz} | 0 ...38188207,execs:584123,op:quick,pos:2.buzz} | 0 ...94940,execs:587182,op:quick,pos:1189.buzz} | 0 ...00332,execs:587197,op:quick,pos:1204.buzz} | 0 ...305450,execs:592573,op:quick,pos:856.buzz} | 0 ...02542,execs:592943,op:quick,pos:1226.buzz} | 0 ...285424,execs:596810,op:quick,pos:413.buzz} | 0 ...307178,execs:596896,op:quick,pos:499.buzz} | 0 ...:142070148,execs:600480,op:inf,rep:3.buzz} | 0 ...136589,execs:600758,op:quick,pos:241.buzz} | 0 ...57467,execs:601586,op:quick,pos:1045.buzz} | 0 ...2624841,execs:602729,op:quick,pos:58.buzz} | 0 ...526968,execs:604368,op:quick,pos:542.buzz} | 0 ...:144228542,execs:606645,op:inf,rep:2.buzz} | 0 ...03637,execs:608378,op:quick,pos:1707.buzz} | 0 ...92309,execs:616204,op:quick,pos:1378.buzz} | 0 ...16543,execs:629065,op:quick,pos:1361.buzz} | 0 ...244497,execs:631388,op:quick,pos:487.buzz} | 0 ...507726,execs:632383,op:flip1,pos:107.buzz} | 0 ...52669967,execs:637308,op:havoc,rep:1.buzz} | 0 ...376684,execs:640072,op:quick,pos:292.buzz} | 0 ...89306,execs:648173,op:quick,pos:1116.buzz} | 0 ...07778,execs:648242,op:quick,pos:1173.buzz} | 0 ...57724,execs:648416,op:quick,pos:1347.buzz} | 0 ...91485,execs:657110,op:quick,pos:1260.buzz} | 0 ...158098880,execs:659084,op:inf,rep:14.buzz} | 0 ...00099,execs:665196,op:quick,pos:1330.buzz} | 0 ...48628,execs:669334,op:quick,pos:1266.buzz} | 0 ...01538,execs:674554,op:quick,pos:1361.buzz} | 0 ...63620812,execs:677989,op:havoc,rep:2.buzz} | 0 ...57626,execs:679854,op:quick,pos:1141.buzz} | 0 ...xecs:680152,op:arith8,pos:490,val:-3.buzz} | 0 ...xecs:680156,op:arith8,pos:490,val:-6.buzz} | 0 ...03629,execs:701244,op:quick,pos:1206.buzz} | 0 ...73964,execs:705329,op:quick,pos:1260.buzz} | 0 ...59313,execs:716841,op:quick,pos:1292.buzz} | 0 ...87920,execs:729142,op:quick,pos:1393.buzz} | 0 ...44890,execs:732799,op:quick,pos:1260.buzz} | 0 ...296864,execs:738689,op:quick,pos:168.buzz} | 0 ...342705,execs:738873,op:quick,pos:327.buzz} | 0 ...50642,execs:739707,op:quick,pos:1077.buzz} | 0 ...28496,execs:740022,op:flip1,pos:1076.buzz} | 0 ...476520,execs:743732,op:quick,pos:445.buzz} | 0 ...37390,execs:744389,op:quick,pos:1078.buzz} | 0 ...96544,execs:748803,op:quick,pos:1188.buzz} | 0 ...43666,execs:753180,op:quick,pos:1474.buzz} | 0 ...380055,execs:759046,op:quick,pos:874.buzz} | 0 ...85947638,execs:762936,op:havoc,rep:6.buzz} | 0 ...85958855,execs:763200,op:havoc,rep:6.buzz} | 0 ...85965568,execs:763363,op:havoc,rep:5.buzz} | 0 ...11538,execs:770090,op:quick,pos:1260.buzz} | 0 ...ecs:773131,op:arith8,pos:468,val:+26.buzz} | 0 ...90089968,execs:782430,op:havoc,rep:3.buzz} | Bin ...794291,execs:785175,op:quick,pos:479.buzz} | 0 ...82029,execs:785861,op:quick,pos:1141.buzz} | 0 ...91163494,execs:786074,op:havoc,rep:2.buzz} | 0 ...94971765,execs:798509,op:havoc,rep:8.buzz} | 0 ...:195386382,execs:799905,op:inf,rep:7.buzz} | 0 ...ecs:802454,op:arith8,pos:1724,val:+5.buzz} | 0 ...xecs:807322,op:quick,pos:1260,val:+5.buzz} | 0 ...30599,execs:815681,op:quick,pos:2046.buzz} | 0 ...37006,execs:821734,op:quick,pos:1361.buzz} | 0 ...57285,execs:824741,op:quick,pos:1391.buzz} | 0 ...1706085,execs:825883,op:quick,pos:25.buzz} | 0 ...xecs:828228,op:arith8,pos:276,val:-1.buzz} | 0 ...69834,execs:835857,op:quick,pos:1455.buzz} | 0 ...4828758,execs:837480,op:quick,pos:24.buzz} | 0 ...42945,execs:849859,op:quick,pos:1289.buzz} | 0 ...25042,execs:854084,op:quick,pos:1203.buzz} | 0 ...43357,execs:857721,op:quick,pos:1260.buzz} | 0 ...997661,execs:860745,op:quick,pos:354.buzz} | 0 ...86640,execs:870338,op:quick,pos:1166.buzz} | 0 ...22391,execs:870432,op:quick,pos:1260.buzz} | 0 ...61874,execs:873986,op:quick,pos:1005.buzz} | 0 ...70605,execs:874386,op:quick,pos:1379.buzz} | 0 ...xecs:879003,op:quick,pos:1804,val:+7.buzz} | 0 ...xecs:879173,op:quick,pos:1974,val:+7.buzz} | 0 ...79354,execs:879333,op:flip32,pos:155.buzz} | 0 ...16696,execs:890847,op:quick,pos:1260.buzz} | 0 ...0362784,execs:895852,op:quick,pos:47.buzz} | 0 ...0369367,execs:895883,op:quick,pos:54.buzz} | 0 ...0370374,execs:895888,op:quick,pos:59.buzz} | 0 ...494544,execs:896448,op:flip1,pos:132.buzz} | 0 ...510164,execs:896521,op:flip2,pos:347.buzz} | 0 ...1247072,execs:900392,op:quick,pos:60.buzz} | 0 ...21475319,execs:901376,op:havoc,rep:1.buzz} | 0 ...76476,execs:909947,op:quick,pos:1260.buzz} | 0 649 files changed, 14 insertions(+), 49 deletions(-) delete mode 100644 tests/fuzzed/README.txt rename tests/fuzzed/{id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0 => id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0.buzz} (100%) rename tests/fuzzed/{id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1 => id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1.buzz} (100%) rename tests/fuzzed/{id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1 => id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1.buzz} (100%) rename tests/fuzzed/{id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105 => id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105.buzz} (100%) rename tests/fuzzed/{id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1 => id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1.buzz} (100%) rename tests/fuzzed/{id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105 => id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105.buzz} (100%) rename tests/fuzzed/{id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1 => id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1.buzz} (100%) rename tests/fuzzed/{id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108 => id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108.buzz} (100%) rename tests/fuzzed/{id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1 => id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1.buzz} (100%) rename tests/fuzzed/{id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105 => id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105.buzz} (100%) rename tests/fuzzed/{id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1 => id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1.buzz} (100%) rename tests/fuzzed/{id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4 => id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66 => id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66.buzz} (100%) rename tests/fuzzed/{id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2 => id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1 => id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1.buzz} (100%) rename tests/fuzzed/{id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4 => id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1 => id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1.buzz} (100%) rename tests/fuzzed/{id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1 => id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4 => id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4.buzz} (100%) rename tests/fuzzed/{id:000009,src:000013,time:1937548,execs:24820,op:havoc,rep:2 => id:000009,src:000013,time:1937548,execs:24820,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000010,sig:06,src:000051,time:83385,execs:2556,op:flip4,pos:49 => id:000010,sig:06,src:000051,time:83385,execs:2556,op:flip4,pos:49.buzz} (100%) rename tests/fuzzed/{id:000010,src:000013,time:2225913,execs:26757,op:havoc,rep:4 => id:000010,src:000013,time:2225913,execs:26757,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000011,sig:06,src:000051,time:88769,execs:2664,op:flip32,pos:3 => id:000011,sig:06,src:000051,time:88769,execs:2664,op:flip32,pos:3.buzz} (100%) rename tests/fuzzed/{id:000011,src:000013,time:2297408,execs:27208,op:havoc,rep:1 => id:000011,src:000013,time:2297408,execs:27208,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000012,sig:06,src:000051,time:88966,execs:2669,op:flip32,pos:12 => id:000012,sig:06,src:000051,time:88966,execs:2669,op:flip32,pos:12.buzz} (100%) rename tests/fuzzed/{id:000012,src:000008,time:2817091,execs:29065,op:quick,pos:488,val:+1 => id:000012,src:000008,time:2817091,execs:29065,op:quick,pos:488,val:+1.buzz} (100%) rename tests/fuzzed/{id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5 => id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5.buzz} (100%) rename tests/fuzzed/{id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1 => id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1.buzz} (100%) rename tests/fuzzed/{id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23 => id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23.buzz} (100%) rename tests/fuzzed/{id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26 => id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26.buzz} (100%) rename tests/fuzzed/{id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23 => id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23.buzz} (100%) rename tests/fuzzed/{id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28 => id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28.buzz} (100%) rename tests/fuzzed/{id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30 => id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30.buzz} (100%) rename tests/fuzzed/{id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2 => id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35 => id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35.buzz} (100%) rename tests/fuzzed/{id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1 => id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1.buzz} (100%) rename tests/fuzzed/{id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6 => id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6.buzz} (100%) rename tests/fuzzed/{id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6 => id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6.buzz} (100%) rename tests/fuzzed/{id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1 => id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1.buzz} (100%) rename tests/fuzzed/{id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10 => id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10.buzz} (100%) rename tests/fuzzed/{id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1 => id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1.buzz} (100%) rename tests/fuzzed/{id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14 => id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1 => id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1.buzz} (100%) rename tests/fuzzed/{id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11 => id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11.buzz} (100%) rename tests/fuzzed/{id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1 => id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5 => id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5.buzz} (100%) rename tests/fuzzed/{id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2 => id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2.buzz} (100%) rename tests/fuzzed/{id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16 => id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16.buzz} (100%) rename tests/fuzzed/{id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2 => id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2.buzz} (100%) rename tests/fuzzed/{id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13 => id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13.buzz} (100%) rename tests/fuzzed/{id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2 => id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2.buzz} (100%) rename tests/fuzzed/{id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6 => id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6.buzz} (100%) rename tests/fuzzed/{id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2 => id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2.buzz} (100%) rename tests/fuzzed/{id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14 => id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2 => id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2.buzz} (100%) rename tests/fuzzed/{id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9 => id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9.buzz} (100%) rename tests/fuzzed/{id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2 => id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2.buzz} (100%) rename tests/fuzzed/{id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14 => id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3 => id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10 => id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10.buzz} (100%) rename tests/fuzzed/{id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3 => id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4 => id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1 => id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16 => id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16.buzz} (100%) rename tests/fuzzed/{id:000034,src:000042,time:13064132,execs:70410,op:quick,pos:868 => id:000034,src:000042,time:13064132,execs:70410,op:quick,pos:868.buzz} (100%) rename tests/fuzzed/{id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6 => id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6.buzz} (100%) rename tests/fuzzed/{id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182 => id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182.buzz} (100%) rename tests/fuzzed/{id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7 => id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7.buzz} (100%) rename tests/fuzzed/{id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413 => id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413.buzz} (100%) rename tests/fuzzed/{id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15 => id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15.buzz} (100%) rename tests/fuzzed/{id:000037,src:000042,time:13686254,execs:72978,op:havoc,rep:1 => id:000037,src:000042,time:13686254,execs:72978,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13 => id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13.buzz} (100%) rename tests/fuzzed/{id:000038,src:000042,time:14303774,execs:75567,op:havoc,rep:2 => id:000038,src:000042,time:14303774,execs:75567,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9 => id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9.buzz} (100%) rename tests/fuzzed/{id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1 => id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1.buzz} (100%) rename tests/fuzzed/{id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12 => id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12.buzz} (100%) rename tests/fuzzed/{id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1 => id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1.buzz} (100%) rename tests/fuzzed/{id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9 => id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9.buzz} (100%) rename tests/fuzzed/{id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1 => id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1.buzz} (100%) rename tests/fuzzed/{id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4 => id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96 => id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96.buzz} (100%) rename tests/fuzzed/{id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11 => id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11.buzz} (100%) rename tests/fuzzed/{id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617 => id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617.buzz} (100%) rename tests/fuzzed/{id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14 => id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000044,src:000003,time:19033188,execs:94894,op:quick,pos:1522 => id:000044,src:000003,time:19033188,execs:94894,op:quick,pos:1522.buzz} (100%) rename tests/fuzzed/{id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6 => id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6.buzz} (100%) rename tests/fuzzed/{id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774 => id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774.buzz} (100%) rename tests/fuzzed/{id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15 => id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15.buzz} (100%) rename tests/fuzzed/{id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4 => id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4.buzz} (100%) rename tests/fuzzed/{id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14 => id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4 => id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4.buzz} (100%) rename tests/fuzzed/{id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16 => id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16.buzz} (100%) rename tests/fuzzed/{id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4 => id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4.buzz} (100%) rename tests/fuzzed/{id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16 => id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16.buzz} (100%) rename tests/fuzzed/{id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3 => id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3.buzz} (100%) rename tests/fuzzed/{id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6 => id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6.buzz} (100%) rename tests/fuzzed/{id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3 => id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3.buzz} (100%) rename tests/fuzzed/{id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16 => id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16.buzz} (100%) rename tests/fuzzed/{id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3 => id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3.buzz} (100%) rename tests/fuzzed/{id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13 => id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13.buzz} (100%) rename tests/fuzzed/{id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3 => id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3.buzz} (100%) rename tests/fuzzed/{id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14 => id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3 => id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3.buzz} (100%) rename tests/fuzzed/{id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13 => id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13.buzz} (100%) rename tests/fuzzed/{id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2 => id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8 => id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8.buzz} (100%) rename tests/fuzzed/{id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2 => id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2.buzz} (100%) rename tests/fuzzed/{id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2 => id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2 => id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2.buzz} (100%) rename tests/fuzzed/{id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12 => id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12.buzz} (100%) rename tests/fuzzed/{id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3 => id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3.buzz} (100%) rename tests/fuzzed/{id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11 => id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11.buzz} (100%) rename tests/fuzzed/{id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3 => id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3.buzz} (100%) rename tests/fuzzed/{id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7 => id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7.buzz} (100%) rename tests/fuzzed/{id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3 => id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3.buzz} (100%) rename tests/fuzzed/{id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13 => id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13.buzz} (100%) rename tests/fuzzed/{id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3 => id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3.buzz} (100%) rename tests/fuzzed/{id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5 => id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5.buzz} (100%) rename tests/fuzzed/{id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3 => id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3.buzz} (100%) rename tests/fuzzed/{id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26 => id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26.buzz} (100%) rename tests/fuzzed/{id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3 => id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3.buzz} (100%) rename tests/fuzzed/{id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5 => id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5.buzz} (100%) rename tests/fuzzed/{id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3 => id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3.buzz} (100%) rename tests/fuzzed/{id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4 => id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3 => id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3.buzz} (100%) rename tests/fuzzed/{id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1 => id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3 => id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3.buzz} (100%) rename tests/fuzzed/{id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2 => id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3 => id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3.buzz} (100%) rename tests/fuzzed/{id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1 => id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1.buzz} (100%) rename tests/fuzzed/{id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3 => id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3.buzz} (100%) rename tests/fuzzed/{id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1 => id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1.buzz} (100%) rename tests/fuzzed/{id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3 => id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3.buzz} (100%) rename tests/fuzzed/{id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1 => id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1.buzz} (100%) rename tests/fuzzed/{id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3 => id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3.buzz} (100%) rename tests/fuzzed/{id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8 => id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8.buzz} (100%) rename tests/fuzzed/{id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3 => id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3.buzz} (100%) rename tests/fuzzed/{id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7 => id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7.buzz} (100%) rename tests/fuzzed/{id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3 => id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3.buzz} (100%) rename tests/fuzzed/{id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3 => id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3 => id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3.buzz} (100%) rename tests/fuzzed/{id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4 => id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3 => id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3.buzz} (100%) rename tests/fuzzed/{id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5 => id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5.buzz} (100%) rename tests/fuzzed/{id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1 => id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3 => id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2 => id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1 => id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1.buzz} (100%) rename tests/fuzzed/{id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1 => id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1 => id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1.buzz} (100%) rename tests/fuzzed/{id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2 => id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1 => id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1.buzz} (100%) rename tests/fuzzed/{id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1 => id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1.buzz} (100%) rename tests/fuzzed/{id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1 => id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1.buzz} (100%) rename tests/fuzzed/{id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3 => id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3.buzz} (100%) rename tests/fuzzed/{id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1 => id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1.buzz} (100%) rename tests/fuzzed/{id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3 => id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3.buzz} (100%) rename tests/fuzzed/{id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1 => id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1.buzz} (100%) rename tests/fuzzed/{id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1 => id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1.buzz} (100%) rename tests/fuzzed/{id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1 => id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1.buzz} (100%) rename tests/fuzzed/{id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1 => id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1.buzz} (100%) rename tests/fuzzed/{id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1 => id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1.buzz} (100%) rename tests/fuzzed/{id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1 => id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1.buzz} (100%) rename tests/fuzzed/{id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1 => id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1.buzz} (100%) rename tests/fuzzed/{id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1 => id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1.buzz} (100%) rename tests/fuzzed/{id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60 => id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60.buzz} (100%) rename tests/fuzzed/{id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1 => id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1.buzz} (100%) rename tests/fuzzed/{id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186 => id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186.buzz} (100%) rename tests/fuzzed/{id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1 => id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1.buzz} (100%) rename tests/fuzzed/{id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186 => id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186.buzz} (100%) rename tests/fuzzed/{id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1 => id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1.buzz} (100%) rename tests/fuzzed/{id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239 => id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239.buzz} (100%) rename tests/fuzzed/{id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1 => id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1.buzz} (100%) rename tests/fuzzed/{id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239 => id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239.buzz} (100%) rename tests/fuzzed/{id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1 => id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243 => id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243.buzz} (100%) rename tests/fuzzed/{id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102 => id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102.buzz} (100%) rename tests/fuzzed/{id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317 => id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317.buzz} (100%) rename tests/fuzzed/{id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2 => id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2.buzz} (100%) rename tests/fuzzed/{id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3 => id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3.buzz} (100%) rename tests/fuzzed/{id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2 => id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2.buzz} (100%) rename tests/fuzzed/{id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27 => id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27.buzz} (100%) rename tests/fuzzed/{id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2 => id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2.buzz} (100%) rename tests/fuzzed/{id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35 => id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35.buzz} (100%) rename tests/fuzzed/{id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2 => id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2.buzz} (100%) rename tests/fuzzed/{id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34 => id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34.buzz} (100%) rename tests/fuzzed/{id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2 => id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2.buzz} (100%) rename tests/fuzzed/{id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34 => id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34.buzz} (100%) rename tests/fuzzed/{id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2 => id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2.buzz} (100%) rename tests/fuzzed/{id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3 => id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2 => id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2.buzz} (100%) rename tests/fuzzed/{id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1 => id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2 => id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2.buzz} (100%) rename tests/fuzzed/{id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7 => id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7.buzz} (100%) rename tests/fuzzed/{id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2 => id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2.buzz} (100%) rename tests/fuzzed/{id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5 => id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5.buzz} (100%) rename tests/fuzzed/{id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1 => id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1.buzz} (100%) rename tests/fuzzed/{id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8 => id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8.buzz} (100%) rename tests/fuzzed/{id:000101,src:001614,time:48112006,execs:208056,op:quick,pos:1162,val:+2 => id:000101,src:001614,time:48112006,execs:208056,op:quick,pos:1162,val:+2.buzz} (100%) rename tests/fuzzed/{id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6 => id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6.buzz} (100%) rename tests/fuzzed/{id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1 => id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1.buzz} (100%) rename tests/fuzzed/{id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2 => id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2 => id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2.buzz} (100%) rename tests/fuzzed/{id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5 => id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5.buzz} (100%) rename tests/fuzzed/{id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2 => id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2.buzz} (100%) rename tests/fuzzed/{id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4 => id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6 => id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6.buzz} (100%) rename tests/fuzzed/{id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3 => id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3.buzz} (100%) rename tests/fuzzed/{id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6 => id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6.buzz} (100%) rename tests/fuzzed/{id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3 => id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3.buzz} (100%) rename tests/fuzzed/{id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3 => id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3.buzz} (100%) rename tests/fuzzed/{id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3 => id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3.buzz} (100%) rename tests/fuzzed/{id:000108,src:000737,time:57203088,execs:248698,op:quick,pos:489,val:+2 => id:000108,src:000737,time:57203088,execs:248698,op:quick,pos:489,val:+2.buzz} (100%) rename tests/fuzzed/{id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14 => id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000109,src:000032,time:57809166,execs:251158,op:quick,pos:453,val:+5 => id:000109,src:000032,time:57809166,execs:251158,op:quick,pos:453,val:+5.buzz} (100%) rename tests/fuzzed/{id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4 => id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5 => id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5.buzz} (100%) rename tests/fuzzed/{id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5 => id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5.buzz} (100%) rename tests/fuzzed/{id:000111,src:000032,time:57910553,execs:251551,op:quick,pos:796,val:+5 => id:000111,src:000032,time:57910553,execs:251551,op:quick,pos:796,val:+5.buzz} (100%) rename tests/fuzzed/{id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3 => id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000112,src:000032,time:57996622,execs:251899,op:quick,pos:1035,val:+5 => id:000112,src:000032,time:57996622,execs:251899,op:quick,pos:1035,val:+5.buzz} (100%) rename tests/fuzzed/{id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7 => id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7.buzz} (100%) rename tests/fuzzed/{id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5 => id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5.buzz} (100%) rename tests/fuzzed/{id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15 => id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15.buzz} (100%) rename tests/fuzzed/{id:000114,src:000032,time:58557878,execs:254103,op:havoc,rep:3 => id:000114,src:000032,time:58557878,execs:254103,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7 => id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7.buzz} (100%) rename tests/fuzzed/{id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2 => id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7 => id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7.buzz} (100%) rename tests/fuzzed/{id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7 => id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7.buzz} (100%) rename tests/fuzzed/{id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1 => id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11 => id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11.buzz} (100%) rename tests/fuzzed/{id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2 => id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82 => id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82.buzz} (100%) rename tests/fuzzed/{id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1 => id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256 => id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256.buzz} (100%) rename tests/fuzzed/{id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34 => id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34.buzz} (100%) rename tests/fuzzed/{id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373 => id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373.buzz} (100%) rename tests/fuzzed/{id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125 => id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125.buzz} (100%) rename tests/fuzzed/{id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807 => id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807.buzz} (100%) rename tests/fuzzed/{id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126 => id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126.buzz} (100%) rename tests/fuzzed/{id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161 => id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161.buzz} (100%) rename tests/fuzzed/{id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130 => id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130.buzz} (100%) rename tests/fuzzed/{id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239 => id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239.buzz} (100%) rename tests/fuzzed/{id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167 => id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167.buzz} (100%) rename tests/fuzzed/{id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339 => id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339.buzz} (100%) rename tests/fuzzed/{id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200 => id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200.buzz} (100%) rename tests/fuzzed/{id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199 => id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199.buzz} (100%) rename tests/fuzzed/{id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234 => id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234.buzz} (100%) rename tests/fuzzed/{id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575 => id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575.buzz} (100%) rename tests/fuzzed/{id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105 => id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105.buzz} (100%) rename tests/fuzzed/{id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778 => id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778.buzz} (100%) rename tests/fuzzed/{id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2 => id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2.buzz} (100%) rename tests/fuzzed/{id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938 => id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938.buzz} (100%) rename tests/fuzzed/{id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2 => id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2.buzz} (100%) rename tests/fuzzed/{id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318 => id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318.buzz} (100%) rename tests/fuzzed/{id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2 => id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2.buzz} (100%) rename tests/fuzzed/{id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187 => id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187.buzz} (100%) rename tests/fuzzed/{id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2 => id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2.buzz} (100%) rename tests/fuzzed/{id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9 => id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9.buzz} (100%) rename tests/fuzzed/{id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224 => id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224.buzz} (100%) rename tests/fuzzed/{id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139 => id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139.buzz} (100%) rename tests/fuzzed/{id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289 => id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289.buzz} (100%) rename tests/fuzzed/{id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241 => id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241.buzz} (100%) rename tests/fuzzed/{id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986 => id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986.buzz} (100%) rename tests/fuzzed/{id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272 => id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272.buzz} (100%) rename tests/fuzzed/{id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084 => id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084.buzz} (100%) rename tests/fuzzed/{id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283 => id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283.buzz} (100%) rename tests/fuzzed/{id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309 => id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309.buzz} (100%) rename tests/fuzzed/{id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179 => id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179.buzz} (100%) rename tests/fuzzed/{id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110 => id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110.buzz} (100%) rename tests/fuzzed/{id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335 => id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335.buzz} (100%) rename tests/fuzzed/{id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112 => id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112.buzz} (100%) rename tests/fuzzed/{id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148 => id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148.buzz} (100%) rename tests/fuzzed/{id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2 => id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385 => id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385.buzz} (100%) rename tests/fuzzed/{id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1 => id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271 => id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271.buzz} (100%) rename tests/fuzzed/{id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2 => id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188 => id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188.buzz} (100%) rename tests/fuzzed/{id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1 => id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275 => id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275.buzz} (100%) rename tests/fuzzed/{id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2 => id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486 => id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486.buzz} (100%) rename tests/fuzzed/{id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2 => id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424 => id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424.buzz} (100%) rename tests/fuzzed/{id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1 => id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213 => id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213.buzz} (100%) rename tests/fuzzed/{id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2 => id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276 => id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276.buzz} (100%) rename tests/fuzzed/{id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1 => id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1.buzz} (100%) rename tests/fuzzed/{id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269 => id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269.buzz} (100%) rename tests/fuzzed/{id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1 => id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1.buzz} (100%) rename tests/fuzzed/{id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564 => id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564.buzz} (100%) rename tests/fuzzed/{id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1 => id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1.buzz} (100%) rename tests/fuzzed/{id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242 => id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242.buzz} (100%) rename tests/fuzzed/{id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1 => id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1.buzz} (100%) rename tests/fuzzed/{id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520 => id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520.buzz} (100%) rename tests/fuzzed/{id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1 => id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1.buzz} (100%) rename tests/fuzzed/{id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2 => id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1 => id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1.buzz} (100%) rename tests/fuzzed/{id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995 => id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995.buzz} (100%) rename tests/fuzzed/{id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1 => id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1.buzz} (100%) rename tests/fuzzed/{id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98 => id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98.buzz} (100%) rename tests/fuzzed/{id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1 => id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1.buzz} (100%) rename tests/fuzzed/{id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650 => id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650.buzz} (100%) rename tests/fuzzed/{id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1 => id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1.buzz} (100%) rename tests/fuzzed/{id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330 => id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330.buzz} (100%) rename tests/fuzzed/{id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1 => id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1.buzz} (100%) rename tests/fuzzed/{id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917 => id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917.buzz} (100%) rename tests/fuzzed/{id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1 => id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1.buzz} (100%) rename tests/fuzzed/{id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144 => id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144.buzz} (100%) rename tests/fuzzed/{id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1 => id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1.buzz} (100%) rename tests/fuzzed/{id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8 => id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8.buzz} (100%) rename tests/fuzzed/{id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1 => id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1.buzz} (100%) rename tests/fuzzed/{id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200 => id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200.buzz} (100%) rename tests/fuzzed/{id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367 => id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367.buzz} (100%) rename tests/fuzzed/{id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289 => id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289.buzz} (100%) rename tests/fuzzed/{id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105 => id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105.buzz} (100%) rename tests/fuzzed/{id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671 => id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671.buzz} (100%) rename tests/fuzzed/{id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597 => id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597.buzz} (100%) rename tests/fuzzed/{id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20 => id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20.buzz} (100%) rename tests/fuzzed/{id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624 => id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624.buzz} (100%) rename tests/fuzzed/{id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27 => id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27.buzz} (100%) rename tests/fuzzed/{id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732 => id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732.buzz} (100%) rename tests/fuzzed/{id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145 => id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145.buzz} (100%) rename tests/fuzzed/{id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4 => id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4.buzz} (100%) rename tests/fuzzed/{id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113 => id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113.buzz} (100%) rename tests/fuzzed/{id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4 => id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4.buzz} (100%) rename tests/fuzzed/{id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906 => id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906.buzz} (100%) rename tests/fuzzed/{id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4 => id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4.buzz} (100%) rename tests/fuzzed/{id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488 => id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488.buzz} (100%) rename tests/fuzzed/{id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4 => id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4.buzz} (100%) rename tests/fuzzed/{id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361 => id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361.buzz} (100%) rename tests/fuzzed/{id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4 => id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4.buzz} (100%) rename tests/fuzzed/{id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4 => id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4 => id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4.buzz} (100%) rename tests/fuzzed/{id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545 => id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545.buzz} (100%) rename tests/fuzzed/{id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14 => id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14.buzz} (100%) rename tests/fuzzed/{id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111 => id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111.buzz} (100%) rename tests/fuzzed/{id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3 => id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3.buzz} (100%) rename tests/fuzzed/{id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179 => id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179.buzz} (100%) rename tests/fuzzed/{id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3 => id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3.buzz} (100%) rename tests/fuzzed/{id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146 => id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146.buzz} (100%) rename tests/fuzzed/{id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3 => id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3.buzz} (100%) rename tests/fuzzed/{id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793 => id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793.buzz} (100%) rename tests/fuzzed/{id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3 => id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3.buzz} (100%) rename tests/fuzzed/{id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192 => id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192.buzz} (100%) rename tests/fuzzed/{id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3 => id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3.buzz} (100%) rename tests/fuzzed/{id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96 => id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96.buzz} (100%) rename tests/fuzzed/{id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3 => id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3.buzz} (100%) rename tests/fuzzed/{id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774 => id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774.buzz} (100%) rename tests/fuzzed/{id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3 => id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3.buzz} (100%) rename tests/fuzzed/{id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056 => id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056.buzz} (100%) rename tests/fuzzed/{id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3 => id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3.buzz} (100%) rename tests/fuzzed/{id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422 => id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422.buzz} (100%) rename tests/fuzzed/{id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166 => id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166.buzz} (100%) rename tests/fuzzed/{id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197 => id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197.buzz} (100%) rename tests/fuzzed/{id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2 => id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489 => id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489.buzz} (100%) rename tests/fuzzed/{id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2 => id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275 => id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275.buzz} (100%) rename tests/fuzzed/{id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2 => id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2.buzz} (100%) rename tests/fuzzed/{id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8 => id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8.buzz} (100%) rename tests/fuzzed/{id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2 => id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2.buzz} (100%) rename tests/fuzzed/{id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523 => id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523.buzz} (100%) rename tests/fuzzed/{id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2 => id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2.buzz} (100%) rename tests/fuzzed/{id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270 => id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270.buzz} (100%) rename tests/fuzzed/{id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2 => id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2.buzz} (100%) rename tests/fuzzed/{id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214 => id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214.buzz} (100%) rename tests/fuzzed/{id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3 => id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3.buzz} (100%) rename tests/fuzzed/{id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164 => id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164.buzz} (100%) rename tests/fuzzed/{id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3 => id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3.buzz} (100%) rename tests/fuzzed/{id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380 => id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380.buzz} (100%) rename tests/fuzzed/{id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2 => id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650 => id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650.buzz} (100%) rename tests/fuzzed/{id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2 => id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037 => id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037.buzz} (100%) rename tests/fuzzed/{id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2 => id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350 => id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350.buzz} (100%) rename tests/fuzzed/{id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2 => id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95 => id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95.buzz} (100%) rename tests/fuzzed/{id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1 => id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1 => id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2 => id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1 => id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1.buzz} (100%) rename tests/fuzzed/{id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1 => id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1.buzz} (100%) rename tests/fuzzed/{id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3 => id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3.buzz} (100%) rename tests/fuzzed/{id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26 => id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26.buzz} (100%) rename tests/fuzzed/{id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13 => id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13.buzz} (100%) rename tests/fuzzed/{id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15 => id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15.buzz} (100%) rename tests/fuzzed/{id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13 => id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13.buzz} (100%) rename tests/fuzzed/{id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9 => id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9.buzz} (100%) rename tests/fuzzed/{id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10 => id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10.buzz} (100%) rename tests/fuzzed/{id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12 => id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12.buzz} (100%) rename tests/fuzzed/{id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14 => id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000207,sig:06,src:000101,time:29549985,execs:138505,op:havoc,rep:10 => id:000207,sig:06,src:000101,time:29549985,execs:138505,op:havoc,rep:10.buzz} (100%) rename tests/fuzzed/{id:000208,sig:06,src:000026,time:29630501,execs:139797,op:inf,rep:12 => id:000208,sig:06,src:000026,time:29630501,execs:139797,op:inf,rep:12.buzz} (100%) rename tests/fuzzed/{id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12 => id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12.buzz} (100%) rename tests/fuzzed/{id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69 => id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69.buzz} (100%) rename tests/fuzzed/{id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1 => id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1.buzz} (100%) rename tests/fuzzed/{id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1 => id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1.buzz} (100%) rename tests/fuzzed/{id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1 => id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1.buzz} (100%) rename tests/fuzzed/{id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1 => id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1.buzz} (100%) rename tests/fuzzed/{id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1 => id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1.buzz} (100%) rename tests/fuzzed/{id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1 => id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1.buzz} (100%) rename tests/fuzzed/{id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1 => id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1.buzz} (100%) rename tests/fuzzed/{id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1 => id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1.buzz} (100%) rename tests/fuzzed/{id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1 => id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1.buzz} (100%) rename tests/fuzzed/{id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1 => id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1.buzz} (100%) rename tests/fuzzed/{id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1 => id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1.buzz} (100%) rename tests/fuzzed/{id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1 => id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2 => id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1 => id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2 => id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2.buzz} (100%) rename tests/fuzzed/{id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13 => id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13.buzz} (100%) rename tests/fuzzed/{id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2 => id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2.buzz} (100%) rename tests/fuzzed/{id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2 => id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2.buzz} (100%) rename tests/fuzzed/{id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955 => id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955.buzz} (100%) rename tests/fuzzed/{id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2 => id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2.buzz} (100%) rename tests/fuzzed/{id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2 => id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2.buzz} (100%) rename tests/fuzzed/{id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2 => id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2.buzz} (100%) rename tests/fuzzed/{id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2 => id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2.buzz} (100%) rename tests/fuzzed/{id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2 => id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2.buzz} (100%) rename tests/fuzzed/{id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2 => id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2.buzz} (100%) rename tests/fuzzed/{id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4 => id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4.buzz} (100%) rename tests/fuzzed/{id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4 => id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000238,sig:06,src:001952,time:40616704,execs:182234,op:quick,pos:1361,val:+4 => id:000238,sig:06,src:001952,time:40616704,execs:182234,op:quick,pos:1361,val:+4.buzz} (100%) rename tests/fuzzed/{id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7 => id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7.buzz} (100%) rename tests/fuzzed/{id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6 => id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6.buzz} (100%) rename tests/fuzzed/{id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5 => id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5.buzz} (100%) rename tests/fuzzed/{id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26 => id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26.buzz} (100%) rename tests/fuzzed/{id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26 => id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26.buzz} (100%) rename tests/fuzzed/{id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2 => id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2.buzz} (100%) rename tests/fuzzed/{id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2 => id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2.buzz} (100%) rename tests/fuzzed/{id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2 => id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2.buzz} (100%) rename tests/fuzzed/{id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167 => id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167.buzz} (100%) rename tests/fuzzed/{id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187 => id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187.buzz} (100%) rename tests/fuzzed/{id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167 => id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167.buzz} (100%) rename tests/fuzzed/{id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10 => id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10.buzz} (100%) rename tests/fuzzed/{id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6 => id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6.buzz} (100%) rename tests/fuzzed/{id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6 => id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6.buzz} (100%) rename tests/fuzzed/{id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1 => id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4 => id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4.buzz} (100%) rename tests/fuzzed/{id:000255,sig:06,src:002305,time:54885789,execs:235917,op:flip32,pos:3 => id:000255,sig:06,src:002305,time:54885789,execs:235917,op:flip32,pos:3.buzz} (100%) rename tests/fuzzed/{id:000256,sig:06,src:002305,time:54897658,execs:236191,op:havoc,rep:15 => id:000256,sig:06,src:002305,time:54897658,execs:236191,op:havoc,rep:15.buzz} (100%) rename tests/fuzzed/{id:000257,sig:06,src:002305,time:54915177,execs:236611,op:havoc,rep:14 => id:000257,sig:06,src:002305,time:54915177,execs:236611,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000258,sig:06,src:002305,time:54918057,execs:236681,op:havoc,rep:16 => id:000258,sig:06,src:002305,time:54918057,execs:236681,op:havoc,rep:16.buzz} (100%) rename tests/fuzzed/{id:000259,sig:06,src:002305,time:54926618,execs:236882,op:havoc,rep:14 => id:000259,sig:06,src:002305,time:54926618,execs:236882,op:havoc,rep:14.buzz} (100%) rename tests/fuzzed/{id:000260,sig:06,src:002305,time:54942338,execs:237257,op:havoc,rep:15 => id:000260,sig:06,src:002305,time:54942338,execs:237257,op:havoc,rep:15.buzz} (100%) rename tests/fuzzed/{id:000261,sig:06,src:002305,time:54965944,execs:237841,op:havoc,rep:15 => id:000261,sig:06,src:002305,time:54965944,execs:237841,op:havoc,rep:15.buzz} (100%) rename tests/fuzzed/{id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5 => id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5.buzz} (100%) rename tests/fuzzed/{id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10 => id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10.buzz} (100%) rename tests/fuzzed/{id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12 => id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12.buzz} (100%) rename tests/fuzzed/{id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26 => id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26.buzz} (100%) rename tests/fuzzed/{id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2 => id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2.buzz} (100%) rename tests/fuzzed/{id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5 => id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5.buzz} (100%) rename tests/fuzzed/{id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5 => id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5.buzz} (100%) rename tests/fuzzed/{id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5 => id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5.buzz} (100%) rename tests/fuzzed/{id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3 => id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2 => id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2 => id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4 => id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000274,sig:06,src:000032,time:58977780,execs:255922,op:havoc,rep:4 => id:000274,sig:06,src:000032,time:58977780,execs:255922,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4 => id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2 => id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1 => id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1 => id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2 => id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1 => id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1.buzz} (100%) rename tests/fuzzed/{id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7 => id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7.buzz} (100%) rename tests/fuzzed/{id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7 => id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7.buzz} (100%) rename tests/fuzzed/{id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11 => id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11.buzz} (100%) rename tests/fuzzed/{id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11 => id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11.buzz} (100%) rename tests/fuzzed/{id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28 => id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28.buzz} (100%) rename tests/fuzzed/{id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2 => id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299 => id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299.buzz} (100%) rename tests/fuzzed/{id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111 => id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111.buzz} (100%) rename tests/fuzzed/{id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331 => id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331.buzz} (100%) rename tests/fuzzed/{id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868 => id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868.buzz} (100%) rename tests/fuzzed/{id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257 => id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257.buzz} (100%) rename tests/fuzzed/{id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62 => id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62.buzz} (100%) rename tests/fuzzed/{id:000293,sig:06,src:001816,time:72343382,execs:315245,op:arith8,pos:458,val:+28 => id:000293,sig:06,src:001816,time:72343382,execs:315245,op:arith8,pos:458,val:+28.buzz} (100%) rename tests/fuzzed/{id:000294,sig:06,src:000057,time:72638050,execs:316690,op:quick,pos:248 => id:000294,sig:06,src:000057,time:72638050,execs:316690,op:quick,pos:248.buzz} (100%) rename tests/fuzzed/{id:000295,sig:06,src:000057,time:72724520,execs:317104,op:arith8,pos:137,val:+5 => id:000295,sig:06,src:000057,time:72724520,execs:317104,op:arith8,pos:137,val:+5.buzz} (100%) rename tests/fuzzed/{id:000296,sig:06,src:001381,time:73193810,execs:319768,op:inf,rep:4 => id:000296,sig:06,src:001381,time:73193810,execs:319768,op:inf,rep:4.buzz} (100%) rename tests/fuzzed/{id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683 => id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683.buzz} (100%) rename tests/fuzzed/{id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78 => id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78.buzz} (100%) rename tests/fuzzed/{id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186 => id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186.buzz} (100%) rename tests/fuzzed/{id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189 => id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189.buzz} (100%) rename tests/fuzzed/{id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190 => id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190.buzz} (100%) rename tests/fuzzed/{id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204 => id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204.buzz} (100%) rename tests/fuzzed/{id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5 => id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5.buzz} (100%) rename tests/fuzzed/{id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232 => id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232.buzz} (100%) rename tests/fuzzed/{id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361 => id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361.buzz} (100%) rename tests/fuzzed/{id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60 => id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60.buzz} (100%) rename tests/fuzzed/{id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231 => id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231.buzz} (100%) rename tests/fuzzed/{id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552 => id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552.buzz} (100%) rename tests/fuzzed/{id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2 => id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290 => id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290.buzz} (100%) rename tests/fuzzed/{id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291 => id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291.buzz} (100%) rename tests/fuzzed/{id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27 => id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27.buzz} (100%) rename tests/fuzzed/{id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270 => id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270.buzz} (100%) rename tests/fuzzed/{id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260 => id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5 => id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5.buzz} (100%) rename tests/fuzzed/{id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187 => id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187.buzz} (100%) rename tests/fuzzed/{id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26 => id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26.buzz} (100%) rename tests/fuzzed/{id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88 => id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88.buzz} (100%) rename tests/fuzzed/{id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3 => id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361 => id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361.buzz} (100%) rename tests/fuzzed/{id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113 => id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113.buzz} (100%) rename tests/fuzzed/{id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510 => id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510.buzz} (100%) rename tests/fuzzed/{id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779 => id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779.buzz} (100%) rename tests/fuzzed/{id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115 => id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115.buzz} (100%) rename tests/fuzzed/{id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309 => id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309.buzz} (100%) rename tests/fuzzed/{id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206 => id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206.buzz} (100%) rename tests/fuzzed/{id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1 => id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260 => id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14 => id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14.buzz} (100%) rename tests/fuzzed/{id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362 => id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362.buzz} (100%) rename tests/fuzzed/{id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488 => id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488.buzz} (100%) rename tests/fuzzed/{id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956 => id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956.buzz} (100%) rename tests/fuzzed/{id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188 => id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188.buzz} (100%) rename tests/fuzzed/{id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357 => id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357.buzz} (100%) rename tests/fuzzed/{id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001 => id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001.buzz} (100%) rename tests/fuzzed/{id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242 => id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242.buzz} (100%) rename tests/fuzzed/{id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243 => id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243.buzz} (100%) rename tests/fuzzed/{id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13 => id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13.buzz} (100%) rename tests/fuzzed/{id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10 => id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10.buzz} (100%) rename tests/fuzzed/{id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260 => id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274 => id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274.buzz} (100%) rename tests/fuzzed/{id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11 => id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11.buzz} (100%) rename tests/fuzzed/{id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11 => id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11.buzz} (100%) rename tests/fuzzed/{id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187 => id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187.buzz} (100%) rename tests/fuzzed/{id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361 => id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361.buzz} (100%) rename tests/fuzzed/{id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415 => id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415.buzz} (100%) rename tests/fuzzed/{id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5 => id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5.buzz} (100%) rename tests/fuzzed/{id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92 => id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92.buzz} (100%) rename tests/fuzzed/{id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595 => id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595.buzz} (100%) rename tests/fuzzed/{id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635 => id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635.buzz} (100%) rename tests/fuzzed/{id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695 => id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695.buzz} (100%) rename tests/fuzzed/{id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821 => id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821.buzz} (100%) rename tests/fuzzed/{id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002 => id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002.buzz} (100%) rename tests/fuzzed/{id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169 => id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169.buzz} (100%) rename tests/fuzzed/{id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395 => id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395.buzz} (100%) rename tests/fuzzed/{id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53 => id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53.buzz} (100%) rename tests/fuzzed/{id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221 => id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221.buzz} (100%) rename tests/fuzzed/{id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435 => id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435.buzz} (100%) rename tests/fuzzed/{id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731 => id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731.buzz} (100%) rename tests/fuzzed/{id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013 => id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013.buzz} (100%) rename tests/fuzzed/{id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324 => id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324.buzz} (100%) rename tests/fuzzed/{id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633 => id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633.buzz} (100%) rename tests/fuzzed/{id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395 => id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395.buzz} (100%) rename tests/fuzzed/{id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4 => id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4.buzz} (100%) rename tests/fuzzed/{id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345 => id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345.buzz} (100%) rename tests/fuzzed/{id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207 => id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207.buzz} (100%) rename tests/fuzzed/{id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260 => id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260 => id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856 => id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856.buzz} (100%) rename tests/fuzzed/{id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018 => id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018.buzz} (100%) rename tests/fuzzed/{id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2 => id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2.buzz} (100%) rename tests/fuzzed/{id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189 => id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189.buzz} (100%) rename tests/fuzzed/{id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204 => id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204.buzz} (100%) rename tests/fuzzed/{id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856 => id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856.buzz} (100%) rename tests/fuzzed/{id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226 => id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226.buzz} (100%) rename tests/fuzzed/{id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413 => id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413.buzz} (100%) rename tests/fuzzed/{id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499 => id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499.buzz} (100%) rename tests/fuzzed/{id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3 => id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3.buzz} (100%) rename tests/fuzzed/{id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241 => id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241.buzz} (100%) rename tests/fuzzed/{id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045 => id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045.buzz} (100%) rename tests/fuzzed/{id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58 => id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58.buzz} (100%) rename tests/fuzzed/{id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542 => id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542.buzz} (100%) rename tests/fuzzed/{id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2 => id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2.buzz} (100%) rename tests/fuzzed/{id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707 => id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707.buzz} (100%) rename tests/fuzzed/{id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378 => id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378.buzz} (100%) rename tests/fuzzed/{id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361 => id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361.buzz} (100%) rename tests/fuzzed/{id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487 => id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487.buzz} (100%) rename tests/fuzzed/{id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107 => id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107.buzz} (100%) rename tests/fuzzed/{id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1 => id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292 => id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292.buzz} (100%) rename tests/fuzzed/{id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116 => id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116.buzz} (100%) rename tests/fuzzed/{id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173 => id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173.buzz} (100%) rename tests/fuzzed/{id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347 => id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347.buzz} (100%) rename tests/fuzzed/{id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260 => id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14 => id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14.buzz} (100%) rename tests/fuzzed/{id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330 => id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330.buzz} (100%) rename tests/fuzzed/{id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266 => id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266.buzz} (100%) rename tests/fuzzed/{id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361 => id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361.buzz} (100%) rename tests/fuzzed/{id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2 => id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141 => id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141.buzz} (100%) rename tests/fuzzed/{id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3 => id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3.buzz} (100%) rename tests/fuzzed/{id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6 => id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6.buzz} (100%) rename tests/fuzzed/{id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206 => id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206.buzz} (100%) rename tests/fuzzed/{id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260 => id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292 => id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292.buzz} (100%) rename tests/fuzzed/{id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393 => id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393.buzz} (100%) rename tests/fuzzed/{id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260 => id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168 => id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168.buzz} (100%) rename tests/fuzzed/{id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327 => id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327.buzz} (100%) rename tests/fuzzed/{id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077 => id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077.buzz} (100%) rename tests/fuzzed/{id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076 => id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076.buzz} (100%) rename tests/fuzzed/{id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445 => id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445.buzz} (100%) rename tests/fuzzed/{id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078 => id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078.buzz} (100%) rename tests/fuzzed/{id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188 => id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188.buzz} (100%) rename tests/fuzzed/{id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474 => id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474.buzz} (100%) rename tests/fuzzed/{id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874 => id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874.buzz} (100%) rename tests/fuzzed/{id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6 => id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6.buzz} (100%) rename tests/fuzzed/{id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6 => id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6.buzz} (100%) rename tests/fuzzed/{id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5 => id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5.buzz} (100%) rename tests/fuzzed/{id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260 => id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26 => id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26.buzz} (100%) rename tests/fuzzed/{id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3 => id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3.buzz} (100%) rename tests/fuzzed/{id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479 => id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479.buzz} (100%) rename tests/fuzzed/{id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141 => id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141.buzz} (100%) rename tests/fuzzed/{id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2 => id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2.buzz} (100%) rename tests/fuzzed/{id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8 => id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8.buzz} (100%) rename tests/fuzzed/{id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7 => id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7.buzz} (100%) rename tests/fuzzed/{id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5 => id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5.buzz} (100%) rename tests/fuzzed/{id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5 => id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5.buzz} (100%) rename tests/fuzzed/{id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046 => id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046.buzz} (100%) rename tests/fuzzed/{id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361 => id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361.buzz} (100%) rename tests/fuzzed/{id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391 => id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391.buzz} (100%) rename tests/fuzzed/{id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25 => id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25.buzz} (100%) rename tests/fuzzed/{id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1 => id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1.buzz} (100%) rename tests/fuzzed/{id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455 => id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455.buzz} (100%) rename tests/fuzzed/{id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24 => id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24.buzz} (100%) rename tests/fuzzed/{id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289 => id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289.buzz} (100%) rename tests/fuzzed/{id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203 => id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203.buzz} (100%) rename tests/fuzzed/{id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260 => id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354 => id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354.buzz} (100%) rename tests/fuzzed/{id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166 => id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166.buzz} (100%) rename tests/fuzzed/{id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260 => id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005 => id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005.buzz} (100%) rename tests/fuzzed/{id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379 => id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379.buzz} (100%) rename tests/fuzzed/{id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7 => id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7.buzz} (100%) rename tests/fuzzed/{id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7 => id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7.buzz} (100%) rename tests/fuzzed/{id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155 => id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155.buzz} (100%) rename tests/fuzzed/{id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260 => id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260.buzz} (100%) rename tests/fuzzed/{id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47 => id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47.buzz} (100%) rename tests/fuzzed/{id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54 => id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54.buzz} (100%) rename tests/fuzzed/{id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59 => id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59.buzz} (100%) rename tests/fuzzed/{id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132 => id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132.buzz} (100%) rename tests/fuzzed/{id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347 => id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347.buzz} (100%) rename tests/fuzzed/{id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60 => id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60.buzz} (100%) rename tests/fuzzed/{id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1 => id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1.buzz} (100%) rename tests/fuzzed/{id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260 => id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260.buzz} (100%) diff --git a/src/Codegen.zig b/src/Codegen.zig index 7bc3f72c..23c309d4 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -467,7 +467,7 @@ fn generateAs(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.O _ = try self.generateNode(components.left, breaks); - try self.OP_COPY(locations[components.left], 0); + try self.OP_COPY(locations[components.left]); try self.OP_CONSTANT(node_location, constant); try self.OP_IS(node_location); try self.OP_NOT(node_location); @@ -1151,7 +1151,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. switch (callee_type.def_type) { .Fiber, .Pattern, .String => { if (components.member_kind == .Call) { - try self.OP_COPY(locations[node], 0); + try self.OP_COPY(locations[node]); _ = try self.generateNode(components.value_or_call_or_enum.Call, breaks); } else { // Expression std.debug.assert(components.member_kind != .Value); @@ -1208,7 +1208,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. .PercentEqual, => { // Copy because OP_GET_INSTANCE_... will consume the subject - try self.OP_COPY(locations[node], 0); + try self.OP_COPY(locations[node]); try self.emitCodeArg( locations[node], @@ -1320,7 +1320,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. }, .List, .Map, .Range => { if (components.member_kind == .Call) { - try self.OP_COPY(locations[node], 0); + try self.OP_COPY(locations[node]); _ = try self.generateNode(components.value_or_call_or_enum.Call, breaks); } else { std.debug.assert(components.member_kind != .Value); @@ -2017,11 +2017,11 @@ fn generateIf(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.O _ = try self.generateNode(components.condition, breaks); const condition_location = locations[components.condition]; if (components.casted_type) |casted_type| { - try self.OP_COPY(condition_location, 0); + try self.OP_COPY(condition_location); try self.emitConstant(condition_location, type_defs[casted_type].?.toValue()); try self.OP_IS(condition_location); } else if (components.unwrapped_identifier != null) { - try self.OP_COPY(condition_location, 0); + try self.OP_COPY(condition_location); try self.OP_NULL(condition_location); try self.OP_EQUAL(condition_location); try self.OP_NOT(condition_location); @@ -2322,7 +2322,7 @@ fn generateObjectDeclaration(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks // Create property default value if (member.method_or_default_value) |default| { if (property_field.static) { - try self.OP_COPY(location, 0); + try self.OP_COPY(location); } _ = try self.generateNode(default, breaks); @@ -2387,7 +2387,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error node_type_def.resolved_type.?.ForeignContainer .fields.getIndex(property_name); - try self.OP_COPY(location, 0); // Will be popped by OP_SET_PROPERTY + try self.OP_COPY(location); // Will be popped by OP_SET_PROPERTY _ = try self.generateNode(property.value, breaks); @@ -2681,7 +2681,7 @@ fn generateTry(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. } // We assume the error is on top of the stack - try self.OP_COPY(clause.identifier, 0); // Copy error value since its argument to the catch clause + try self.OP_COPY(clause.identifier); // Copy error value since its argument to the catch clause try self.emitConstant(clause.identifier, error_type.toValue()); try self.OP_IS(clause.identifier); // If error type does not match, jump to next catch clause @@ -2885,7 +2885,7 @@ fn generateUnwrap(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o _ = try self.generateNode(components.unwrapped, breaks); - try self.OP_COPY(location, 0); + try self.OP_COPY(location); try self.OP_NULL(location); try self.OP_EQUAL(location); try self.OP_NOT(location); @@ -3400,12 +3400,8 @@ fn OP_EXPORT(self: *Self, location: Ast.TokenIndex, count: u24) !void { ); } -fn OP_COPY(self: *Self, location: Ast.TokenIndex, dist: u24) !void { - try self.emitCodeArg( - location, - .OP_COPY, - dist, - ); +fn OP_COPY(self: *Self, location: Ast.TokenIndex) !void { + try self.emitOpCode(location, .OP_COPY); } fn OP_CLONE(self: *Self, location: Ast.TokenIndex) !void { diff --git a/src/Debugger.zig b/src/Debugger.zig index 23b485cf..57b47a26 100644 --- a/src/Debugger.zig +++ b/src/Debugger.zig @@ -453,7 +453,6 @@ pub fn launch(self: *Debugger, arguments: Arguments(.launch)) Error!Response(.la ); // While debugger is active, the program won't start right away - // FIXME: needs to report stdout of the program with `output` events self.session.?.runner.runFile( program, &.{}, // TODO diff --git a/src/vm.zig b/src/vm.zig index 34dae686..3dcf4d33 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -541,22 +541,6 @@ pub const VM = struct { return (self.current_fiber.stack_top - 1 - distance)[0]; } - pub fn copy(self: *Self, n: u24) void { - if (n == 0) { - self.push(self.peek(0)); - return; - } - - var i = n - 1; - while (i >= 0) : (i -= 1) { - self.push(self.peek(i)); - - if (i == 0) { - break; - } - } - } - pub fn cloneValue(self: *Self, value: Value) !Value { return if (value.isObj()) try obj.cloneObject(value.obj(), self) @@ -1022,8 +1006,8 @@ pub const VM = struct { ); } - fn OP_COPY(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, arg: u24) void { - self.copy(arg); + fn OP_COPY(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, _: u24) void { + self.push(self.peek(0)); const next_full_instruction = self.readInstruction(); @call( diff --git a/tests/fuzzed/README.txt b/tests/fuzzed/README.txt deleted file mode 100644 index 71526cf4..00000000 --- a/tests/fuzzed/README.txt +++ /dev/null @@ -1,14 +0,0 @@ -Command line used to find this crash: - -/opt/homebrew/Cellar/afl++/4.31/libexec/afl-fuzz -i tests/behavior -o dist zig-out/bin/fuzz_afl - -If you can't reproduce a bug outside of afl-fuzz, be sure to set the same -memory limit. The limit used for this fuzzing session was 0 B. - -Need a tool to minimize test cases before investigating the crashes or sending -them to a vendor? Check out the afl-tmin that comes with the fuzzer! - -Found any cool bugs in open-source tools using afl-fuzz? If yes, please post -to https://github.com/AFLplusplus/AFLplusplus/issues/286 once the issues - are fixed :) - diff --git a/tests/fuzzed/id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0 b/tests/fuzzed/id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0.buzz similarity index 100% rename from tests/fuzzed/id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0 rename to tests/fuzzed/id:000000,sig:06,src:000051,time:929,execs:782,op:quick,pos:0.buzz diff --git a/tests/fuzzed/id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1 b/tests/fuzzed/id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1 rename to tests/fuzzed/id:000000,src:000013,time:863917,execs:18330,op:quick,pos:104,val:+1.buzz diff --git a/tests/fuzzed/id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1 b/tests/fuzzed/id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1.buzz similarity index 100% rename from tests/fuzzed/id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1 rename to tests/fuzzed/id:000001,sig:06,src:000051,time:13766,execs:1095,op:flip1,pos:1.buzz diff --git a/tests/fuzzed/id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105 b/tests/fuzzed/id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105.buzz similarity index 100% rename from tests/fuzzed/id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105 rename to tests/fuzzed/id:000001,src:000013,time:932808,execs:18686,op:flip1,pos:105.buzz diff --git a/tests/fuzzed/id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1 b/tests/fuzzed/id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1.buzz similarity index 100% rename from tests/fuzzed/id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1 rename to tests/fuzzed/id:000002,sig:06,src:000051,time:13812,execs:1096,op:flip1,pos:1.buzz diff --git a/tests/fuzzed/id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105 b/tests/fuzzed/id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105.buzz similarity index 100% rename from tests/fuzzed/id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105 rename to tests/fuzzed/id:000002,src:000013,time:934683,execs:18688,op:flip1,pos:105.buzz diff --git a/tests/fuzzed/id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1 b/tests/fuzzed/id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1.buzz similarity index 100% rename from tests/fuzzed/id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1 rename to tests/fuzzed/id:000003,sig:06,src:000051,time:15542,execs:1136,op:flip1,pos:1.buzz diff --git a/tests/fuzzed/id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108 b/tests/fuzzed/id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108.buzz similarity index 100% rename from tests/fuzzed/id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108 rename to tests/fuzzed/id:000003,src:000013,time:944955,execs:18702,op:flip1,pos:108.buzz diff --git a/tests/fuzzed/id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1 b/tests/fuzzed/id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1.buzz similarity index 100% rename from tests/fuzzed/id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1 rename to tests/fuzzed/id:000004,sig:06,src:000051,time:45178,execs:1765,op:flip2,pos:1.buzz diff --git a/tests/fuzzed/id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105 b/tests/fuzzed/id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105.buzz similarity index 100% rename from tests/fuzzed/id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105 rename to tests/fuzzed/id:000004,src:000013,time:982430,execs:18918,op:flip2,pos:105.buzz diff --git a/tests/fuzzed/id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1 b/tests/fuzzed/id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1.buzz similarity index 100% rename from tests/fuzzed/id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1 rename to tests/fuzzed/id:000005,sig:06,src:000051,time:46425,execs:1794,op:flip2,pos:1.buzz diff --git a/tests/fuzzed/id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4 b/tests/fuzzed/id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4 rename to tests/fuzzed/id:000005,src:000013,time:1726632,execs:23371,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66 b/tests/fuzzed/id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66.buzz similarity index 100% rename from tests/fuzzed/id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66 rename to tests/fuzzed/id:000006,sig:11,src:000051,time:66728,execs:2227,op:flip2,pos:66.buzz diff --git a/tests/fuzzed/id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2 b/tests/fuzzed/id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2 rename to tests/fuzzed/id:000006,src:000013,time:1755372,execs:23546,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1 b/tests/fuzzed/id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1.buzz similarity index 100% rename from tests/fuzzed/id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1 rename to tests/fuzzed/id:000007,sig:06,src:000051,time:69064,execs:2277,op:flip4,pos:1.buzz diff --git a/tests/fuzzed/id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4 b/tests/fuzzed/id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4 rename to tests/fuzzed/id:000007,src:000013,time:1831679,execs:24074,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1 b/tests/fuzzed/id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1.buzz similarity index 100% rename from tests/fuzzed/id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1 rename to tests/fuzzed/id:000008,sig:06,src:000051,time:69114,execs:2278,op:flip4,pos:1.buzz diff --git a/tests/fuzzed/id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1 b/tests/fuzzed/id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1 rename to tests/fuzzed/id:000008,src:000013,time:1878199,execs:24397,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4 b/tests/fuzzed/id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4.buzz similarity index 100% rename from tests/fuzzed/id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4 rename to tests/fuzzed/id:000009,sig:06,src:000051,time:71379,execs:2330,op:flip4,pos:4.buzz diff --git a/tests/fuzzed/id:000009,src:000013,time:1937548,execs:24820,op:havoc,rep:2 b/tests/fuzzed/id:000009,src:000013,time:1937548,execs:24820,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000009,src:000013,time:1937548,execs:24820,op:havoc,rep:2 rename to tests/fuzzed/id:000009,src:000013,time:1937548,execs:24820,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000010,sig:06,src:000051,time:83385,execs:2556,op:flip4,pos:49 b/tests/fuzzed/id:000010,sig:06,src:000051,time:83385,execs:2556,op:flip4,pos:49.buzz similarity index 100% rename from tests/fuzzed/id:000010,sig:06,src:000051,time:83385,execs:2556,op:flip4,pos:49 rename to tests/fuzzed/id:000010,sig:06,src:000051,time:83385,execs:2556,op:flip4,pos:49.buzz diff --git a/tests/fuzzed/id:000010,src:000013,time:2225913,execs:26757,op:havoc,rep:4 b/tests/fuzzed/id:000010,src:000013,time:2225913,execs:26757,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000010,src:000013,time:2225913,execs:26757,op:havoc,rep:4 rename to tests/fuzzed/id:000010,src:000013,time:2225913,execs:26757,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000011,sig:06,src:000051,time:88769,execs:2664,op:flip32,pos:3 b/tests/fuzzed/id:000011,sig:06,src:000051,time:88769,execs:2664,op:flip32,pos:3.buzz similarity index 100% rename from tests/fuzzed/id:000011,sig:06,src:000051,time:88769,execs:2664,op:flip32,pos:3 rename to tests/fuzzed/id:000011,sig:06,src:000051,time:88769,execs:2664,op:flip32,pos:3.buzz diff --git a/tests/fuzzed/id:000011,src:000013,time:2297408,execs:27208,op:havoc,rep:1 b/tests/fuzzed/id:000011,src:000013,time:2297408,execs:27208,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000011,src:000013,time:2297408,execs:27208,op:havoc,rep:1 rename to tests/fuzzed/id:000011,src:000013,time:2297408,execs:27208,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000012,sig:06,src:000051,time:88966,execs:2669,op:flip32,pos:12 b/tests/fuzzed/id:000012,sig:06,src:000051,time:88966,execs:2669,op:flip32,pos:12.buzz similarity index 100% rename from tests/fuzzed/id:000012,sig:06,src:000051,time:88966,execs:2669,op:flip32,pos:12 rename to tests/fuzzed/id:000012,sig:06,src:000051,time:88966,execs:2669,op:flip32,pos:12.buzz diff --git a/tests/fuzzed/id:000012,src:000008,time:2817091,execs:29065,op:quick,pos:488,val:+1 b/tests/fuzzed/id:000012,src:000008,time:2817091,execs:29065,op:quick,pos:488,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000012,src:000008,time:2817091,execs:29065,op:quick,pos:488,val:+1 rename to tests/fuzzed/id:000012,src:000008,time:2817091,execs:29065,op:quick,pos:488,val:+1.buzz diff --git a/tests/fuzzed/id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5 b/tests/fuzzed/id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5 rename to tests/fuzzed/id:000013,sig:06,src:000051,time:116999,execs:3388,op:arith8,pos:12,val:+5.buzz diff --git a/tests/fuzzed/id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1 b/tests/fuzzed/id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1 rename to tests/fuzzed/id:000013,src:000008,time:2819714,execs:29070,op:quick,pos:492,val:+1.buzz diff --git a/tests/fuzzed/id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23 b/tests/fuzzed/id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23.buzz similarity index 100% rename from tests/fuzzed/id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23 rename to tests/fuzzed/id:000014,sig:06,src:000051,time:120257,execs:3463,op:arith8,pos:12,val:-23.buzz diff --git a/tests/fuzzed/id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26 b/tests/fuzzed/id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26.buzz similarity index 100% rename from tests/fuzzed/id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26 rename to tests/fuzzed/id:000015,sig:06,src:000051,time:126085,execs:3567,op:arith8,pos:13,val:+26.buzz diff --git a/tests/fuzzed/id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23 b/tests/fuzzed/id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23.buzz similarity index 100% rename from tests/fuzzed/id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23 rename to tests/fuzzed/id:000016,sig:11,src:000051,time:192476,execs:4807,op:arith8,pos:67,val:+23.buzz diff --git a/tests/fuzzed/id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28 b/tests/fuzzed/id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28.buzz similarity index 100% rename from tests/fuzzed/id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28 rename to tests/fuzzed/id:000017,sig:11,src:000051,time:193738,execs:4829,op:arith8,pos:67,val:+28.buzz diff --git a/tests/fuzzed/id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30 b/tests/fuzzed/id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30.buzz similarity index 100% rename from tests/fuzzed/id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30 rename to tests/fuzzed/id:000018,sig:11,src:000051,time:194012,execs:4833,op:arith8,pos:67,val:+30.buzz diff --git a/tests/fuzzed/id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2 b/tests/fuzzed/id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2 rename to tests/fuzzed/id:000018,src:000008,time:3677561,execs:32267,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35 b/tests/fuzzed/id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35.buzz similarity index 100% rename from tests/fuzzed/id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35 rename to tests/fuzzed/id:000019,sig:11,src:000051,time:195179,execs:4854,op:arith8,pos:67,val:+35.buzz diff --git a/tests/fuzzed/id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1 b/tests/fuzzed/id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1 rename to tests/fuzzed/id:000020,sig:06,src:000051,time:218857,execs:5246,op:int16,pos:1,val:+1.buzz diff --git a/tests/fuzzed/id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6 b/tests/fuzzed/id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6.buzz similarity index 100% rename from tests/fuzzed/id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6 rename to tests/fuzzed/id:000020,src:000727,time:5187468,execs:38213,op:quick,pos:492,val:+6.buzz diff --git a/tests/fuzzed/id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6 b/tests/fuzzed/id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6.buzz similarity index 100% rename from tests/fuzzed/id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6 rename to tests/fuzzed/id:000021,sig:06,src:000051,time:304934,execs:7111,op:havoc,rep:6.buzz diff --git a/tests/fuzzed/id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1 b/tests/fuzzed/id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1 rename to tests/fuzzed/id:000021,src:000055,time:5539582,execs:39686,op:quick,pos:251,val:+1.buzz diff --git a/tests/fuzzed/id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10 b/tests/fuzzed/id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10.buzz similarity index 100% rename from tests/fuzzed/id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10 rename to tests/fuzzed/id:000022,sig:06,src:000051,time:317141,execs:7388,op:havoc,rep:10.buzz diff --git a/tests/fuzzed/id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1 b/tests/fuzzed/id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1 rename to tests/fuzzed/id:000022,src:000055,time:5562885,execs:39790,op:quick,pos:330,val:+1.buzz diff --git a/tests/fuzzed/id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14 b/tests/fuzzed/id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14 rename to tests/fuzzed/id:000023,sig:06,src:000051,time:317455,execs:7395,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1 b/tests/fuzzed/id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1 rename to tests/fuzzed/id:000023,src:000055,time:5564772,execs:39792,op:quick,pos:331,val:+1.buzz diff --git a/tests/fuzzed/id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11 b/tests/fuzzed/id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11.buzz similarity index 100% rename from tests/fuzzed/id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11 rename to tests/fuzzed/id:000024,sig:06,src:000051,time:324656,execs:7522,op:havoc,rep:11.buzz diff --git a/tests/fuzzed/id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1 b/tests/fuzzed/id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1 rename to tests/fuzzed/id:000024,src:000055,time:6940331,execs:46733,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5 b/tests/fuzzed/id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5 rename to tests/fuzzed/id:000025,sig:06,src:000051,time:341820,execs:7862,op:havoc,rep:5.buzz diff --git a/tests/fuzzed/id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2 b/tests/fuzzed/id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2 rename to tests/fuzzed/id:000025,src:000025,time:8384774,execs:58114,op:quick,pos:79,val:+2.buzz diff --git a/tests/fuzzed/id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16 b/tests/fuzzed/id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16.buzz similarity index 100% rename from tests/fuzzed/id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16 rename to tests/fuzzed/id:000026,sig:06,src:000051,time:345967,execs:7955,op:havoc,rep:16.buzz diff --git a/tests/fuzzed/id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2 b/tests/fuzzed/id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2 rename to tests/fuzzed/id:000026,src:000025,time:8439302,execs:58339,op:quick,pos:255,val:+2.buzz diff --git a/tests/fuzzed/id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13 b/tests/fuzzed/id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13.buzz similarity index 100% rename from tests/fuzzed/id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13 rename to tests/fuzzed/id:000027,sig:06,src:000051,time:347472,execs:7988,op:havoc,rep:13.buzz diff --git a/tests/fuzzed/id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2 b/tests/fuzzed/id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2 rename to tests/fuzzed/id:000027,src:000025,time:8492973,execs:58552,op:quick,pos:431,val:+2.buzz diff --git a/tests/fuzzed/id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6 b/tests/fuzzed/id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6.buzz similarity index 100% rename from tests/fuzzed/id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6 rename to tests/fuzzed/id:000028,sig:06,src:000051,time:347609,execs:7991,op:havoc,rep:6.buzz diff --git a/tests/fuzzed/id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2 b/tests/fuzzed/id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2 rename to tests/fuzzed/id:000028,src:000025,time:8557626,execs:58806,op:quick,pos:612,val:+2.buzz diff --git a/tests/fuzzed/id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14 b/tests/fuzzed/id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14 rename to tests/fuzzed/id:000029,sig:06,src:000051,time:400266,execs:9041,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2 b/tests/fuzzed/id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2 rename to tests/fuzzed/id:000029,src:000025,time:8611425,execs:59012,op:quick,pos:781,val:+2.buzz diff --git a/tests/fuzzed/id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9 b/tests/fuzzed/id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9.buzz similarity index 100% rename from tests/fuzzed/id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9 rename to tests/fuzzed/id:000030,sig:06,src:000051,time:401374,execs:9066,op:havoc,rep:9.buzz diff --git a/tests/fuzzed/id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2 b/tests/fuzzed/id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2 rename to tests/fuzzed/id:000030,src:000025,time:8842115,execs:59845,op:quick,pos:1313,val:+2.buzz diff --git a/tests/fuzzed/id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14 b/tests/fuzzed/id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14 rename to tests/fuzzed/id:000031,sig:06,src:000051,time:408249,execs:9208,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3 b/tests/fuzzed/id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3 rename to tests/fuzzed/id:000031,src:000025,time:9590514,execs:62692,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10 b/tests/fuzzed/id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10.buzz similarity index 100% rename from tests/fuzzed/id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10 rename to tests/fuzzed/id:000032,sig:06,src:000051,time:414648,execs:9350,op:havoc,rep:10.buzz diff --git a/tests/fuzzed/id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3 b/tests/fuzzed/id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3 rename to tests/fuzzed/id:000032,src:000025,time:9938774,execs:64109,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4 b/tests/fuzzed/id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4 rename to tests/fuzzed/id:000033,sig:06,src:000051,time:421281,execs:9487,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1 b/tests/fuzzed/id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1 rename to tests/fuzzed/id:000033,src:000025,time:10025436,execs:64464,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16 b/tests/fuzzed/id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16.buzz similarity index 100% rename from tests/fuzzed/id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16 rename to tests/fuzzed/id:000034,sig:06,src:000051,time:429246,execs:9657,op:havoc,rep:16.buzz diff --git a/tests/fuzzed/id:000034,src:000042,time:13064132,execs:70410,op:quick,pos:868 b/tests/fuzzed/id:000034,src:000042,time:13064132,execs:70410,op:quick,pos:868.buzz similarity index 100% rename from tests/fuzzed/id:000034,src:000042,time:13064132,execs:70410,op:quick,pos:868 rename to tests/fuzzed/id:000034,src:000042,time:13064132,execs:70410,op:quick,pos:868.buzz diff --git a/tests/fuzzed/id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6 b/tests/fuzzed/id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6.buzz similarity index 100% rename from tests/fuzzed/id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6 rename to tests/fuzzed/id:000035,sig:06,src:000051,time:435014,execs:9787,op:havoc,rep:6.buzz diff --git a/tests/fuzzed/id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182 b/tests/fuzzed/id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182.buzz similarity index 100% rename from tests/fuzzed/id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182 rename to tests/fuzzed/id:000035,src:000042,time:13199030,execs:70941,op:quick,pos:1182.buzz diff --git a/tests/fuzzed/id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7 b/tests/fuzzed/id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7.buzz similarity index 100% rename from tests/fuzzed/id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7 rename to tests/fuzzed/id:000036,sig:06,src:000051,time:458317,execs:10266,op:havoc,rep:7.buzz diff --git a/tests/fuzzed/id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413 b/tests/fuzzed/id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413.buzz similarity index 100% rename from tests/fuzzed/id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413 rename to tests/fuzzed/id:000036,src:000042,time:13268403,execs:71209,op:quick,pos:1413.buzz diff --git a/tests/fuzzed/id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15 b/tests/fuzzed/id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15.buzz similarity index 100% rename from tests/fuzzed/id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15 rename to tests/fuzzed/id:000037,sig:06,src:000051,time:462379,execs:10345,op:havoc,rep:15.buzz diff --git a/tests/fuzzed/id:000037,src:000042,time:13686254,execs:72978,op:havoc,rep:1 b/tests/fuzzed/id:000037,src:000042,time:13686254,execs:72978,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000037,src:000042,time:13686254,execs:72978,op:havoc,rep:1 rename to tests/fuzzed/id:000037,src:000042,time:13686254,execs:72978,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13 b/tests/fuzzed/id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13.buzz similarity index 100% rename from tests/fuzzed/id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13 rename to tests/fuzzed/id:000038,sig:06,src:000051,time:464531,execs:10395,op:havoc,rep:13.buzz diff --git a/tests/fuzzed/id:000038,src:000042,time:14303774,execs:75567,op:havoc,rep:2 b/tests/fuzzed/id:000038,src:000042,time:14303774,execs:75567,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000038,src:000042,time:14303774,execs:75567,op:havoc,rep:2 rename to tests/fuzzed/id:000038,src:000042,time:14303774,execs:75567,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9 b/tests/fuzzed/id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9.buzz similarity index 100% rename from tests/fuzzed/id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9 rename to tests/fuzzed/id:000039,sig:06,src:000051,time:475463,execs:10632,op:havoc,rep:9.buzz diff --git a/tests/fuzzed/id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1 b/tests/fuzzed/id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1 rename to tests/fuzzed/id:000039,src:000041,time:17190307,execs:87650,op:quick,pos:152,val:+1.buzz diff --git a/tests/fuzzed/id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12 b/tests/fuzzed/id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12.buzz similarity index 100% rename from tests/fuzzed/id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12 rename to tests/fuzzed/id:000040,sig:06,src:000051,time:486723,execs:10886,op:havoc,rep:12.buzz diff --git a/tests/fuzzed/id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1 b/tests/fuzzed/id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1 rename to tests/fuzzed/id:000040,src:000041,time:17293232,execs:88058,op:quick,pos:391,val:+1.buzz diff --git a/tests/fuzzed/id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9 b/tests/fuzzed/id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9.buzz similarity index 100% rename from tests/fuzzed/id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9 rename to tests/fuzzed/id:000041,sig:06,src:000051,time:487763,execs:10912,op:havoc,rep:9.buzz diff --git a/tests/fuzzed/id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1 b/tests/fuzzed/id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1 rename to tests/fuzzed/id:000041,src:000041,time:17392405,execs:88430,op:quick,pos:678,val:+1.buzz diff --git a/tests/fuzzed/id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4 b/tests/fuzzed/id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4 rename to tests/fuzzed/id:000042,sig:06,src:000051,time:503456,execs:11261,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96 b/tests/fuzzed/id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96.buzz similarity index 100% rename from tests/fuzzed/id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96 rename to tests/fuzzed/id:000042,src:000003,time:18612333,execs:93274,op:quick,pos:96.buzz diff --git a/tests/fuzzed/id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11 b/tests/fuzzed/id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11.buzz similarity index 100% rename from tests/fuzzed/id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11 rename to tests/fuzzed/id:000043,sig:06,src:000051,time:514440,execs:11517,op:havoc,rep:11.buzz diff --git a/tests/fuzzed/id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617 b/tests/fuzzed/id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617.buzz similarity index 100% rename from tests/fuzzed/id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617 rename to tests/fuzzed/id:000043,src:000003,time:18759009,execs:93868,op:quick,pos:617.buzz diff --git a/tests/fuzzed/id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14 b/tests/fuzzed/id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14 rename to tests/fuzzed/id:000044,sig:06,src:000051,time:520847,execs:11652,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000044,src:000003,time:19033188,execs:94894,op:quick,pos:1522 b/tests/fuzzed/id:000044,src:000003,time:19033188,execs:94894,op:quick,pos:1522.buzz similarity index 100% rename from tests/fuzzed/id:000044,src:000003,time:19033188,execs:94894,op:quick,pos:1522 rename to tests/fuzzed/id:000044,src:000003,time:19033188,execs:94894,op:quick,pos:1522.buzz diff --git a/tests/fuzzed/id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6 b/tests/fuzzed/id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6.buzz similarity index 100% rename from tests/fuzzed/id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6 rename to tests/fuzzed/id:000045,sig:06,src:000051,time:523723,execs:11720,op:havoc,rep:6.buzz diff --git a/tests/fuzzed/id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774 b/tests/fuzzed/id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774.buzz similarity index 100% rename from tests/fuzzed/id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774 rename to tests/fuzzed/id:000045,src:000003,time:19108064,execs:95159,op:quick,pos:1774.buzz diff --git a/tests/fuzzed/id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15 b/tests/fuzzed/id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15.buzz similarity index 100% rename from tests/fuzzed/id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15 rename to tests/fuzzed/id:000046,sig:06,src:000051,time:528438,execs:11825,op:havoc,rep:15.buzz diff --git a/tests/fuzzed/id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4 b/tests/fuzzed/id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4 rename to tests/fuzzed/id:000046,src:000029,time:20042119,execs:98972,op:quick,pos:215,val:+4.buzz diff --git a/tests/fuzzed/id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14 b/tests/fuzzed/id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14 rename to tests/fuzzed/id:000047,sig:06,src:000051,time:547324,execs:12257,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4 b/tests/fuzzed/id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4 rename to tests/fuzzed/id:000047,src:000029,time:20216929,execs:99679,op:quick,pos:825,val:+4.buzz diff --git a/tests/fuzzed/id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16 b/tests/fuzzed/id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16.buzz similarity index 100% rename from tests/fuzzed/id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16 rename to tests/fuzzed/id:000048,sig:06,src:000051,time:557798,execs:12486,op:havoc,rep:16.buzz diff --git a/tests/fuzzed/id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4 b/tests/fuzzed/id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4 rename to tests/fuzzed/id:000048,src:000029,time:20292375,execs:99967,op:quick,pos:1112,val:+4.buzz diff --git a/tests/fuzzed/id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16 b/tests/fuzzed/id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16.buzz similarity index 100% rename from tests/fuzzed/id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16 rename to tests/fuzzed/id:000049,sig:06,src:000051,time:591401,execs:13229,op:havoc,rep:16.buzz diff --git a/tests/fuzzed/id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3 b/tests/fuzzed/id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3 rename to tests/fuzzed/id:000049,src:000043,time:21516152,execs:105200,op:quick,pos:228,val:+3.buzz diff --git a/tests/fuzzed/id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6 b/tests/fuzzed/id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6.buzz similarity index 100% rename from tests/fuzzed/id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6 rename to tests/fuzzed/id:000050,sig:06,src:000051,time:624596,execs:13922,op:havoc,rep:6.buzz diff --git a/tests/fuzzed/id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3 b/tests/fuzzed/id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3 rename to tests/fuzzed/id:000050,src:000043,time:21589771,execs:105475,op:quick,pos:454,val:+3.buzz diff --git a/tests/fuzzed/id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16 b/tests/fuzzed/id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16.buzz similarity index 100% rename from tests/fuzzed/id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16 rename to tests/fuzzed/id:000051,sig:06,src:000051,time:628015,execs:13999,op:havoc,rep:16.buzz diff --git a/tests/fuzzed/id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3 b/tests/fuzzed/id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3 rename to tests/fuzzed/id:000051,src:000043,time:21654674,execs:105711,op:quick,pos:653,val:+3.buzz diff --git a/tests/fuzzed/id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13 b/tests/fuzzed/id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13.buzz similarity index 100% rename from tests/fuzzed/id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13 rename to tests/fuzzed/id:000052,sig:06,src:000051,time:638876,execs:14245,op:havoc,rep:13.buzz diff --git a/tests/fuzzed/id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3 b/tests/fuzzed/id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3 rename to tests/fuzzed/id:000052,src:000043,time:21728271,execs:105976,op:quick,pos:869,val:+3.buzz diff --git a/tests/fuzzed/id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14 b/tests/fuzzed/id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14 rename to tests/fuzzed/id:000053,sig:06,src:000051,time:656502,execs:14649,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3 b/tests/fuzzed/id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3 rename to tests/fuzzed/id:000053,src:000043,time:21821873,execs:106306,op:quick,pos:1162,val:+3.buzz diff --git a/tests/fuzzed/id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13 b/tests/fuzzed/id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13.buzz similarity index 100% rename from tests/fuzzed/id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13 rename to tests/fuzzed/id:000054,sig:06,src:000051,time:662089,execs:14767,op:havoc,rep:13.buzz diff --git a/tests/fuzzed/id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2 b/tests/fuzzed/id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2 rename to tests/fuzzed/id:000054,src:000043,time:22766394,execs:109675,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8 b/tests/fuzzed/id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8.buzz similarity index 100% rename from tests/fuzzed/id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8 rename to tests/fuzzed/id:000055,sig:11,src:000459,time:709950,execs:15892,op:havoc,rep:8.buzz diff --git a/tests/fuzzed/id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2 b/tests/fuzzed/id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2 rename to tests/fuzzed/id:000055,src:001513,time:24308324,execs:115372,op:quick,pos:418,val:+2.buzz diff --git a/tests/fuzzed/id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2 b/tests/fuzzed/id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2 rename to tests/fuzzed/id:000056,sig:06,src:000459,time:737512,execs:16496,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2 b/tests/fuzzed/id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2 rename to tests/fuzzed/id:000056,src:001513,time:24612052,execs:116487,op:quick,pos:1520,val:+2.buzz diff --git a/tests/fuzzed/id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12 b/tests/fuzzed/id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12.buzz similarity index 100% rename from tests/fuzzed/id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12 rename to tests/fuzzed/id:000057,sig:06,src:000456,time:792567,execs:17714,op:havoc,rep:12.buzz diff --git a/tests/fuzzed/id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3 b/tests/fuzzed/id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3 rename to tests/fuzzed/id:000057,src:000062,time:26580338,execs:124145,op:quick,pos:8,val:+3.buzz diff --git a/tests/fuzzed/id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11 b/tests/fuzzed/id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11.buzz similarity index 100% rename from tests/fuzzed/id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11 rename to tests/fuzzed/id:000058,sig:06,src:000456,time:792739,execs:17718,op:havoc,rep:11.buzz diff --git a/tests/fuzzed/id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3 b/tests/fuzzed/id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3 rename to tests/fuzzed/id:000058,src:000062,time:26613047,execs:124255,op:quick,pos:105,val:+3.buzz diff --git a/tests/fuzzed/id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7 b/tests/fuzzed/id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7.buzz similarity index 100% rename from tests/fuzzed/id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7 rename to tests/fuzzed/id:000059,sig:06,src:000013,time:1038554,execs:19208,op:flip16,pos:7.buzz diff --git a/tests/fuzzed/id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3 b/tests/fuzzed/id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3 rename to tests/fuzzed/id:000059,src:000062,time:26638975,execs:124340,op:quick,pos:165,val:+3.buzz diff --git a/tests/fuzzed/id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13 b/tests/fuzzed/id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13.buzz similarity index 100% rename from tests/fuzzed/id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13 rename to tests/fuzzed/id:000060,sig:06,src:000013,time:1046996,execs:19259,op:flip32,pos:13.buzz diff --git a/tests/fuzzed/id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3 b/tests/fuzzed/id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3 rename to tests/fuzzed/id:000060,src:000062,time:26660362,execs:124411,op:quick,pos:223,val:+3.buzz diff --git a/tests/fuzzed/id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5 b/tests/fuzzed/id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5 rename to tests/fuzzed/id:000061,sig:06,src:000013,time:1106817,execs:19778,op:arith8,pos:31,val:+5.buzz diff --git a/tests/fuzzed/id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3 b/tests/fuzzed/id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3 rename to tests/fuzzed/id:000061,src:000062,time:26680548,execs:124482,op:quick,pos:281,val:+3.buzz diff --git a/tests/fuzzed/id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26 b/tests/fuzzed/id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26.buzz similarity index 100% rename from tests/fuzzed/id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26 rename to tests/fuzzed/id:000062,sig:06,src:000013,time:1116204,execs:19905,op:arith8,pos:32,val:+26.buzz diff --git a/tests/fuzzed/id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3 b/tests/fuzzed/id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3 rename to tests/fuzzed/id:000062,src:000062,time:26699147,execs:124542,op:quick,pos:340,val:+3.buzz diff --git a/tests/fuzzed/id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5 b/tests/fuzzed/id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5 rename to tests/fuzzed/id:000063,sig:06,src:000013,time:1337862,execs:20767,op:arith8,pos:142,val:+5.buzz diff --git a/tests/fuzzed/id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3 b/tests/fuzzed/id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3 rename to tests/fuzzed/id:000063,src:000062,time:26732156,execs:124652,op:quick,pos:413,val:+3.buzz diff --git a/tests/fuzzed/id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4 b/tests/fuzzed/id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4 rename to tests/fuzzed/id:000064,sig:06,src:000013,time:2034525,execs:25498,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3 b/tests/fuzzed/id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3 rename to tests/fuzzed/id:000064,src:000062,time:26749328,execs:124710,op:quick,pos:470,val:+3.buzz diff --git a/tests/fuzzed/id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1 b/tests/fuzzed/id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1 rename to tests/fuzzed/id:000065,sig:06,src:000013,time:2092469,execs:25900,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3 b/tests/fuzzed/id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3 rename to tests/fuzzed/id:000065,src:000062,time:26766350,execs:124771,op:quick,pos:518,val:+3.buzz diff --git a/tests/fuzzed/id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2 b/tests/fuzzed/id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2 rename to tests/fuzzed/id:000066,sig:11,src:000013,time:2172493,execs:26420,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3 b/tests/fuzzed/id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3 rename to tests/fuzzed/id:000066,src:000062,time:26785044,execs:124841,op:quick,pos:575,val:+3.buzz diff --git a/tests/fuzzed/id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1 b/tests/fuzzed/id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1 rename to tests/fuzzed/id:000067,sig:06,src:000008,time:2538361,execs:28186,op:quick,pos:56,val:+1.buzz diff --git a/tests/fuzzed/id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3 b/tests/fuzzed/id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3 rename to tests/fuzzed/id:000067,src:000062,time:26801799,execs:124902,op:quick,pos:623,val:+3.buzz diff --git a/tests/fuzzed/id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1 b/tests/fuzzed/id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1 rename to tests/fuzzed/id:000068,sig:06,src:000008,time:2566540,execs:28302,op:quick,pos:81,val:+1.buzz diff --git a/tests/fuzzed/id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3 b/tests/fuzzed/id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3 rename to tests/fuzzed/id:000068,src:000062,time:26828586,execs:124990,op:quick,pos:698,val:+3.buzz diff --git a/tests/fuzzed/id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1 b/tests/fuzzed/id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1 rename to tests/fuzzed/id:000069,sig:06,src:000008,time:2614555,execs:28454,op:quick,pos:113,val:+1.buzz diff --git a/tests/fuzzed/id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3 b/tests/fuzzed/id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3 rename to tests/fuzzed/id:000069,src:000062,time:26850392,execs:125070,op:quick,pos:765,val:+3.buzz diff --git a/tests/fuzzed/id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8 b/tests/fuzzed/id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8.buzz similarity index 100% rename from tests/fuzzed/id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8 rename to tests/fuzzed/id:000070,sig:06,src:000008,time:3510036,execs:31594,op:havoc,rep:8.buzz diff --git a/tests/fuzzed/id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3 b/tests/fuzzed/id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3 rename to tests/fuzzed/id:000070,src:000062,time:26869125,execs:125130,op:quick,pos:824,val:+3.buzz diff --git a/tests/fuzzed/id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7 b/tests/fuzzed/id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7.buzz similarity index 100% rename from tests/fuzzed/id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7 rename to tests/fuzzed/id:000071,sig:06,src:000008,time:3606862,execs:31986,op:havoc,rep:7.buzz diff --git a/tests/fuzzed/id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3 b/tests/fuzzed/id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3 rename to tests/fuzzed/id:000071,src:000062,time:26897575,execs:125220,op:quick,pos:889,val:+3.buzz diff --git a/tests/fuzzed/id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3 b/tests/fuzzed/id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3 rename to tests/fuzzed/id:000072,sig:06,src:000008,time:4056407,execs:33850,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3 b/tests/fuzzed/id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3 rename to tests/fuzzed/id:000072,src:000062,time:26955312,execs:125414,op:quick,pos:1058,val:+3.buzz diff --git a/tests/fuzzed/id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4 b/tests/fuzzed/id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4 rename to tests/fuzzed/id:000073,sig:06,src:000008,time:4061094,execs:33873,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3 b/tests/fuzzed/id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3 rename to tests/fuzzed/id:000073,src:000062,time:26985803,execs:125519,op:quick,pos:1162,val:+3.buzz diff --git a/tests/fuzzed/id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5 b/tests/fuzzed/id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5 rename to tests/fuzzed/id:000074,sig:06,src:000008,time:4177920,execs:34344,op:havoc,rep:5.buzz diff --git a/tests/fuzzed/id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1 b/tests/fuzzed/id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1 rename to tests/fuzzed/id:000074,src:000062,time:27343581,execs:126803,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3 b/tests/fuzzed/id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3 rename to tests/fuzzed/id:000075,sig:06,src:000008,time:4631215,execs:36218,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2 b/tests/fuzzed/id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2 rename to tests/fuzzed/id:000075,src:000062,time:27428500,execs:127060,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1 b/tests/fuzzed/id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1 rename to tests/fuzzed/id:000076,sig:06,src:000055,time:5407943,execs:39064,op:quick,pos:26,val:+1.buzz diff --git a/tests/fuzzed/id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1 b/tests/fuzzed/id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1 rename to tests/fuzzed/id:000076,src:000062,time:27508860,execs:127320,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1 b/tests/fuzzed/id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1 rename to tests/fuzzed/id:000077,sig:06,src:000055,time:5426024,execs:39154,op:quick,pos:44,val:+1.buzz diff --git a/tests/fuzzed/id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2 b/tests/fuzzed/id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2 rename to tests/fuzzed/id:000077,src:000062,time:28280222,execs:129828,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1 b/tests/fuzzed/id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1 rename to tests/fuzzed/id:000078,sig:06,src:000055,time:5433289,execs:39190,op:quick,pos:56,val:+1.buzz diff --git a/tests/fuzzed/id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1 b/tests/fuzzed/id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1 rename to tests/fuzzed/id:000078,src:000014,time:28520594,execs:130825,op:quick,pos:320,val:+1.buzz diff --git a/tests/fuzzed/id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1 b/tests/fuzzed/id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1 rename to tests/fuzzed/id:000079,sig:06,src:000055,time:5459686,execs:39316,op:quick,pos:122,val:+1.buzz diff --git a/tests/fuzzed/id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3 b/tests/fuzzed/id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3 rename to tests/fuzzed/id:000079,src:000037,time:29046037,execs:133312,op:quick,pos:326,val:+3.buzz diff --git a/tests/fuzzed/id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1 b/tests/fuzzed/id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1 rename to tests/fuzzed/id:000080,sig:06,src:000055,time:5478330,execs:39405,op:quick,pos:151,val:+1.buzz diff --git a/tests/fuzzed/id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3 b/tests/fuzzed/id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3 rename to tests/fuzzed/id:000080,src:000037,time:29140727,execs:133730,op:quick,pos:712,val:+3.buzz diff --git a/tests/fuzzed/id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1 b/tests/fuzzed/id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1 rename to tests/fuzzed/id:000081,sig:06,src:000055,time:5520960,execs:39604,op:quick,pos:230,val:+1.buzz diff --git a/tests/fuzzed/id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1 b/tests/fuzzed/id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1 rename to tests/fuzzed/id:000081,src:000048,time:30658481,execs:148166,op:quick,pos:273,val:+1.buzz diff --git a/tests/fuzzed/id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1 b/tests/fuzzed/id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1 rename to tests/fuzzed/id:000082,sig:06,src:000055,time:5521136,execs:39605,op:quick,pos:231,val:+1.buzz diff --git a/tests/fuzzed/id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1 b/tests/fuzzed/id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1 rename to tests/fuzzed/id:000082,src:000048,time:30684031,execs:148255,op:quick,pos:361,val:+1.buzz diff --git a/tests/fuzzed/id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1 b/tests/fuzzed/id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1 rename to tests/fuzzed/id:000083,sig:06,src:000055,time:5536649,execs:39679,op:quick,pos:245,val:+1.buzz diff --git a/tests/fuzzed/id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1 b/tests/fuzzed/id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1 rename to tests/fuzzed/id:000083,src:000048,time:30709291,execs:148343,op:quick,pos:436,val:+1.buzz diff --git a/tests/fuzzed/id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1 b/tests/fuzzed/id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1 rename to tests/fuzzed/id:000084,sig:06,src:000055,time:5552734,execs:39749,op:quick,pos:314,val:+1.buzz diff --git a/tests/fuzzed/id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1 b/tests/fuzzed/id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1 rename to tests/fuzzed/id:000084,src:000048,time:30755833,execs:148502,op:quick,pos:582,val:+1.buzz diff --git a/tests/fuzzed/id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60 b/tests/fuzzed/id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60.buzz similarity index 100% rename from tests/fuzzed/id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60 rename to tests/fuzzed/id:000085,sig:06,src:000055,time:5604619,execs:39983,op:flip1,pos:60.buzz diff --git a/tests/fuzzed/id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1 b/tests/fuzzed/id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1 rename to tests/fuzzed/id:000085,src:000048,time:30778751,execs:148584,op:quick,pos:651,val:+1.buzz diff --git a/tests/fuzzed/id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186 b/tests/fuzzed/id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186.buzz similarity index 100% rename from tests/fuzzed/id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186 rename to tests/fuzzed/id:000086,sig:06,src:000055,time:5630503,execs:40108,op:flip1,pos:186.buzz diff --git a/tests/fuzzed/id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1 b/tests/fuzzed/id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1 rename to tests/fuzzed/id:000086,src:000048,time:30828467,execs:148754,op:quick,pos:796,val:+1.buzz diff --git a/tests/fuzzed/id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186 b/tests/fuzzed/id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186.buzz similarity index 100% rename from tests/fuzzed/id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186 rename to tests/fuzzed/id:000087,sig:06,src:000055,time:5700746,execs:40445,op:flip2,pos:186.buzz diff --git a/tests/fuzzed/id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1 b/tests/fuzzed/id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1 rename to tests/fuzzed/id:000087,src:000048,time:30855954,execs:148843,op:quick,pos:872,val:+1.buzz diff --git a/tests/fuzzed/id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239 b/tests/fuzzed/id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239.buzz similarity index 100% rename from tests/fuzzed/id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239 rename to tests/fuzzed/id:000088,sig:06,src:000055,time:5713841,execs:40506,op:flip2,pos:239.buzz diff --git a/tests/fuzzed/id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1 b/tests/fuzzed/id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1 rename to tests/fuzzed/id:000088,src:000048,time:30898019,execs:148990,op:quick,pos:982,val:+1.buzz diff --git a/tests/fuzzed/id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239 b/tests/fuzzed/id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239.buzz similarity index 100% rename from tests/fuzzed/id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239 rename to tests/fuzzed/id:000089,sig:06,src:000055,time:5790667,execs:40876,op:flip4,pos:239.buzz diff --git a/tests/fuzzed/id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1 b/tests/fuzzed/id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1 rename to tests/fuzzed/id:000089,src:001899,time:31699360,execs:151545,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243 b/tests/fuzzed/id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243.buzz similarity index 100% rename from tests/fuzzed/id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243 rename to tests/fuzzed/id:000090,sig:06,src:000055,time:5793602,execs:40890,op:flip4,pos:243.buzz diff --git a/tests/fuzzed/id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102 b/tests/fuzzed/id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102.buzz similarity index 100% rename from tests/fuzzed/id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102 rename to tests/fuzzed/id:000090,src:000023,time:32133122,execs:152343,op:quick,pos:102.buzz diff --git a/tests/fuzzed/id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317 b/tests/fuzzed/id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317.buzz similarity index 100% rename from tests/fuzzed/id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317 rename to tests/fuzzed/id:000091,sig:06,src:000055,time:5842975,execs:41125,op:flip32,pos:317.buzz diff --git a/tests/fuzzed/id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2 b/tests/fuzzed/id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2 rename to tests/fuzzed/id:000091,src:000031,time:35333046,execs:158378,op:quick,pos:73,val:+2.buzz diff --git a/tests/fuzzed/id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3 b/tests/fuzzed/id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3.buzz similarity index 100% rename from tests/fuzzed/id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3 rename to tests/fuzzed/id:000092,sig:06,src:000055,time:6020917,execs:41990,op:arith8,pos:112,val:-3.buzz diff --git a/tests/fuzzed/id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2 b/tests/fuzzed/id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2 rename to tests/fuzzed/id:000092,src:000017,time:36126521,execs:162046,op:quick,pos:175,val:+2.buzz diff --git a/tests/fuzzed/id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27 b/tests/fuzzed/id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27.buzz similarity index 100% rename from tests/fuzzed/id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27 rename to tests/fuzzed/id:000093,sig:06,src:000055,time:6029262,execs:42028,op:arith8,pos:112,val:+27.buzz diff --git a/tests/fuzzed/id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2 b/tests/fuzzed/id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2 rename to tests/fuzzed/id:000093,src:000017,time:36242131,execs:162494,op:quick,pos:610,val:+2.buzz diff --git a/tests/fuzzed/id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35 b/tests/fuzzed/id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35.buzz similarity index 100% rename from tests/fuzzed/id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35 rename to tests/fuzzed/id:000094,sig:06,src:000055,time:6032394,execs:42043,op:arith8,pos:112,val:-35.buzz diff --git a/tests/fuzzed/id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2 b/tests/fuzzed/id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2 rename to tests/fuzzed/id:000094,src:000017,time:36300862,execs:162728,op:quick,pos:819,val:+2.buzz diff --git a/tests/fuzzed/id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34 b/tests/fuzzed/id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34.buzz similarity index 100% rename from tests/fuzzed/id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34 rename to tests/fuzzed/id:000095,sig:06,src:000055,time:6067419,execs:42208,op:arith8,pos:127,val:+34.buzz diff --git a/tests/fuzzed/id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2 b/tests/fuzzed/id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2 rename to tests/fuzzed/id:000095,src:000017,time:36402844,execs:163118,op:quick,pos:1172,val:+2.buzz diff --git a/tests/fuzzed/id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34 b/tests/fuzzed/id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34.buzz similarity index 100% rename from tests/fuzzed/id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34 rename to tests/fuzzed/id:000096,sig:06,src:000055,time:6160725,execs:42654,op:arith8,pos:186,val:-34.buzz diff --git a/tests/fuzzed/id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2 b/tests/fuzzed/id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2 rename to tests/fuzzed/id:000096,src:000005,time:38028286,execs:169847,op:quick,pos:409,val:+2.buzz diff --git a/tests/fuzzed/id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3 b/tests/fuzzed/id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3 rename to tests/fuzzed/id:000097,sig:06,src:000055,time:6505974,execs:44419,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2 b/tests/fuzzed/id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2 rename to tests/fuzzed/id:000097,src:000005,time:38088218,execs:170086,op:quick,pos:635,val:+2.buzz diff --git a/tests/fuzzed/id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1 b/tests/fuzzed/id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1 rename to tests/fuzzed/id:000098,sig:06,src:000055,time:6555894,execs:44698,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2 b/tests/fuzzed/id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2 rename to tests/fuzzed/id:000098,src:000005,time:38114550,execs:170187,op:quick,pos:735,val:+2.buzz diff --git a/tests/fuzzed/id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7 b/tests/fuzzed/id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7.buzz similarity index 100% rename from tests/fuzzed/id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7 rename to tests/fuzzed/id:000099,sig:06,src:000055,time:6580144,execs:44831,op:havoc,rep:7.buzz diff --git a/tests/fuzzed/id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2 b/tests/fuzzed/id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2 rename to tests/fuzzed/id:000099,src:000005,time:38137561,execs:170274,op:quick,pos:821,val:+2.buzz diff --git a/tests/fuzzed/id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5 b/tests/fuzzed/id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5 rename to tests/fuzzed/id:000100,sig:06,src:000055,time:6597156,execs:44919,op:havoc,rep:5.buzz diff --git a/tests/fuzzed/id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1 b/tests/fuzzed/id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1 rename to tests/fuzzed/id:000100,src:000050,time:38768876,execs:173461,op:quick,pos:103,val:+1.buzz diff --git a/tests/fuzzed/id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8 b/tests/fuzzed/id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8.buzz similarity index 100% rename from tests/fuzzed/id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8 rename to tests/fuzzed/id:000101,sig:06,src:000055,time:6648180,execs:45187,op:havoc,rep:8.buzz diff --git a/tests/fuzzed/id:000101,src:001614,time:48112006,execs:208056,op:quick,pos:1162,val:+2 b/tests/fuzzed/id:000101,src:001614,time:48112006,execs:208056,op:quick,pos:1162,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000101,src:001614,time:48112006,execs:208056,op:quick,pos:1162,val:+2 rename to tests/fuzzed/id:000101,src:001614,time:48112006,execs:208056,op:quick,pos:1162,val:+2.buzz diff --git a/tests/fuzzed/id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6 b/tests/fuzzed/id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6.buzz similarity index 100% rename from tests/fuzzed/id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6 rename to tests/fuzzed/id:000102,sig:06,src:000055,time:6696301,execs:45445,op:havoc,rep:6.buzz diff --git a/tests/fuzzed/id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1 b/tests/fuzzed/id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1 rename to tests/fuzzed/id:000102,src:000000,time:49080496,execs:212283,op:quick,pos:294,val:+1.buzz diff --git a/tests/fuzzed/id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2 b/tests/fuzzed/id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2 rename to tests/fuzzed/id:000103,sig:06,src:000055,time:6992140,execs:47011,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2 b/tests/fuzzed/id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2 rename to tests/fuzzed/id:000103,src:001997,time:52393260,execs:226508,op:quick,pos:273,val:+2.buzz diff --git a/tests/fuzzed/id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5 b/tests/fuzzed/id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5 rename to tests/fuzzed/id:000104,sig:06,src:000055,time:7265946,execs:48467,op:havoc,rep:5.buzz diff --git a/tests/fuzzed/id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2 b/tests/fuzzed/id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2 rename to tests/fuzzed/id:000104,src:001997,time:52717851,execs:227633,op:quick,pos:1277,val:+2.buzz diff --git a/tests/fuzzed/id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4 b/tests/fuzzed/id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4 rename to tests/fuzzed/id:000105,sig:11,src:000055,time:7281766,execs:48549,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6 b/tests/fuzzed/id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6.buzz similarity index 100% rename from tests/fuzzed/id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6 rename to tests/fuzzed/id:000105,src:002280,time:53554723,execs:230519,op:quick,pos:269,val:+6.buzz diff --git a/tests/fuzzed/id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3 b/tests/fuzzed/id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3 rename to tests/fuzzed/id:000106,sig:06,src:000993,time:7459796,execs:49596,op:quick,pos:122,val:+3.buzz diff --git a/tests/fuzzed/id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6 b/tests/fuzzed/id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6.buzz similarity index 100% rename from tests/fuzzed/id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6 rename to tests/fuzzed/id:000106,src:002280,time:53853199,execs:231555,op:quick,pos:1280,val:+6.buzz diff --git a/tests/fuzzed/id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3 b/tests/fuzzed/id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3 rename to tests/fuzzed/id:000107,sig:06,src:000993,time:7462843,execs:49625,op:quick,pos:151,val:+3.buzz diff --git a/tests/fuzzed/id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3 b/tests/fuzzed/id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3 rename to tests/fuzzed/id:000107,src:002251,time:56162737,execs:243769,op:quick,pos:192,val:+3.buzz diff --git a/tests/fuzzed/id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3 b/tests/fuzzed/id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3 rename to tests/fuzzed/id:000108,sig:06,src:000993,time:7474202,execs:49705,op:quick,pos:231,val:+3.buzz diff --git a/tests/fuzzed/id:000108,src:000737,time:57203088,execs:248698,op:quick,pos:489,val:+2 b/tests/fuzzed/id:000108,src:000737,time:57203088,execs:248698,op:quick,pos:489,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000108,src:000737,time:57203088,execs:248698,op:quick,pos:489,val:+2 rename to tests/fuzzed/id:000108,src:000737,time:57203088,execs:248698,op:quick,pos:489,val:+2.buzz diff --git a/tests/fuzzed/id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14 b/tests/fuzzed/id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14 rename to tests/fuzzed/id:000109,sig:06,src:000993,time:7674377,execs:51835,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000109,src:000032,time:57809166,execs:251158,op:quick,pos:453,val:+5 b/tests/fuzzed/id:000109,src:000032,time:57809166,execs:251158,op:quick,pos:453,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000109,src:000032,time:57809166,execs:251158,op:quick,pos:453,val:+5 rename to tests/fuzzed/id:000109,src:000032,time:57809166,execs:251158,op:quick,pos:453,val:+5.buzz diff --git a/tests/fuzzed/id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4 b/tests/fuzzed/id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4 rename to tests/fuzzed/id:000110,sig:06,src:000993,time:7678243,execs:51883,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5 b/tests/fuzzed/id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5 rename to tests/fuzzed/id:000110,src:000032,time:57862230,execs:251363,op:quick,pos:633,val:+5.buzz diff --git a/tests/fuzzed/id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5 b/tests/fuzzed/id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5 rename to tests/fuzzed/id:000111,sig:06,src:000993,time:7769850,execs:52921,op:havoc,rep:5.buzz diff --git a/tests/fuzzed/id:000111,src:000032,time:57910553,execs:251551,op:quick,pos:796,val:+5 b/tests/fuzzed/id:000111,src:000032,time:57910553,execs:251551,op:quick,pos:796,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000111,src:000032,time:57910553,execs:251551,op:quick,pos:796,val:+5 rename to tests/fuzzed/id:000111,src:000032,time:57910553,execs:251551,op:quick,pos:796,val:+5.buzz diff --git a/tests/fuzzed/id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3 b/tests/fuzzed/id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3 rename to tests/fuzzed/id:000112,sig:06,src:000993,time:7815337,execs:53475,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000112,src:000032,time:57996622,execs:251899,op:quick,pos:1035,val:+5 b/tests/fuzzed/id:000112,src:000032,time:57996622,execs:251899,op:quick,pos:1035,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000112,src:000032,time:57996622,execs:251899,op:quick,pos:1035,val:+5 rename to tests/fuzzed/id:000112,src:000032,time:57996622,execs:251899,op:quick,pos:1035,val:+5.buzz diff --git a/tests/fuzzed/id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7 b/tests/fuzzed/id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7.buzz similarity index 100% rename from tests/fuzzed/id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7 rename to tests/fuzzed/id:000113,sig:06,src:000993,time:7830891,execs:53673,op:havoc,rep:7.buzz diff --git a/tests/fuzzed/id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5 b/tests/fuzzed/id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5 rename to tests/fuzzed/id:000113,src:000032,time:58155815,execs:252532,op:quick,pos:1583,val:+5.buzz diff --git a/tests/fuzzed/id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15 b/tests/fuzzed/id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15.buzz similarity index 100% rename from tests/fuzzed/id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15 rename to tests/fuzzed/id:000114,sig:06,src:000993,time:8013157,execs:55794,op:havoc,rep:15.buzz diff --git a/tests/fuzzed/id:000114,src:000032,time:58557878,execs:254103,op:havoc,rep:3 b/tests/fuzzed/id:000114,src:000032,time:58557878,execs:254103,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000114,src:000032,time:58557878,execs:254103,op:havoc,rep:3 rename to tests/fuzzed/id:000114,src:000032,time:58557878,execs:254103,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7 b/tests/fuzzed/id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7.buzz similarity index 100% rename from tests/fuzzed/id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7 rename to tests/fuzzed/id:000115,sig:06,src:001073,time:8037100,execs:56052,op:quick,pos:23,val:+7.buzz diff --git a/tests/fuzzed/id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2 b/tests/fuzzed/id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2 rename to tests/fuzzed/id:000115,src:000032,time:58726876,execs:254838,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7 b/tests/fuzzed/id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7.buzz similarity index 100% rename from tests/fuzzed/id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7 rename to tests/fuzzed/id:000116,sig:06,src:001073,time:8048681,execs:56176,op:quick,pos:123,val:+7.buzz diff --git a/tests/fuzzed/id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7 b/tests/fuzzed/id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7.buzz similarity index 100% rename from tests/fuzzed/id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7 rename to tests/fuzzed/id:000116,src:002424,time:61625154,execs:266652,op:quick,pos:963,val:+7.buzz diff --git a/tests/fuzzed/id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1 b/tests/fuzzed/id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1 rename to tests/fuzzed/id:000117,sig:06,src:000025,time:9269834,execs:61432,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11 b/tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11.buzz similarity index 100% rename from tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11 rename to tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11.buzz diff --git a/tests/fuzzed/id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2 b/tests/fuzzed/id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2 rename to tests/fuzzed/id:000118,sig:06,src:000025,time:9918752,execs:64030,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82 b/tests/fuzzed/id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82.buzz similarity index 100% rename from tests/fuzzed/id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82 rename to tests/fuzzed/id:000118,src:000002,time:63625401,execs:275620,op:quick,pos:82.buzz diff --git a/tests/fuzzed/id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1 b/tests/fuzzed/id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1 rename to tests/fuzzed/id:000119,sig:06,src:000025,time:9949208,execs:64155,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256 b/tests/fuzzed/id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256.buzz similarity index 100% rename from tests/fuzzed/id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256 rename to tests/fuzzed/id:000119,src:000002,time:63664836,execs:275795,op:quick,pos:256.buzz diff --git a/tests/fuzzed/id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34 b/tests/fuzzed/id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34.buzz similarity index 100% rename from tests/fuzzed/id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34 rename to tests/fuzzed/id:000120,sig:06,src:000033,time:10618133,execs:65391,op:quick,pos:34.buzz diff --git a/tests/fuzzed/id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373 b/tests/fuzzed/id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373.buzz similarity index 100% rename from tests/fuzzed/id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373 rename to tests/fuzzed/id:000120,src:000002,time:63692320,execs:275913,op:quick,pos:373.buzz diff --git a/tests/fuzzed/id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125 b/tests/fuzzed/id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125.buzz similarity index 100% rename from tests/fuzzed/id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125 rename to tests/fuzzed/id:000121,sig:06,src:000033,time:10729928,execs:65545,op:quick,pos:125.buzz diff --git a/tests/fuzzed/id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807 b/tests/fuzzed/id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807.buzz similarity index 100% rename from tests/fuzzed/id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807 rename to tests/fuzzed/id:000121,src:000002,time:63795623,execs:276360,op:quick,pos:807.buzz diff --git a/tests/fuzzed/id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126 b/tests/fuzzed/id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126.buzz similarity index 100% rename from tests/fuzzed/id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126 rename to tests/fuzzed/id:000122,sig:06,src:000033,time:10730659,execs:65546,op:quick,pos:126.buzz diff --git a/tests/fuzzed/id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161 b/tests/fuzzed/id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161.buzz similarity index 100% rename from tests/fuzzed/id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161 rename to tests/fuzzed/id:000122,src:000002,time:63896430,execs:276799,op:quick,pos:1161.buzz diff --git a/tests/fuzzed/id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130 b/tests/fuzzed/id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130.buzz similarity index 100% rename from tests/fuzzed/id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130 rename to tests/fuzzed/id:000123,sig:06,src:000033,time:10733578,execs:65550,op:quick,pos:130.buzz diff --git a/tests/fuzzed/id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239 b/tests/fuzzed/id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239.buzz similarity index 100% rename from tests/fuzzed/id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239 rename to tests/fuzzed/id:000123,src:000053,time:66971371,execs:290741,op:quick,pos:239.buzz diff --git a/tests/fuzzed/id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167 b/tests/fuzzed/id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167.buzz similarity index 100% rename from tests/fuzzed/id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167 rename to tests/fuzzed/id:000124,sig:06,src:000033,time:10771649,execs:65599,op:quick,pos:167.buzz diff --git a/tests/fuzzed/id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339 b/tests/fuzzed/id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339.buzz similarity index 100% rename from tests/fuzzed/id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339 rename to tests/fuzzed/id:000124,src:000053,time:66996461,execs:290854,op:quick,pos:339.buzz diff --git a/tests/fuzzed/id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200 b/tests/fuzzed/id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200.buzz similarity index 100% rename from tests/fuzzed/id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200 rename to tests/fuzzed/id:000125,sig:06,src:000033,time:10878938,execs:65728,op:quick,pos:200.buzz diff --git a/tests/fuzzed/id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199 b/tests/fuzzed/id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199.buzz similarity index 100% rename from tests/fuzzed/id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199 rename to tests/fuzzed/id:000125,src:000039,time:68732463,execs:299979,op:quick,pos:199.buzz diff --git a/tests/fuzzed/id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234 b/tests/fuzzed/id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234.buzz similarity index 100% rename from tests/fuzzed/id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234 rename to tests/fuzzed/id:000126,sig:06,src:000033,time:10930657,execs:65798,op:quick,pos:234.buzz diff --git a/tests/fuzzed/id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575 b/tests/fuzzed/id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575.buzz similarity index 100% rename from tests/fuzzed/id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575 rename to tests/fuzzed/id:000126,src:000039,time:68819907,execs:300356,op:quick,pos:575.buzz diff --git a/tests/fuzzed/id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105 b/tests/fuzzed/id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105.buzz similarity index 100% rename from tests/fuzzed/id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105 rename to tests/fuzzed/id:000127,sig:06,src:000033,time:11132540,execs:66081,op:flip1,pos:105.buzz diff --git a/tests/fuzzed/id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778 b/tests/fuzzed/id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778.buzz similarity index 100% rename from tests/fuzzed/id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778 rename to tests/fuzzed/id:000127,src:000039,time:68869489,execs:300560,op:quick,pos:778.buzz diff --git a/tests/fuzzed/id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2 b/tests/fuzzed/id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2 rename to tests/fuzzed/id:000128,sig:06,src:000042,time:12674554,execs:68759,op:inf,rep:2.buzz diff --git a/tests/fuzzed/id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938 b/tests/fuzzed/id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938.buzz similarity index 100% rename from tests/fuzzed/id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938 rename to tests/fuzzed/id:000128,src:000039,time:68913805,execs:300733,op:quick,pos:938.buzz diff --git a/tests/fuzzed/id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2 b/tests/fuzzed/id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2 rename to tests/fuzzed/id:000129,sig:06,src:000042,time:12674783,execs:68760,op:inf,rep:2.buzz diff --git a/tests/fuzzed/id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318 b/tests/fuzzed/id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318.buzz similarity index 100% rename from tests/fuzzed/id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318 rename to tests/fuzzed/id:000129,src:000039,time:69011117,execs:301126,op:quick,pos:1318.buzz diff --git a/tests/fuzzed/id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2 b/tests/fuzzed/id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2 rename to tests/fuzzed/id:000130,sig:06,src:000042,time:12675014,execs:68761,op:inf,rep:2.buzz diff --git a/tests/fuzzed/id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187 b/tests/fuzzed/id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187.buzz similarity index 100% rename from tests/fuzzed/id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187 rename to tests/fuzzed/id:000130,src:000057,time:72625976,execs:316629,op:quick,pos:187.buzz diff --git a/tests/fuzzed/id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2 b/tests/fuzzed/id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2 rename to tests/fuzzed/id:000131,sig:06,src:000042,time:12691268,execs:68827,op:inf,rep:2.buzz diff --git a/tests/fuzzed/id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9 b/tests/fuzzed/id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9.buzz similarity index 100% rename from tests/fuzzed/id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9 rename to tests/fuzzed/id:000131,src:000057,time:72856961,execs:317728,op:havoc,rep:9.buzz diff --git a/tests/fuzzed/id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224 b/tests/fuzzed/id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224.buzz similarity index 100% rename from tests/fuzzed/id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224 rename to tests/fuzzed/id:000132,sig:06,src:000042,time:12838977,execs:69470,op:quick,pos:224.buzz diff --git a/tests/fuzzed/id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139 b/tests/fuzzed/id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139.buzz similarity index 100% rename from tests/fuzzed/id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139 rename to tests/fuzzed/id:000132,src:000040,time:74481265,execs:324476,op:quick,pos:139.buzz diff --git a/tests/fuzzed/id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289 b/tests/fuzzed/id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289.buzz similarity index 100% rename from tests/fuzzed/id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289 rename to tests/fuzzed/id:000133,sig:06,src:000042,time:12877414,execs:69638,op:quick,pos:289.buzz diff --git a/tests/fuzzed/id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241 b/tests/fuzzed/id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241.buzz similarity index 100% rename from tests/fuzzed/id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241 rename to tests/fuzzed/id:000133,src:000040,time:74505122,execs:324579,op:quick,pos:241.buzz diff --git a/tests/fuzzed/id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986 b/tests/fuzzed/id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986.buzz similarity index 100% rename from tests/fuzzed/id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986 rename to tests/fuzzed/id:000134,sig:06,src:000042,time:13102189,execs:70564,op:quick,pos:986.buzz diff --git a/tests/fuzzed/id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272 b/tests/fuzzed/id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272.buzz similarity index 100% rename from tests/fuzzed/id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272 rename to tests/fuzzed/id:000134,src:002271,time:75747279,execs:329773,op:quick,pos:272.buzz diff --git a/tests/fuzzed/id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084 b/tests/fuzzed/id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084.buzz similarity index 100% rename from tests/fuzzed/id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084 rename to tests/fuzzed/id:000135,sig:11,src:000042,time:13150009,execs:70758,op:quick,pos:1084.buzz diff --git a/tests/fuzzed/id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283 b/tests/fuzzed/id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283.buzz similarity index 100% rename from tests/fuzzed/id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283 rename to tests/fuzzed/id:000135,src:002271,time:76064205,execs:330797,op:quick,pos:1283.buzz diff --git a/tests/fuzzed/id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309 b/tests/fuzzed/id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309.buzz similarity index 100% rename from tests/fuzzed/id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309 rename to tests/fuzzed/id:000136,sig:06,src:000042,time:13234094,execs:71080,op:quick,pos:1309.buzz diff --git a/tests/fuzzed/id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179 b/tests/fuzzed/id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179.buzz similarity index 100% rename from tests/fuzzed/id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179 rename to tests/fuzzed/id:000136,src:000012,time:84717279,execs:364061,op:quick,pos:179.buzz diff --git a/tests/fuzzed/id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110 b/tests/fuzzed/id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110.buzz similarity index 100% rename from tests/fuzzed/id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110 rename to tests/fuzzed/id:000137,sig:06,src:000042,time:13422798,execs:71869,op:flip1,pos:1110.buzz diff --git a/tests/fuzzed/id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335 b/tests/fuzzed/id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335.buzz similarity index 100% rename from tests/fuzzed/id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335 rename to tests/fuzzed/id:000137,src:000058,time:84933133,execs:364998,op:quick,pos:335.buzz diff --git a/tests/fuzzed/id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112 b/tests/fuzzed/id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112.buzz similarity index 100% rename from tests/fuzzed/id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112 rename to tests/fuzzed/id:000138,sig:06,src:000042,time:13424527,execs:71876,op:flip1,pos:1112.buzz diff --git a/tests/fuzzed/id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148 b/tests/fuzzed/id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148.buzz similarity index 100% rename from tests/fuzzed/id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148 rename to tests/fuzzed/id:000138,src:000016,time:89300118,execs:384604,op:quick,pos:148.buzz diff --git a/tests/fuzzed/id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2 b/tests/fuzzed/id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2 rename to tests/fuzzed/id:000139,sig:06,src:000042,time:13700952,execs:73041,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385 b/tests/fuzzed/id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385.buzz similarity index 100% rename from tests/fuzzed/id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385 rename to tests/fuzzed/id:000139,src:000016,time:89357369,execs:384854,op:quick,pos:385.buzz diff --git a/tests/fuzzed/id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1 b/tests/fuzzed/id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1 rename to tests/fuzzed/id:000140,sig:06,src:000042,time:13733874,execs:73181,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271 b/tests/fuzzed/id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271.buzz similarity index 100% rename from tests/fuzzed/id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271 rename to tests/fuzzed/id:000140,src:001946,time:92042894,execs:396343,op:quick,pos:271.buzz diff --git a/tests/fuzzed/id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2 b/tests/fuzzed/id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2 rename to tests/fuzzed/id:000141,sig:06,src:000042,time:13837821,execs:73611,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188 b/tests/fuzzed/id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188.buzz similarity index 100% rename from tests/fuzzed/id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188 rename to tests/fuzzed/id:000141,src:002252,time:93070185,execs:400582,op:quick,pos:188.buzz diff --git a/tests/fuzzed/id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1 b/tests/fuzzed/id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1 rename to tests/fuzzed/id:000142,sig:06,src:000042,time:13838964,execs:73616,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275 b/tests/fuzzed/id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275.buzz similarity index 100% rename from tests/fuzzed/id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275 rename to tests/fuzzed/id:000142,src:002528,time:94883913,execs:411509,op:quick,pos:275.buzz diff --git a/tests/fuzzed/id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2 b/tests/fuzzed/id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2 rename to tests/fuzzed/id:000143,sig:06,src:000042,time:13845124,execs:73643,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486 b/tests/fuzzed/id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486.buzz similarity index 100% rename from tests/fuzzed/id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486 rename to tests/fuzzed/id:000143,src:000755,time:98888502,execs:427842,op:quick,pos:486.buzz diff --git a/tests/fuzzed/id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2 b/tests/fuzzed/id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2 rename to tests/fuzzed/id:000144,sig:06,src:000042,time:14025464,execs:74393,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424 b/tests/fuzzed/id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424.buzz similarity index 100% rename from tests/fuzzed/id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424 rename to tests/fuzzed/id:000144,src:001522,time:103858379,execs:448821,op:quick,pos:424.buzz diff --git a/tests/fuzzed/id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1 b/tests/fuzzed/id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1 rename to tests/fuzzed/id:000145,sig:06,src:000042,time:14121826,execs:74794,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213 b/tests/fuzzed/id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213.buzz similarity index 100% rename from tests/fuzzed/id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213 rename to tests/fuzzed/id:000145,src:000038,time:104657823,execs:451929,op:quick,pos:213.buzz diff --git a/tests/fuzzed/id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2 b/tests/fuzzed/id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2 rename to tests/fuzzed/id:000146,sig:06,src:000042,time:14463265,execs:76249,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276 b/tests/fuzzed/id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276.buzz similarity index 100% rename from tests/fuzzed/id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276 rename to tests/fuzzed/id:000146,src:002286,time:112146080,execs:481926,op:quick,pos:276.buzz diff --git a/tests/fuzzed/id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1 b/tests/fuzzed/id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1 rename to tests/fuzzed/id:000147,sig:11,src:001346,time:15760059,execs:81806,op:quick,pos:1085,val:+1.buzz diff --git a/tests/fuzzed/id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269 b/tests/fuzzed/id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269.buzz similarity index 100% rename from tests/fuzzed/id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269 rename to tests/fuzzed/id:000147,src:002673,time:113015992,execs:485048,op:quick,pos:269.buzz diff --git a/tests/fuzzed/id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1 b/tests/fuzzed/id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1 rename to tests/fuzzed/id:000148,sig:11,src:001346,time:15760548,execs:81808,op:quick,pos:1087,val:+1.buzz diff --git a/tests/fuzzed/id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564 b/tests/fuzzed/id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564.buzz similarity index 100% rename from tests/fuzzed/id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564 rename to tests/fuzzed/id:000148,src:002407,time:114577936,execs:491508,op:quick,pos:1564.buzz diff --git a/tests/fuzzed/id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1 b/tests/fuzzed/id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1 rename to tests/fuzzed/id:000149,sig:06,src:000041,time:17182551,execs:87620,op:quick,pos:123,val:+1.buzz diff --git a/tests/fuzzed/id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242 b/tests/fuzzed/id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242.buzz similarity index 100% rename from tests/fuzzed/id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242 rename to tests/fuzzed/id:000149,src:000024,time:120573893,execs:513984,op:quick,pos:242.buzz diff --git a/tests/fuzzed/id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1 b/tests/fuzzed/id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1 rename to tests/fuzzed/id:000150,sig:06,src:000041,time:17217299,execs:87755,op:quick,pos:209,val:+1.buzz diff --git a/tests/fuzzed/id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520 b/tests/fuzzed/id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520.buzz similarity index 100% rename from tests/fuzzed/id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520 rename to tests/fuzzed/id:000150,src:000024,time:120642287,execs:514287,op:quick,pos:520.buzz diff --git a/tests/fuzzed/id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1 b/tests/fuzzed/id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1 rename to tests/fuzzed/id:000151,sig:06,src:000041,time:17229285,execs:87812,op:quick,pos:230,val:+1.buzz diff --git a/tests/fuzzed/id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2 b/tests/fuzzed/id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2 rename to tests/fuzzed/id:000151,src:000024,time:120901995,execs:515417,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1 b/tests/fuzzed/id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1 rename to tests/fuzzed/id:000152,sig:06,src:000041,time:17325009,execs:88181,op:quick,pos:478,val:+1.buzz diff --git a/tests/fuzzed/id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995 b/tests/fuzzed/id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995.buzz similarity index 100% rename from tests/fuzzed/id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995 rename to tests/fuzzed/id:000152,src:002620,time:121738515,execs:518760,op:quick,pos:995.buzz diff --git a/tests/fuzzed/id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1 b/tests/fuzzed/id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1 rename to tests/fuzzed/id:000153,sig:06,src:000041,time:17386339,execs:88410,op:quick,pos:659,val:+1.buzz diff --git a/tests/fuzzed/id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98 b/tests/fuzzed/id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98.buzz similarity index 100% rename from tests/fuzzed/id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98 rename to tests/fuzzed/id:000153,src:000047,time:124016451,execs:527534,op:quick,pos:98.buzz diff --git a/tests/fuzzed/id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1 b/tests/fuzzed/id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1 rename to tests/fuzzed/id:000154,sig:06,src:000041,time:17416405,execs:88510,op:quick,pos:758,val:+1.buzz diff --git a/tests/fuzzed/id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650 b/tests/fuzzed/id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650.buzz similarity index 100% rename from tests/fuzzed/id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650 rename to tests/fuzzed/id:000154,src:000047,time:124150367,execs:528099,op:quick,pos:650.buzz diff --git a/tests/fuzzed/id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1 b/tests/fuzzed/id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1 rename to tests/fuzzed/id:000155,sig:06,src:000041,time:17534453,execs:88939,op:quick,pos:1103,val:+1.buzz diff --git a/tests/fuzzed/id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330 b/tests/fuzzed/id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330.buzz similarity index 100% rename from tests/fuzzed/id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330 rename to tests/fuzzed/id:000155,src:000036,time:126120097,execs:536761,op:quick,pos:330.buzz diff --git a/tests/fuzzed/id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1 b/tests/fuzzed/id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1 rename to tests/fuzzed/id:000156,sig:06,src:000041,time:17550174,execs:89002,op:quick,pos:1118,val:+1.buzz diff --git a/tests/fuzzed/id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917 b/tests/fuzzed/id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917.buzz similarity index 100% rename from tests/fuzzed/id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917 rename to tests/fuzzed/id:000156,src:000036,time:126273407,execs:537385,op:quick,pos:917.buzz diff --git a/tests/fuzzed/id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1 b/tests/fuzzed/id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1 rename to tests/fuzzed/id:000157,sig:06,src:000041,time:17558416,execs:89034,op:quick,pos:1150,val:+1.buzz diff --git a/tests/fuzzed/id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144 b/tests/fuzzed/id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144.buzz similarity index 100% rename from tests/fuzzed/id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144 rename to tests/fuzzed/id:000157,src:000011,time:132646048,execs:564729,op:quick,pos:144.buzz diff --git a/tests/fuzzed/id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1 b/tests/fuzzed/id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1 rename to tests/fuzzed/id:000158,sig:06,src:000041,time:17560428,execs:89042,op:quick,pos:1158,val:+1.buzz diff --git a/tests/fuzzed/id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8 b/tests/fuzzed/id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8.buzz similarity index 100% rename from tests/fuzzed/id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8 rename to tests/fuzzed/id:000158,src:001756,time:147926702,execs:620168,op:quick,pos:8.buzz diff --git a/tests/fuzzed/id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1 b/tests/fuzzed/id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1 rename to tests/fuzzed/id:000159,sig:06,src:000041,time:17620059,execs:89256,op:quick,pos:1348,val:+1.buzz diff --git a/tests/fuzzed/id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200 b/tests/fuzzed/id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200.buzz similarity index 100% rename from tests/fuzzed/id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200 rename to tests/fuzzed/id:000159,src:000030,time:151166653,execs:631064,op:quick,pos:200.buzz diff --git a/tests/fuzzed/id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367 b/tests/fuzzed/id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367.buzz similarity index 100% rename from tests/fuzzed/id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367 rename to tests/fuzzed/id:000160,sig:06,src:000041,time:17808080,execs:89986,op:flip2,pos:367.buzz diff --git a/tests/fuzzed/id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289 b/tests/fuzzed/id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289.buzz similarity index 100% rename from tests/fuzzed/id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289 rename to tests/fuzzed/id:000160,src:000030,time:151195334,execs:631178,op:quick,pos:289.buzz diff --git a/tests/fuzzed/id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105 b/tests/fuzzed/id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105.buzz similarity index 100% rename from tests/fuzzed/id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105 rename to tests/fuzzed/id:000161,sig:06,src:000041,time:17849378,execs:90143,op:flip2,pos:1105.buzz diff --git a/tests/fuzzed/id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671 b/tests/fuzzed/id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671.buzz similarity index 100% rename from tests/fuzzed/id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671 rename to tests/fuzzed/id:000161,src:000030,time:151298817,execs:631609,op:quick,pos:671.buzz diff --git a/tests/fuzzed/id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597 b/tests/fuzzed/id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597.buzz similarity index 100% rename from tests/fuzzed/id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597 rename to tests/fuzzed/id:000162,sig:06,src:000003,time:18752646,execs:93847,op:quick,pos:597.buzz diff --git a/tests/fuzzed/id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20 b/tests/fuzzed/id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20.buzz similarity index 100% rename from tests/fuzzed/id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20 rename to tests/fuzzed/id:000162,src:000030,time:151734520,execs:633310,op:arith8,pos:439,val:+20.buzz diff --git a/tests/fuzzed/id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624 b/tests/fuzzed/id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624.buzz similarity index 100% rename from tests/fuzzed/id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624 rename to tests/fuzzed/id:000163,sig:06,src:000003,time:19062258,execs:94996,op:quick,pos:1624.buzz diff --git a/tests/fuzzed/id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27 b/tests/fuzzed/id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27.buzz similarity index 100% rename from tests/fuzzed/id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27 rename to tests/fuzzed/id:000163,src:000030,time:151877078,execs:633895,op:arith8,pos:1177,val:+27.buzz diff --git a/tests/fuzzed/id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732 b/tests/fuzzed/id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732.buzz similarity index 100% rename from tests/fuzzed/id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732 rename to tests/fuzzed/id:000164,sig:11,src:000003,time:19095426,execs:95116,op:quick,pos:1732.buzz diff --git a/tests/fuzzed/id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145 b/tests/fuzzed/id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145.buzz similarity index 100% rename from tests/fuzzed/id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145 rename to tests/fuzzed/id:000164,src:001475,time:154919895,execs:647201,op:quick,pos:145.buzz diff --git a/tests/fuzzed/id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4 b/tests/fuzzed/id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4 rename to tests/fuzzed/id:000165,sig:06,src:000029,time:19996347,execs:98774,op:quick,pos:42,val:+4.buzz diff --git a/tests/fuzzed/id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113 b/tests/fuzzed/id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113.buzz similarity index 100% rename from tests/fuzzed/id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113 rename to tests/fuzzed/id:000165,src:001475,time:155188552,execs:648170,op:quick,pos:1113.buzz diff --git a/tests/fuzzed/id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4 b/tests/fuzzed/id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4 rename to tests/fuzzed/id:000166,sig:06,src:000029,time:20004883,execs:98814,op:quick,pos:82,val:+4.buzz diff --git a/tests/fuzzed/id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906 b/tests/fuzzed/id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906.buzz similarity index 100% rename from tests/fuzzed/id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906 rename to tests/fuzzed/id:000166,src:001475,time:155429965,execs:648988,op:quick,pos:1906.buzz diff --git a/tests/fuzzed/id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4 b/tests/fuzzed/id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4 rename to tests/fuzzed/id:000167,sig:06,src:000029,time:20032108,execs:98934,op:quick,pos:178,val:+4.buzz diff --git a/tests/fuzzed/id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488 b/tests/fuzzed/id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488.buzz similarity index 100% rename from tests/fuzzed/id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488 rename to tests/fuzzed/id:000167,src:002330,time:167303517,execs:690662,op:quick,pos:488.buzz diff --git a/tests/fuzzed/id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4 b/tests/fuzzed/id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4 rename to tests/fuzzed/id:000168,sig:06,src:000029,time:20130305,execs:99336,op:quick,pos:543,val:+4.buzz diff --git a/tests/fuzzed/id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361 b/tests/fuzzed/id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361.buzz similarity index 100% rename from tests/fuzzed/id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361 rename to tests/fuzzed/id:000168,src:002295,time:169552579,execs:700399,op:quick,pos:361.buzz diff --git a/tests/fuzzed/id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4 b/tests/fuzzed/id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4 rename to tests/fuzzed/id:000169,sig:06,src:000029,time:20140911,execs:99379,op:quick,pos:574,val:+4.buzz diff --git a/tests/fuzzed/id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4 b/tests/fuzzed/id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4 rename to tests/fuzzed/id:000169,src:002931,time:172114514,execs:710320,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4 b/tests/fuzzed/id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4 rename to tests/fuzzed/id:000170,sig:06,src:000029,time:20287093,execs:99951,op:quick,pos:1097,val:+4.buzz diff --git a/tests/fuzzed/id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545 b/tests/fuzzed/id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545.buzz similarity index 100% rename from tests/fuzzed/id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545 rename to tests/fuzzed/id:000170,src:002049,time:172859960,execs:712036,op:quick,pos:545.buzz diff --git a/tests/fuzzed/id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14 b/tests/fuzzed/id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14.buzz similarity index 100% rename from tests/fuzzed/id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14 rename to tests/fuzzed/id:000171,sig:06,src:000029,time:20554693,execs:101095,op:arith8,pos:1177,val:-14.buzz diff --git a/tests/fuzzed/id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111 b/tests/fuzzed/id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111.buzz similarity index 100% rename from tests/fuzzed/id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111 rename to tests/fuzzed/id:000171,src:000045,time:180281587,execs:738632,op:quick,pos:111.buzz diff --git a/tests/fuzzed/id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3 b/tests/fuzzed/id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3 rename to tests/fuzzed/id:000172,sig:06,src:000043,time:21391248,execs:104731,op:inf,rep:3.buzz diff --git a/tests/fuzzed/id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179 b/tests/fuzzed/id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179.buzz similarity index 100% rename from tests/fuzzed/id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179 rename to tests/fuzzed/id:000172,src:000045,time:180306068,execs:738725,op:quick,pos:179.buzz diff --git a/tests/fuzzed/id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3 b/tests/fuzzed/id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3 rename to tests/fuzzed/id:000173,sig:06,src:000043,time:21686281,execs:105821,op:quick,pos:763,val:+3.buzz diff --git a/tests/fuzzed/id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146 b/tests/fuzzed/id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146.buzz similarity index 100% rename from tests/fuzzed/id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146 rename to tests/fuzzed/id:000173,src:002993,time:181655026,execs:744458,op:quick,pos:1146.buzz diff --git a/tests/fuzzed/id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3 b/tests/fuzzed/id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3 rename to tests/fuzzed/id:000174,sig:06,src:000043,time:21692063,execs:105842,op:quick,pos:772,val:+3.buzz diff --git a/tests/fuzzed/id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793 b/tests/fuzzed/id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793.buzz similarity index 100% rename from tests/fuzzed/id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793 rename to tests/fuzzed/id:000174,src:002585,time:182673300,execs:748408,op:quick,pos:793.buzz diff --git a/tests/fuzzed/id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3 b/tests/fuzzed/id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3 rename to tests/fuzzed/id:000175,sig:06,src:000043,time:21774292,execs:106146,op:quick,pos:1039,val:+3.buzz diff --git a/tests/fuzzed/id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192 b/tests/fuzzed/id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192.buzz similarity index 100% rename from tests/fuzzed/id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192 rename to tests/fuzzed/id:000175,src:002248,time:187493256,execs:772257,op:quick,pos:192.buzz diff --git a/tests/fuzzed/id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3 b/tests/fuzzed/id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3 rename to tests/fuzzed/id:000176,sig:06,src:000043,time:21883689,execs:106523,op:quick,pos:1379,val:+3.buzz diff --git a/tests/fuzzed/id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96 b/tests/fuzzed/id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96.buzz similarity index 100% rename from tests/fuzzed/id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96 rename to tests/fuzzed/id:000176,src:002034,time:189032794,execs:779095,op:quick,pos:96.buzz diff --git a/tests/fuzzed/id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3 b/tests/fuzzed/id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3 rename to tests/fuzzed/id:000177,sig:06,src:000043,time:21960753,execs:106794,op:quick,pos:1638,val:+3.buzz diff --git a/tests/fuzzed/id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774 b/tests/fuzzed/id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774.buzz similarity index 100% rename from tests/fuzzed/id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774 rename to tests/fuzzed/id:000177,src:002034,time:189421710,execs:779774,op:quick,pos:774.buzz diff --git a/tests/fuzzed/id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3 b/tests/fuzzed/id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3 rename to tests/fuzzed/id:000178,sig:06,src:000043,time:21965617,execs:106813,op:quick,pos:1645,val:+3.buzz diff --git a/tests/fuzzed/id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056 b/tests/fuzzed/id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056.buzz similarity index 100% rename from tests/fuzzed/id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056 rename to tests/fuzzed/id:000178,src:001735,time:195697600,execs:801006,op:quick,pos:1056.buzz diff --git a/tests/fuzzed/id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3 b/tests/fuzzed/id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3 rename to tests/fuzzed/id:000179,sig:06,src:000043,time:21973559,execs:106843,op:quick,pos:1675,val:+3.buzz diff --git a/tests/fuzzed/id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422 b/tests/fuzzed/id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422.buzz similarity index 100% rename from tests/fuzzed/id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422 rename to tests/fuzzed/id:000179,src:001511,time:198594135,execs:814057,op:quick,pos:422.buzz diff --git a/tests/fuzzed/id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166 b/tests/fuzzed/id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166.buzz similarity index 100% rename from tests/fuzzed/id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166 rename to tests/fuzzed/id:000180,sig:06,src:000043,time:22085529,execs:107218,op:flip2,pos:166.buzz diff --git a/tests/fuzzed/id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197 b/tests/fuzzed/id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197.buzz similarity index 100% rename from tests/fuzzed/id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197 rename to tests/fuzzed/id:000180,src:001511,time:199075942,execs:815845,op:quick,pos:2197.buzz diff --git a/tests/fuzzed/id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2 b/tests/fuzzed/id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2 rename to tests/fuzzed/id:000181,sig:06,src:000043,time:22793575,execs:109779,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489 b/tests/fuzzed/id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489.buzz similarity index 100% rename from tests/fuzzed/id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489 rename to tests/fuzzed/id:000181,src:000723,time:202248786,execs:827898,op:quick,pos:489.buzz diff --git a/tests/fuzzed/id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2 b/tests/fuzzed/id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2 rename to tests/fuzzed/id:000182,sig:06,src:000043,time:23096210,execs:110896,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275 b/tests/fuzzed/id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275.buzz similarity index 100% rename from tests/fuzzed/id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275 rename to tests/fuzzed/id:000182,src:003065,time:202691712,execs:829235,op:quick,pos:275.buzz diff --git a/tests/fuzzed/id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2 b/tests/fuzzed/id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2 rename to tests/fuzzed/id:000183,sig:11,src:001513,time:24670687,execs:116699,op:quick,pos:1732,val:+2.buzz diff --git a/tests/fuzzed/id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8 b/tests/fuzzed/id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8.buzz similarity index 100% rename from tests/fuzzed/id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8 rename to tests/fuzzed/id:000183,src:001769,time:203941473,execs:834350,op:quick,pos:8.buzz diff --git a/tests/fuzzed/id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2 b/tests/fuzzed/id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2 rename to tests/fuzzed/id:000184,sig:06,src:001513,time:24726807,execs:116894,op:quick,pos:1903,val:+2.buzz diff --git a/tests/fuzzed/id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523 b/tests/fuzzed/id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523.buzz similarity index 100% rename from tests/fuzzed/id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523 rename to tests/fuzzed/id:000184,src:001769,time:204389712,execs:835926,op:quick,pos:1523.buzz diff --git a/tests/fuzzed/id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2 b/tests/fuzzed/id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2 rename to tests/fuzzed/id:000185,sig:06,src:001513,time:24733896,execs:116921,op:quick,pos:1930,val:+2.buzz diff --git a/tests/fuzzed/id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270 b/tests/fuzzed/id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270.buzz similarity index 100% rename from tests/fuzzed/id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270 rename to tests/fuzzed/id:000185,src:002566,time:205435280,execs:839748,op:quick,pos:270.buzz diff --git a/tests/fuzzed/id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2 b/tests/fuzzed/id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2 rename to tests/fuzzed/id:000186,sig:06,src:001513,time:24749023,execs:116978,op:quick,pos:1975,val:+2.buzz diff --git a/tests/fuzzed/id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214 b/tests/fuzzed/id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214.buzz similarity index 100% rename from tests/fuzzed/id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214 rename to tests/fuzzed/id:000186,src:000052,time:210967608,execs:860605,op:quick,pos:214.buzz diff --git a/tests/fuzzed/id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3 b/tests/fuzzed/id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3 rename to tests/fuzzed/id:000187,sig:06,src:000062,time:26456345,execs:123726,op:inf,rep:3.buzz diff --git a/tests/fuzzed/id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164 b/tests/fuzzed/id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164.buzz similarity index 100% rename from tests/fuzzed/id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164 rename to tests/fuzzed/id:000187,src:000004,time:214211283,execs:873047,op:quick,pos:164.buzz diff --git a/tests/fuzzed/id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3 b/tests/fuzzed/id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3 rename to tests/fuzzed/id:000188,sig:06,src:000062,time:26522012,execs:123960,op:inf,rep:3.buzz diff --git a/tests/fuzzed/id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380 b/tests/fuzzed/id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380.buzz similarity index 100% rename from tests/fuzzed/id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380 rename to tests/fuzzed/id:000188,src:000004,time:214275257,execs:873288,op:quick,pos:380.buzz diff --git a/tests/fuzzed/id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2 b/tests/fuzzed/id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2 rename to tests/fuzzed/id:000189,sig:06,src:000062,time:27533658,execs:127407,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650 b/tests/fuzzed/id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650.buzz similarity index 100% rename from tests/fuzzed/id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650 rename to tests/fuzzed/id:000189,src:000004,time:214362282,execs:873607,op:quick,pos:650.buzz diff --git a/tests/fuzzed/id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2 b/tests/fuzzed/id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2 rename to tests/fuzzed/id:000190,sig:06,src:000062,time:27575102,execs:127519,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037 b/tests/fuzzed/id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037.buzz similarity index 100% rename from tests/fuzzed/id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037 rename to tests/fuzzed/id:000190,src:000004,time:214471338,execs:874019,op:quick,pos:1037.buzz diff --git a/tests/fuzzed/id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2 b/tests/fuzzed/id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2 rename to tests/fuzzed/id:000191,sig:06,src:000062,time:27601964,execs:127607,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350 b/tests/fuzzed/id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350.buzz similarity index 100% rename from tests/fuzzed/id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350 rename to tests/fuzzed/id:000191,src:000004,time:214562447,execs:874357,op:quick,pos:1350.buzz diff --git a/tests/fuzzed/id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2 b/tests/fuzzed/id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2 rename to tests/fuzzed/id:000192,sig:06,src:000062,time:27613589,execs:127646,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95 b/tests/fuzzed/id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95.buzz similarity index 100% rename from tests/fuzzed/id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95 rename to tests/fuzzed/id:000192,src:002024,time:216472182,execs:880398,op:quick,pos:95.buzz diff --git a/tests/fuzzed/id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1 b/tests/fuzzed/id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1 rename to tests/fuzzed/id:000193,sig:06,src:000062,time:27670992,execs:127846,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1 b/tests/fuzzed/id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1 rename to tests/fuzzed/id:000194,sig:06,src:000062,time:27946896,execs:128742,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2 b/tests/fuzzed/id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2 rename to tests/fuzzed/id:000195,sig:06,src:000062,time:28222078,execs:129633,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1 b/tests/fuzzed/id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1 rename to tests/fuzzed/id:000196,sig:11,src:000014,time:28508916,execs:130776,op:quick,pos:272,val:+1.buzz diff --git a/tests/fuzzed/id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1 b/tests/fuzzed/id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1 rename to tests/fuzzed/id:000197,sig:11,src:000014,time:28587620,execs:131137,op:quick,pos:620,val:+1.buzz diff --git a/tests/fuzzed/id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3 b/tests/fuzzed/id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3.buzz similarity index 100% rename from tests/fuzzed/id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3 rename to tests/fuzzed/id:000198,sig:11,src:000037,time:29077210,execs:133450,op:quick,pos:452,val:+3.buzz diff --git a/tests/fuzzed/id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26 b/tests/fuzzed/id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26.buzz similarity index 100% rename from tests/fuzzed/id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26 rename to tests/fuzzed/id:000199,sig:06,src:000101,time:29397323,execs:135059,op:arith8,pos:13,val:+26.buzz diff --git a/tests/fuzzed/id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13 b/tests/fuzzed/id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13.buzz similarity index 100% rename from tests/fuzzed/id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13 rename to tests/fuzzed/id:000200,sig:06,src:000101,time:29407430,execs:135235,op:havoc,rep:13.buzz diff --git a/tests/fuzzed/id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15 b/tests/fuzzed/id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15.buzz similarity index 100% rename from tests/fuzzed/id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15 rename to tests/fuzzed/id:000201,sig:06,src:000101,time:29420002,execs:135521,op:havoc,rep:15.buzz diff --git a/tests/fuzzed/id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13 b/tests/fuzzed/id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13.buzz similarity index 100% rename from tests/fuzzed/id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13 rename to tests/fuzzed/id:000202,sig:06,src:000101,time:29420590,execs:135536,op:havoc,rep:13.buzz diff --git a/tests/fuzzed/id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9 b/tests/fuzzed/id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9.buzz similarity index 100% rename from tests/fuzzed/id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9 rename to tests/fuzzed/id:000203,sig:06,src:000101,time:29450311,execs:136209,op:havoc,rep:9.buzz diff --git a/tests/fuzzed/id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10 b/tests/fuzzed/id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10.buzz similarity index 100% rename from tests/fuzzed/id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10 rename to tests/fuzzed/id:000204,sig:06,src:000101,time:29492045,execs:137161,op:havoc,rep:10.buzz diff --git a/tests/fuzzed/id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12 b/tests/fuzzed/id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12.buzz similarity index 100% rename from tests/fuzzed/id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12 rename to tests/fuzzed/id:000205,sig:06,src:000101,time:29503454,execs:137426,op:havoc,rep:12.buzz diff --git a/tests/fuzzed/id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14 b/tests/fuzzed/id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14 rename to tests/fuzzed/id:000206,sig:06,src:000101,time:29522839,execs:137871,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000207,sig:06,src:000101,time:29549985,execs:138505,op:havoc,rep:10 b/tests/fuzzed/id:000207,sig:06,src:000101,time:29549985,execs:138505,op:havoc,rep:10.buzz similarity index 100% rename from tests/fuzzed/id:000207,sig:06,src:000101,time:29549985,execs:138505,op:havoc,rep:10 rename to tests/fuzzed/id:000207,sig:06,src:000101,time:29549985,execs:138505,op:havoc,rep:10.buzz diff --git a/tests/fuzzed/id:000208,sig:06,src:000026,time:29630501,execs:139797,op:inf,rep:12 b/tests/fuzzed/id:000208,sig:06,src:000026,time:29630501,execs:139797,op:inf,rep:12.buzz similarity index 100% rename from tests/fuzzed/id:000208,sig:06,src:000026,time:29630501,execs:139797,op:inf,rep:12 rename to tests/fuzzed/id:000208,sig:06,src:000026,time:29630501,execs:139797,op:inf,rep:12.buzz diff --git a/tests/fuzzed/id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12 b/tests/fuzzed/id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12.buzz similarity index 100% rename from tests/fuzzed/id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12 rename to tests/fuzzed/id:000209,sig:06,src:000026,time:29630595,execs:139798,op:inf,rep:12.buzz diff --git a/tests/fuzzed/id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69 b/tests/fuzzed/id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69.buzz similarity index 100% rename from tests/fuzzed/id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69 rename to tests/fuzzed/id:000210,sig:06,src:000026,time:29775683,execs:141256,op:flip1,pos:69.buzz diff --git a/tests/fuzzed/id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1 b/tests/fuzzed/id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1 rename to tests/fuzzed/id:000211,sig:06,src:000048,time:30611700,execs:147988,op:quick,pos:96,val:+1.buzz diff --git a/tests/fuzzed/id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1 b/tests/fuzzed/id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1 rename to tests/fuzzed/id:000212,sig:06,src:000048,time:30639923,execs:148098,op:quick,pos:206,val:+1.buzz diff --git a/tests/fuzzed/id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1 b/tests/fuzzed/id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1 rename to tests/fuzzed/id:000213,sig:06,src:000048,time:30706654,execs:148338,op:quick,pos:432,val:+1.buzz diff --git a/tests/fuzzed/id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1 b/tests/fuzzed/id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1 rename to tests/fuzzed/id:000214,sig:06,src:000048,time:30729033,execs:148412,op:quick,pos:505,val:+1.buzz diff --git a/tests/fuzzed/id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1 b/tests/fuzzed/id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1 rename to tests/fuzzed/id:000215,sig:06,src:000048,time:30775865,execs:148578,op:quick,pos:646,val:+1.buzz diff --git a/tests/fuzzed/id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1 b/tests/fuzzed/id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1 rename to tests/fuzzed/id:000216,sig:06,src:000048,time:30880180,execs:148928,op:quick,pos:945,val:+1.buzz diff --git a/tests/fuzzed/id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1 b/tests/fuzzed/id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1 rename to tests/fuzzed/id:000217,sig:06,src:000048,time:30893991,execs:148980,op:quick,pos:973,val:+1.buzz diff --git a/tests/fuzzed/id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1 b/tests/fuzzed/id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1 rename to tests/fuzzed/id:000218,sig:06,src:000048,time:31098067,execs:149571,op:quick,pos:1167,val:+1.buzz diff --git a/tests/fuzzed/id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1 b/tests/fuzzed/id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1 rename to tests/fuzzed/id:000219,sig:06,src:000048,time:31127331,execs:149663,op:quick,pos:1187,val:+1.buzz diff --git a/tests/fuzzed/id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1 b/tests/fuzzed/id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1 rename to tests/fuzzed/id:000220,sig:06,src:000048,time:31133468,execs:149681,op:quick,pos:1193,val:+1.buzz diff --git a/tests/fuzzed/id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1 b/tests/fuzzed/id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1.buzz similarity index 100% rename from tests/fuzzed/id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1 rename to tests/fuzzed/id:000221,sig:06,src:000048,time:31134081,execs:149683,op:quick,pos:1195,val:+1.buzz diff --git a/tests/fuzzed/id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1 b/tests/fuzzed/id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1 rename to tests/fuzzed/id:000222,sig:11,src:000023,time:33486227,execs:154769,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2 b/tests/fuzzed/id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2 rename to tests/fuzzed/id:000223,sig:11,src:000023,time:33501291,execs:154794,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1 b/tests/fuzzed/id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1 rename to tests/fuzzed/id:000224,sig:11,src:000023,time:33514023,execs:154818,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2 b/tests/fuzzed/id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2 rename to tests/fuzzed/id:000225,sig:06,src:000031,time:35414892,execs:158766,op:quick,pos:413,val:+2.buzz diff --git a/tests/fuzzed/id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13 b/tests/fuzzed/id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13.buzz similarity index 100% rename from tests/fuzzed/id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13 rename to tests/fuzzed/id:000226,sig:06,src:000031,time:35613427,execs:159728,op:arith8,pos:420,val:+13.buzz diff --git a/tests/fuzzed/id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2 b/tests/fuzzed/id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2 rename to tests/fuzzed/id:000227,sig:11,src:000017,time:36221548,execs:162414,op:quick,pos:543,val:+2.buzz diff --git a/tests/fuzzed/id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2 b/tests/fuzzed/id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2 rename to tests/fuzzed/id:000228,sig:06,src:000017,time:36378948,execs:163029,op:quick,pos:1084,val:+2.buzz diff --git a/tests/fuzzed/id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955 b/tests/fuzzed/id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955.buzz similarity index 100% rename from tests/fuzzed/id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955 rename to tests/fuzzed/id:000229,sig:06,src:000017,time:36540958,execs:163656,op:flip16,pos:955.buzz diff --git a/tests/fuzzed/id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2 b/tests/fuzzed/id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2 rename to tests/fuzzed/id:000230,sig:06,src:001363,time:37170525,execs:166260,op:inf,rep:2.buzz diff --git a/tests/fuzzed/id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2 b/tests/fuzzed/id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2 rename to tests/fuzzed/id:000231,sig:06,src:000005,time:37963086,execs:169564,op:quick,pos:151,val:+2.buzz diff --git a/tests/fuzzed/id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2 b/tests/fuzzed/id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2 rename to tests/fuzzed/id:000232,sig:06,src:000005,time:37968237,execs:169589,op:quick,pos:176,val:+2.buzz diff --git a/tests/fuzzed/id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2 b/tests/fuzzed/id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2 rename to tests/fuzzed/id:000233,sig:06,src:000005,time:37981668,execs:169650,op:quick,pos:237,val:+2.buzz diff --git a/tests/fuzzed/id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2 b/tests/fuzzed/id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2 rename to tests/fuzzed/id:000234,sig:06,src:000005,time:37983850,execs:169661,op:quick,pos:248,val:+2.buzz diff --git a/tests/fuzzed/id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2 b/tests/fuzzed/id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2 rename to tests/fuzzed/id:000235,sig:06,src:000005,time:37985373,execs:169668,op:quick,pos:255,val:+2.buzz diff --git a/tests/fuzzed/id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4 b/tests/fuzzed/id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4 rename to tests/fuzzed/id:000236,sig:06,src:002128,time:39642666,execs:177607,op:quick,pos:410,val:+4.buzz diff --git a/tests/fuzzed/id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4 b/tests/fuzzed/id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4 rename to tests/fuzzed/id:000237,sig:06,src:000650,time:39870522,execs:179236,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000238,sig:06,src:001952,time:40616704,execs:182234,op:quick,pos:1361,val:+4 b/tests/fuzzed/id:000238,sig:06,src:001952,time:40616704,execs:182234,op:quick,pos:1361,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000238,sig:06,src:001952,time:40616704,execs:182234,op:quick,pos:1361,val:+4 rename to tests/fuzzed/id:000238,sig:06,src:001952,time:40616704,execs:182234,op:quick,pos:1361,val:+4.buzz diff --git a/tests/fuzzed/id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7 b/tests/fuzzed/id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7.buzz similarity index 100% rename from tests/fuzzed/id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7 rename to tests/fuzzed/id:000239,sig:06,src:002210,time:45661354,execs:195188,op:inf,rep:7.buzz diff --git a/tests/fuzzed/id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6 b/tests/fuzzed/id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6.buzz similarity index 100% rename from tests/fuzzed/id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6 rename to tests/fuzzed/id:000240,sig:06,src:000019,time:46132030,execs:198251,op:quick,pos:106,val:+6.buzz diff --git a/tests/fuzzed/id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5 b/tests/fuzzed/id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5 rename to tests/fuzzed/id:000241,sig:06,src:000000,time:49412938,execs:213759,op:arith8,pos:362,val:+5.buzz diff --git a/tests/fuzzed/id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26 b/tests/fuzzed/id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26.buzz similarity index 100% rename from tests/fuzzed/id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26 rename to tests/fuzzed/id:000242,sig:06,src:000000,time:49536879,execs:214311,op:arith8,pos:683,val:+26.buzz diff --git a/tests/fuzzed/id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26 b/tests/fuzzed/id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26.buzz similarity index 100% rename from tests/fuzzed/id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26 rename to tests/fuzzed/id:000243,sig:06,src:000000,time:49577095,execs:214478,op:arith8,pos:781,val:+26.buzz diff --git a/tests/fuzzed/id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2 b/tests/fuzzed/id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2 rename to tests/fuzzed/id:000244,sig:06,src:001723,time:51459348,execs:222520,op:quick,pos:198,val:+2.buzz diff --git a/tests/fuzzed/id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2 b/tests/fuzzed/id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2 rename to tests/fuzzed/id:000245,sig:06,src:001997,time:52688593,execs:227532,op:quick,pos:1189,val:+2.buzz diff --git a/tests/fuzzed/id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2 b/tests/fuzzed/id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2 rename to tests/fuzzed/id:000246,sig:06,src:001997,time:52692507,execs:227545,op:quick,pos:1202,val:+2.buzz diff --git a/tests/fuzzed/id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167 b/tests/fuzzed/id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167.buzz similarity index 100% rename from tests/fuzzed/id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167 rename to tests/fuzzed/id:000247,sig:06,src:001997,time:52882604,execs:228188,op:flip1,pos:1167.buzz diff --git a/tests/fuzzed/id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187 b/tests/fuzzed/id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187.buzz similarity index 100% rename from tests/fuzzed/id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187 rename to tests/fuzzed/id:000248,sig:06,src:001997,time:52922773,execs:228312,op:flip2,pos:1187.buzz diff --git a/tests/fuzzed/id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167 b/tests/fuzzed/id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167.buzz similarity index 100% rename from tests/fuzzed/id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167 rename to tests/fuzzed/id:000249,sig:06,src:001997,time:52953605,execs:228408,op:flip4,pos:1167.buzz diff --git a/tests/fuzzed/id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10 b/tests/fuzzed/id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10.buzz similarity index 100% rename from tests/fuzzed/id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10 rename to tests/fuzzed/id:000250,sig:06,src:001997,time:53147299,execs:229022,op:arith8,pos:1187,val:-10.buzz diff --git a/tests/fuzzed/id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6 b/tests/fuzzed/id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6.buzz similarity index 100% rename from tests/fuzzed/id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6 rename to tests/fuzzed/id:000251,sig:06,src:002280,time:53826593,execs:231465,op:quick,pos:1191,val:+6.buzz diff --git a/tests/fuzzed/id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6 b/tests/fuzzed/id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6.buzz similarity index 100% rename from tests/fuzzed/id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6 rename to tests/fuzzed/id:000252,sig:06,src:002280,time:53829997,execs:231476,op:quick,pos:1202,val:+6.buzz diff --git a/tests/fuzzed/id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1 b/tests/fuzzed/id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1 rename to tests/fuzzed/id:000253,sig:06,src:002290,time:54426132,execs:233561,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4 b/tests/fuzzed/id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4.buzz similarity index 100% rename from tests/fuzzed/id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4 rename to tests/fuzzed/id:000254,sig:06,src:000995,time:54810724,execs:235381,op:quick,pos:122,val:+4.buzz diff --git a/tests/fuzzed/id:000255,sig:06,src:002305,time:54885789,execs:235917,op:flip32,pos:3 b/tests/fuzzed/id:000255,sig:06,src:002305,time:54885789,execs:235917,op:flip32,pos:3.buzz similarity index 100% rename from tests/fuzzed/id:000255,sig:06,src:002305,time:54885789,execs:235917,op:flip32,pos:3 rename to tests/fuzzed/id:000255,sig:06,src:002305,time:54885789,execs:235917,op:flip32,pos:3.buzz diff --git a/tests/fuzzed/id:000256,sig:06,src:002305,time:54897658,execs:236191,op:havoc,rep:15 b/tests/fuzzed/id:000256,sig:06,src:002305,time:54897658,execs:236191,op:havoc,rep:15.buzz similarity index 100% rename from tests/fuzzed/id:000256,sig:06,src:002305,time:54897658,execs:236191,op:havoc,rep:15 rename to tests/fuzzed/id:000256,sig:06,src:002305,time:54897658,execs:236191,op:havoc,rep:15.buzz diff --git a/tests/fuzzed/id:000257,sig:06,src:002305,time:54915177,execs:236611,op:havoc,rep:14 b/tests/fuzzed/id:000257,sig:06,src:002305,time:54915177,execs:236611,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000257,sig:06,src:002305,time:54915177,execs:236611,op:havoc,rep:14 rename to tests/fuzzed/id:000257,sig:06,src:002305,time:54915177,execs:236611,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000258,sig:06,src:002305,time:54918057,execs:236681,op:havoc,rep:16 b/tests/fuzzed/id:000258,sig:06,src:002305,time:54918057,execs:236681,op:havoc,rep:16.buzz similarity index 100% rename from tests/fuzzed/id:000258,sig:06,src:002305,time:54918057,execs:236681,op:havoc,rep:16 rename to tests/fuzzed/id:000258,sig:06,src:002305,time:54918057,execs:236681,op:havoc,rep:16.buzz diff --git a/tests/fuzzed/id:000259,sig:06,src:002305,time:54926618,execs:236882,op:havoc,rep:14 b/tests/fuzzed/id:000259,sig:06,src:002305,time:54926618,execs:236882,op:havoc,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000259,sig:06,src:002305,time:54926618,execs:236882,op:havoc,rep:14 rename to tests/fuzzed/id:000259,sig:06,src:002305,time:54926618,execs:236882,op:havoc,rep:14.buzz diff --git a/tests/fuzzed/id:000260,sig:06,src:002305,time:54942338,execs:237257,op:havoc,rep:15 b/tests/fuzzed/id:000260,sig:06,src:002305,time:54942338,execs:237257,op:havoc,rep:15.buzz similarity index 100% rename from tests/fuzzed/id:000260,sig:06,src:002305,time:54942338,execs:237257,op:havoc,rep:15 rename to tests/fuzzed/id:000260,sig:06,src:002305,time:54942338,execs:237257,op:havoc,rep:15.buzz diff --git a/tests/fuzzed/id:000261,sig:06,src:002305,time:54965944,execs:237841,op:havoc,rep:15 b/tests/fuzzed/id:000261,sig:06,src:002305,time:54965944,execs:237841,op:havoc,rep:15.buzz similarity index 100% rename from tests/fuzzed/id:000261,sig:06,src:002305,time:54965944,execs:237841,op:havoc,rep:15 rename to tests/fuzzed/id:000261,sig:06,src:002305,time:54965944,execs:237841,op:havoc,rep:15.buzz diff --git a/tests/fuzzed/id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5 b/tests/fuzzed/id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5 rename to tests/fuzzed/id:000262,sig:06,src:002305,time:55034933,execs:239470,op:havoc,rep:5.buzz diff --git a/tests/fuzzed/id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10 b/tests/fuzzed/id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10.buzz similarity index 100% rename from tests/fuzzed/id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10 rename to tests/fuzzed/id:000263,sig:06,src:002305,time:55084384,execs:240661,op:havoc,rep:10.buzz diff --git a/tests/fuzzed/id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12 b/tests/fuzzed/id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12.buzz similarity index 100% rename from tests/fuzzed/id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12 rename to tests/fuzzed/id:000264,sig:06,src:002305,time:55102023,execs:241087,op:havoc,rep:12.buzz diff --git a/tests/fuzzed/id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26 b/tests/fuzzed/id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26.buzz similarity index 100% rename from tests/fuzzed/id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26 rename to tests/fuzzed/id:000265,sig:06,src:002251,time:56396097,execs:244791,op:arith8,pos:468,val:+26.buzz diff --git a/tests/fuzzed/id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2 b/tests/fuzzed/id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2.buzz similarity index 100% rename from tests/fuzzed/id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2 rename to tests/fuzzed/id:000266,sig:11,src:000737,time:57232300,execs:248805,op:quick,pos:596,val:+2.buzz diff --git a/tests/fuzzed/id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5 b/tests/fuzzed/id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5 rename to tests/fuzzed/id:000267,sig:06,src:000032,time:57646435,execs:250539,op:inf,rep:5.buzz diff --git a/tests/fuzzed/id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5 b/tests/fuzzed/id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5 rename to tests/fuzzed/id:000268,sig:06,src:000032,time:57900615,execs:251516,op:quick,pos:762,val:+5.buzz diff --git a/tests/fuzzed/id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5 b/tests/fuzzed/id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5 rename to tests/fuzzed/id:000269,sig:06,src:000032,time:58080994,execs:252235,op:quick,pos:1347,val:+5.buzz diff --git a/tests/fuzzed/id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3 b/tests/fuzzed/id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3 rename to tests/fuzzed/id:000270,sig:11,src:000032,time:58572284,execs:254163,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2 b/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2 rename to tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2 b/tests/fuzzed/id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2 rename to tests/fuzzed/id:000272,sig:06,src:000032,time:58663945,execs:254571,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4 b/tests/fuzzed/id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4 rename to tests/fuzzed/id:000273,sig:06,src:000032,time:58681715,execs:254650,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000274,sig:06,src:000032,time:58977780,execs:255922,op:havoc,rep:4 b/tests/fuzzed/id:000274,sig:06,src:000032,time:58977780,execs:255922,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000274,sig:06,src:000032,time:58977780,execs:255922,op:havoc,rep:4 rename to tests/fuzzed/id:000274,sig:06,src:000032,time:58977780,execs:255922,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4 b/tests/fuzzed/id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4 rename to tests/fuzzed/id:000275,sig:06,src:000032,time:59042763,execs:256202,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2 b/tests/fuzzed/id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2 rename to tests/fuzzed/id:000276,sig:06,src:000032,time:59124537,execs:256553,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1 b/tests/fuzzed/id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1 rename to tests/fuzzed/id:000277,sig:06,src:000032,time:59235059,execs:257029,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1 b/tests/fuzzed/id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1 rename to tests/fuzzed/id:000278,sig:06,src:000032,time:59358971,execs:257542,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2 b/tests/fuzzed/id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2 rename to tests/fuzzed/id:000279,sig:11,src:000032,time:59479191,execs:258032,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1 b/tests/fuzzed/id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1 rename to tests/fuzzed/id:000280,sig:06,src:002390,time:60321735,execs:261733,op:inf,rep:1.buzz diff --git a/tests/fuzzed/id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7 b/tests/fuzzed/id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7.buzz similarity index 100% rename from tests/fuzzed/id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7 rename to tests/fuzzed/id:000281,sig:06,src:002390,time:61063439,execs:264478,op:havoc,rep:7.buzz diff --git a/tests/fuzzed/id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7 b/tests/fuzzed/id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7.buzz similarity index 100% rename from tests/fuzzed/id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7 rename to tests/fuzzed/id:000282,sig:06,src:002424,time:61734115,execs:267045,op:quick,pos:1356,val:+7.buzz diff --git a/tests/fuzzed/id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11 b/tests/fuzzed/id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11.buzz similarity index 100% rename from tests/fuzzed/id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11 rename to tests/fuzzed/id:000283,sig:11,src:000059,time:62479041,execs:270064,op:quick,pos:265,val:+11.buzz diff --git a/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11 b/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11.buzz similarity index 100% rename from tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11 rename to tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11.buzz diff --git a/tests/fuzzed/id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28 b/tests/fuzzed/id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28.buzz similarity index 100% rename from tests/fuzzed/id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28 rename to tests/fuzzed/id:000285,sig:06,src:000002,time:64028189,execs:277373,op:arith8,pos:1097,val:+28.buzz diff --git a/tests/fuzzed/id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2 b/tests/fuzzed/id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2 rename to tests/fuzzed/id:000286,sig:06,src:000002,time:64274306,execs:278459,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299 b/tests/fuzzed/id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299.buzz similarity index 100% rename from tests/fuzzed/id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299 rename to tests/fuzzed/id:000287,sig:06,src:000053,time:66983681,execs:290801,op:quick,pos:299.buzz diff --git a/tests/fuzzed/id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111 b/tests/fuzzed/id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111.buzz similarity index 100% rename from tests/fuzzed/id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111 rename to tests/fuzzed/id:000288,sig:06,src:002462,time:67514570,execs:293548,op:quick,pos:111.buzz diff --git a/tests/fuzzed/id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331 b/tests/fuzzed/id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331.buzz similarity index 100% rename from tests/fuzzed/id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331 rename to tests/fuzzed/id:000289,sig:06,src:000039,time:68762636,execs:300111,op:quick,pos:331.buzz diff --git a/tests/fuzzed/id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868 b/tests/fuzzed/id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868.buzz similarity index 100% rename from tests/fuzzed/id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868 rename to tests/fuzzed/id:000290,sig:06,src:000039,time:68893120,execs:300650,op:quick,pos:868.buzz diff --git a/tests/fuzzed/id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257 b/tests/fuzzed/id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257.buzz similarity index 100% rename from tests/fuzzed/id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257 rename to tests/fuzzed/id:000291,sig:06,src:000039,time:68994477,execs:301064,op:quick,pos:1257.buzz diff --git a/tests/fuzzed/id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62 b/tests/fuzzed/id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62.buzz similarity index 100% rename from tests/fuzzed/id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62 rename to tests/fuzzed/id:000292,sig:06,src:002499,time:71705596,execs:312341,op:quick,pos:62.buzz diff --git a/tests/fuzzed/id:000293,sig:06,src:001816,time:72343382,execs:315245,op:arith8,pos:458,val:+28 b/tests/fuzzed/id:000293,sig:06,src:001816,time:72343382,execs:315245,op:arith8,pos:458,val:+28.buzz similarity index 100% rename from tests/fuzzed/id:000293,sig:06,src:001816,time:72343382,execs:315245,op:arith8,pos:458,val:+28 rename to tests/fuzzed/id:000293,sig:06,src:001816,time:72343382,execs:315245,op:arith8,pos:458,val:+28.buzz diff --git a/tests/fuzzed/id:000294,sig:06,src:000057,time:72638050,execs:316690,op:quick,pos:248 b/tests/fuzzed/id:000294,sig:06,src:000057,time:72638050,execs:316690,op:quick,pos:248.buzz similarity index 100% rename from tests/fuzzed/id:000294,sig:06,src:000057,time:72638050,execs:316690,op:quick,pos:248 rename to tests/fuzzed/id:000294,sig:06,src:000057,time:72638050,execs:316690,op:quick,pos:248.buzz diff --git a/tests/fuzzed/id:000295,sig:06,src:000057,time:72724520,execs:317104,op:arith8,pos:137,val:+5 b/tests/fuzzed/id:000295,sig:06,src:000057,time:72724520,execs:317104,op:arith8,pos:137,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000295,sig:06,src:000057,time:72724520,execs:317104,op:arith8,pos:137,val:+5 rename to tests/fuzzed/id:000295,sig:06,src:000057,time:72724520,execs:317104,op:arith8,pos:137,val:+5.buzz diff --git a/tests/fuzzed/id:000296,sig:06,src:001381,time:73193810,execs:319768,op:inf,rep:4 b/tests/fuzzed/id:000296,sig:06,src:001381,time:73193810,execs:319768,op:inf,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000296,sig:06,src:001381,time:73193810,execs:319768,op:inf,rep:4 rename to tests/fuzzed/id:000296,sig:06,src:001381,time:73193810,execs:319768,op:inf,rep:4.buzz diff --git a/tests/fuzzed/id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683 b/tests/fuzzed/id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683.buzz similarity index 100% rename from tests/fuzzed/id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683 rename to tests/fuzzed/id:000297,sig:11,src:001419,time:74415488,execs:324164,op:quick,pos:1683.buzz diff --git a/tests/fuzzed/id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78 b/tests/fuzzed/id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78.buzz similarity index 100% rename from tests/fuzzed/id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78 rename to tests/fuzzed/id:000298,sig:06,src:000040,time:74464538,execs:324402,op:quick,pos:78.buzz diff --git a/tests/fuzzed/id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186 b/tests/fuzzed/id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186.buzz similarity index 100% rename from tests/fuzzed/id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186 rename to tests/fuzzed/id:000299,sig:06,src:002271,time:76032260,execs:330699,op:quick,pos:1186.buzz diff --git a/tests/fuzzed/id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189 b/tests/fuzzed/id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189.buzz similarity index 100% rename from tests/fuzzed/id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189 rename to tests/fuzzed/id:000300,sig:06,src:002271,time:76033152,execs:330702,op:quick,pos:1189.buzz diff --git a/tests/fuzzed/id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190 b/tests/fuzzed/id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190.buzz similarity index 100% rename from tests/fuzzed/id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190 rename to tests/fuzzed/id:000301,sig:06,src:002271,time:76033415,execs:330703,op:quick,pos:1190.buzz diff --git a/tests/fuzzed/id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204 b/tests/fuzzed/id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204.buzz similarity index 100% rename from tests/fuzzed/id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204 rename to tests/fuzzed/id:000302,sig:06,src:002271,time:76038104,execs:330717,op:quick,pos:1204.buzz diff --git a/tests/fuzzed/id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5 b/tests/fuzzed/id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5 rename to tests/fuzzed/id:000303,sig:06,src:002271,time:76341093,execs:331567,op:arith8,pos:827,val:+5.buzz diff --git a/tests/fuzzed/id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232 b/tests/fuzzed/id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232.buzz similarity index 100% rename from tests/fuzzed/id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232 rename to tests/fuzzed/id:000304,sig:06,src:001333,time:79400261,execs:342468,op:quick,pos:232.buzz diff --git a/tests/fuzzed/id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361 b/tests/fuzzed/id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361.buzz similarity index 100% rename from tests/fuzzed/id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361 rename to tests/fuzzed/id:000305,sig:06,src:001957,time:83462475,execs:359210,op:quick,pos:1361.buzz diff --git a/tests/fuzzed/id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60 b/tests/fuzzed/id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60.buzz similarity index 100% rename from tests/fuzzed/id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60 rename to tests/fuzzed/id:000306,sig:06,src:000058,time:84869130,execs:364710,op:quick,pos:60.buzz diff --git a/tests/fuzzed/id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231 b/tests/fuzzed/id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231.buzz similarity index 100% rename from tests/fuzzed/id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231 rename to tests/fuzzed/id:000307,sig:06,src:000058,time:84908720,execs:364893,op:quick,pos:231.buzz diff --git a/tests/fuzzed/id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552 b/tests/fuzzed/id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552.buzz similarity index 100% rename from tests/fuzzed/id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552 rename to tests/fuzzed/id:000308,sig:06,src:000058,time:84983967,execs:365215,op:quick,pos:552.buzz diff --git a/tests/fuzzed/id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2 b/tests/fuzzed/id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2 rename to tests/fuzzed/id:000309,sig:06,src:002554,time:86923124,execs:373881,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290 b/tests/fuzzed/id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290.buzz similarity index 100% rename from tests/fuzzed/id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290 rename to tests/fuzzed/id:000310,sig:06,src:001358,time:87910948,execs:378156,op:quick,pos:290.buzz diff --git a/tests/fuzzed/id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291 b/tests/fuzzed/id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291.buzz similarity index 100% rename from tests/fuzzed/id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291 rename to tests/fuzzed/id:000311,sig:06,src:002406,time:88382776,execs:380377,op:flip32,pos:291.buzz diff --git a/tests/fuzzed/id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27 b/tests/fuzzed/id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27.buzz similarity index 100% rename from tests/fuzzed/id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27 rename to tests/fuzzed/id:000312,sig:06,src:002406,time:88391762,execs:380418,op:arith8,pos:291,val:-27.buzz diff --git a/tests/fuzzed/id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270 b/tests/fuzzed/id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270.buzz similarity index 100% rename from tests/fuzzed/id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270 rename to tests/fuzzed/id:000313,sig:06,src:000016,time:89328446,execs:384726,op:quick,pos:270.buzz diff --git a/tests/fuzzed/id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260 b/tests/fuzzed/id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260 rename to tests/fuzzed/id:000314,sig:06,src:002297,time:90703853,execs:390606,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5 b/tests/fuzzed/id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5 rename to tests/fuzzed/id:000315,sig:06,src:002297,time:90997899,execs:391555,op:havoc,rep:5.buzz diff --git a/tests/fuzzed/id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187 b/tests/fuzzed/id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187.buzz similarity index 100% rename from tests/fuzzed/id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187 rename to tests/fuzzed/id:000316,sig:06,src:001946,time:92303472,execs:397259,op:quick,pos:1187.buzz diff --git a/tests/fuzzed/id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26 b/tests/fuzzed/id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26.buzz similarity index 100% rename from tests/fuzzed/id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26 rename to tests/fuzzed/id:000317,sig:06,src:002252,time:93260094,execs:401419,op:arith8,pos:464,val:+26.buzz diff --git a/tests/fuzzed/id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88 b/tests/fuzzed/id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88.buzz similarity index 100% rename from tests/fuzzed/id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88 rename to tests/fuzzed/id:000318,sig:06,src:002528,time:94833516,execs:411321,op:quick,pos:88.buzz diff --git a/tests/fuzzed/id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3 b/tests/fuzzed/id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3 rename to tests/fuzzed/id:000319,sig:06,src:002528,time:95632731,execs:413985,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361 b/tests/fuzzed/id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361.buzz similarity index 100% rename from tests/fuzzed/id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361 rename to tests/fuzzed/id:000320,sig:06,src:002283,time:97688567,execs:423495,op:quick,pos:1361.buzz diff --git a/tests/fuzzed/id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113 b/tests/fuzzed/id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113.buzz similarity index 100% rename from tests/fuzzed/id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113 rename to tests/fuzzed/id:000321,sig:06,src:000755,time:98745206,execs:427456,op:quick,pos:113.buzz diff --git a/tests/fuzzed/id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510 b/tests/fuzzed/id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510.buzz similarity index 100% rename from tests/fuzzed/id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510 rename to tests/fuzzed/id:000322,sig:06,src:000035,time:99732791,execs:431227,op:quick,pos:510.buzz diff --git a/tests/fuzzed/id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779 b/tests/fuzzed/id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779.buzz similarity index 100% rename from tests/fuzzed/id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779 rename to tests/fuzzed/id:000323,sig:06,src:000035,time:99796047,execs:431508,op:quick,pos:779.buzz diff --git a/tests/fuzzed/id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115 b/tests/fuzzed/id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115.buzz similarity index 100% rename from tests/fuzzed/id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115 rename to tests/fuzzed/id:000324,sig:06,src:001337,time:100748507,execs:435529,op:quick,pos:1115.buzz diff --git a/tests/fuzzed/id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309 b/tests/fuzzed/id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309.buzz similarity index 100% rename from tests/fuzzed/id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309 rename to tests/fuzzed/id:000325,sig:06,src:001337,time:100811010,execs:435723,op:quick,pos:1309.buzz diff --git a/tests/fuzzed/id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206 b/tests/fuzzed/id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206.buzz similarity index 100% rename from tests/fuzzed/id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206 rename to tests/fuzzed/id:000326,sig:06,src:000038,time:104654402,execs:451921,op:quick,pos:206.buzz diff --git a/tests/fuzzed/id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1 b/tests/fuzzed/id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1 rename to tests/fuzzed/id:000327,sig:06,src:000038,time:104943562,execs:452954,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260 b/tests/fuzzed/id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260 rename to tests/fuzzed/id:000328,sig:06,src:002592,time:105717054,execs:455456,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14 b/tests/fuzzed/id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14.buzz similarity index 100% rename from tests/fuzzed/id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14 rename to tests/fuzzed/id:000329,sig:06,src:002587,time:110943511,execs:477593,op:arith8,pos:1166,val:+14.buzz diff --git a/tests/fuzzed/id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362 b/tests/fuzzed/id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362.buzz similarity index 100% rename from tests/fuzzed/id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362 rename to tests/fuzzed/id:000330,sig:06,src:002665,time:111703982,execs:480343,op:quick,pos:1362.buzz diff --git a/tests/fuzzed/id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488 b/tests/fuzzed/id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488.buzz similarity index 100% rename from tests/fuzzed/id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488 rename to tests/fuzzed/id:000331,sig:06,src:002665,time:111742104,execs:480469,op:quick,pos:1488.buzz diff --git a/tests/fuzzed/id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956 b/tests/fuzzed/id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956.buzz similarity index 100% rename from tests/fuzzed/id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956 rename to tests/fuzzed/id:000332,sig:06,src:002286,time:112340414,execs:482618,op:quick,pos:956.buzz diff --git a/tests/fuzzed/id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188 b/tests/fuzzed/id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188.buzz similarity index 100% rename from tests/fuzzed/id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188 rename to tests/fuzzed/id:000333,sig:06,src:002286,time:112413712,execs:482862,op:quick,pos:1188.buzz diff --git a/tests/fuzzed/id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357 b/tests/fuzzed/id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357.buzz similarity index 100% rename from tests/fuzzed/id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357 rename to tests/fuzzed/id:000334,sig:06,src:002673,time:113043394,execs:485148,op:quick,pos:357.buzz diff --git a/tests/fuzzed/id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001 b/tests/fuzzed/id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001.buzz similarity index 100% rename from tests/fuzzed/id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001 rename to tests/fuzzed/id:000335,sig:06,src:002407,time:114693274,execs:491945,op:quick,pos:2001.buzz diff --git a/tests/fuzzed/id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242 b/tests/fuzzed/id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242.buzz similarity index 100% rename from tests/fuzzed/id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242 rename to tests/fuzzed/id:000336,sig:06,src:002407,time:114757430,execs:492186,op:quick,pos:2242.buzz diff --git a/tests/fuzzed/id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243 b/tests/fuzzed/id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243.buzz similarity index 100% rename from tests/fuzzed/id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243 rename to tests/fuzzed/id:000337,sig:06,src:002407,time:114778052,execs:492262,op:flip32,pos:2243.buzz diff --git a/tests/fuzzed/id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13 b/tests/fuzzed/id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13.buzz similarity index 100% rename from tests/fuzzed/id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13 rename to tests/fuzzed/id:000338,sig:06,src:002407,time:114828037,execs:492473,op:havoc,rep:13.buzz diff --git a/tests/fuzzed/id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10 b/tests/fuzzed/id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10.buzz similarity index 100% rename from tests/fuzzed/id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10 rename to tests/fuzzed/id:000339,sig:06,src:002407,time:114839245,execs:492527,op:havoc,rep:10.buzz diff --git a/tests/fuzzed/id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260 b/tests/fuzzed/id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260 rename to tests/fuzzed/id:000340,sig:06,src:002542,time:116648763,execs:499499,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274 b/tests/fuzzed/id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274.buzz similarity index 100% rename from tests/fuzzed/id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274 rename to tests/fuzzed/id:000341,sig:06,src:002715,time:119774513,execs:510315,op:quick,pos:1274.buzz diff --git a/tests/fuzzed/id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11 b/tests/fuzzed/id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11.buzz similarity index 100% rename from tests/fuzzed/id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11 rename to tests/fuzzed/id:000342,sig:06,src:000024,time:120510785,execs:513697,op:inf,rep:11.buzz diff --git a/tests/fuzzed/id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11 b/tests/fuzzed/id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11.buzz similarity index 100% rename from tests/fuzzed/id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11 rename to tests/fuzzed/id:000343,sig:06,src:000024,time:120513847,execs:513711,op:inf,rep:11.buzz diff --git a/tests/fuzzed/id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187 b/tests/fuzzed/id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187.buzz similarity index 100% rename from tests/fuzzed/id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187 rename to tests/fuzzed/id:000344,sig:06,src:000963,time:121066290,execs:516173,op:quick,pos:187.buzz diff --git a/tests/fuzzed/id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361 b/tests/fuzzed/id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361.buzz similarity index 100% rename from tests/fuzzed/id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361 rename to tests/fuzzed/id:000345,sig:06,src:002185,time:122760443,execs:522183,op:quick,pos:1361.buzz diff --git a/tests/fuzzed/id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415 b/tests/fuzzed/id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415.buzz similarity index 100% rename from tests/fuzzed/id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415 rename to tests/fuzzed/id:000346,sig:06,src:002415,time:123625396,execs:525714,op:quick,pos:1415.buzz diff --git a/tests/fuzzed/id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5 b/tests/fuzzed/id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5 rename to tests/fuzzed/id:000347,sig:06,src:002415,time:123719386,execs:526124,op:arith8,pos:414,val:+5.buzz diff --git a/tests/fuzzed/id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92 b/tests/fuzzed/id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92.buzz similarity index 100% rename from tests/fuzzed/id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92 rename to tests/fuzzed/id:000348,sig:06,src:000047,time:124013546,execs:527527,op:quick,pos:92.buzz diff --git a/tests/fuzzed/id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595 b/tests/fuzzed/id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595.buzz similarity index 100% rename from tests/fuzzed/id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595 rename to tests/fuzzed/id:000349,sig:06,src:000047,time:124136371,execs:528043,op:quick,pos:595.buzz diff --git a/tests/fuzzed/id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635 b/tests/fuzzed/id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635.buzz similarity index 100% rename from tests/fuzzed/id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635 rename to tests/fuzzed/id:000350,sig:06,src:000047,time:124145431,execs:528083,op:quick,pos:635.buzz diff --git a/tests/fuzzed/id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695 b/tests/fuzzed/id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695.buzz similarity index 100% rename from tests/fuzzed/id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695 rename to tests/fuzzed/id:000351,sig:06,src:000047,time:124161290,execs:528144,op:quick,pos:695.buzz diff --git a/tests/fuzzed/id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821 b/tests/fuzzed/id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821.buzz similarity index 100% rename from tests/fuzzed/id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821 rename to tests/fuzzed/id:000352,sig:11,src:000047,time:124192242,execs:528270,op:quick,pos:821.buzz diff --git a/tests/fuzzed/id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002 b/tests/fuzzed/id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002.buzz similarity index 100% rename from tests/fuzzed/id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002 rename to tests/fuzzed/id:000353,sig:11,src:000047,time:124237297,execs:528463,op:quick,pos:1002.buzz diff --git a/tests/fuzzed/id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169 b/tests/fuzzed/id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169.buzz similarity index 100% rename from tests/fuzzed/id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169 rename to tests/fuzzed/id:000354,sig:11,src:000047,time:124279900,execs:528642,op:quick,pos:1169.buzz diff --git a/tests/fuzzed/id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395 b/tests/fuzzed/id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395.buzz similarity index 100% rename from tests/fuzzed/id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395 rename to tests/fuzzed/id:000355,sig:06,src:002743,time:124784112,execs:530854,op:quick,pos:395.buzz diff --git a/tests/fuzzed/id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53 b/tests/fuzzed/id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53.buzz similarity index 100% rename from tests/fuzzed/id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53 rename to tests/fuzzed/id:000356,sig:06,src:000036,time:126023882,execs:536351,op:quick,pos:53.buzz diff --git a/tests/fuzzed/id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221 b/tests/fuzzed/id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221.buzz similarity index 100% rename from tests/fuzzed/id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221 rename to tests/fuzzed/id:000357,sig:06,src:000036,time:126078535,execs:536579,op:quick,pos:221.buzz diff --git a/tests/fuzzed/id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435 b/tests/fuzzed/id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435.buzz similarity index 100% rename from tests/fuzzed/id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435 rename to tests/fuzzed/id:000358,sig:06,src:000036,time:126145735,execs:536866,op:quick,pos:435.buzz diff --git a/tests/fuzzed/id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731 b/tests/fuzzed/id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731.buzz similarity index 100% rename from tests/fuzzed/id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731 rename to tests/fuzzed/id:000359,sig:06,src:000036,time:126220134,execs:537174,op:quick,pos:731.buzz diff --git a/tests/fuzzed/id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013 b/tests/fuzzed/id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013.buzz similarity index 100% rename from tests/fuzzed/id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013 rename to tests/fuzzed/id:000360,sig:06,src:000036,time:126297966,execs:537481,op:quick,pos:1013.buzz diff --git a/tests/fuzzed/id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324 b/tests/fuzzed/id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324.buzz similarity index 100% rename from tests/fuzzed/id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324 rename to tests/fuzzed/id:000361,sig:06,src:000036,time:126378354,execs:537804,op:quick,pos:1324.buzz diff --git a/tests/fuzzed/id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633 b/tests/fuzzed/id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633.buzz similarity index 100% rename from tests/fuzzed/id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633 rename to tests/fuzzed/id:000362,sig:06,src:000036,time:126459384,execs:538148,op:flip2,pos:633.buzz diff --git a/tests/fuzzed/id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395 b/tests/fuzzed/id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395.buzz similarity index 100% rename from tests/fuzzed/id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395 rename to tests/fuzzed/id:000363,sig:06,src:001308,time:129546242,execs:551523,op:quick,pos:395.buzz diff --git a/tests/fuzzed/id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4 b/tests/fuzzed/id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4.buzz similarity index 100% rename from tests/fuzzed/id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4 rename to tests/fuzzed/id:000364,sig:06,src:002724,time:130658572,execs:556311,op:havoc,rep:4.buzz diff --git a/tests/fuzzed/id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345 b/tests/fuzzed/id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345.buzz similarity index 100% rename from tests/fuzzed/id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345 rename to tests/fuzzed/id:000365,sig:06,src:002096,time:131750132,execs:560931,op:quick,pos:1345.buzz diff --git a/tests/fuzzed/id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207 b/tests/fuzzed/id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207.buzz similarity index 100% rename from tests/fuzzed/id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207 rename to tests/fuzzed/id:000366,sig:06,src:000011,time:132660299,execs:564792,op:quick,pos:207.buzz diff --git a/tests/fuzzed/id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260 b/tests/fuzzed/id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260 rename to tests/fuzzed/id:000367,sig:06,src:002651,time:134817591,execs:570429,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260 b/tests/fuzzed/id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260 rename to tests/fuzzed/id:000368,sig:06,src:002591,time:136486905,execs:576825,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856 b/tests/fuzzed/id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856.buzz similarity index 100% rename from tests/fuzzed/id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856 rename to tests/fuzzed/id:000369,sig:06,src:002408,time:138068601,execs:583673,op:quick,pos:1856.buzz diff --git a/tests/fuzzed/id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018 b/tests/fuzzed/id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018.buzz similarity index 100% rename from tests/fuzzed/id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018 rename to tests/fuzzed/id:000370,sig:06,src:002408,time:138112253,execs:583835,op:quick,pos:2018.buzz diff --git a/tests/fuzzed/id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2 b/tests/fuzzed/id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2.buzz similarity index 100% rename from tests/fuzzed/id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2 rename to tests/fuzzed/id:000371,sig:06,src:001837,time:138188207,execs:584123,op:quick,pos:2.buzz diff --git a/tests/fuzzed/id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189 b/tests/fuzzed/id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189.buzz similarity index 100% rename from tests/fuzzed/id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189 rename to tests/fuzzed/id:000372,sig:06,src:002709,time:138994940,execs:587182,op:quick,pos:1189.buzz diff --git a/tests/fuzzed/id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204 b/tests/fuzzed/id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204.buzz similarity index 100% rename from tests/fuzzed/id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204 rename to tests/fuzzed/id:000373,sig:06,src:002709,time:139000332,execs:587197,op:quick,pos:1204.buzz diff --git a/tests/fuzzed/id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856 b/tests/fuzzed/id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856.buzz similarity index 100% rename from tests/fuzzed/id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856 rename to tests/fuzzed/id:000374,sig:06,src:002775,time:140305450,execs:592573,op:quick,pos:856.buzz diff --git a/tests/fuzzed/id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226 b/tests/fuzzed/id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226.buzz similarity index 100% rename from tests/fuzzed/id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226 rename to tests/fuzzed/id:000375,sig:06,src:002775,time:140402542,execs:592943,op:quick,pos:1226.buzz diff --git a/tests/fuzzed/id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413 b/tests/fuzzed/id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413.buzz similarity index 100% rename from tests/fuzzed/id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413 rename to tests/fuzzed/id:000376,sig:06,src:002068,time:141285424,execs:596810,op:quick,pos:413.buzz diff --git a/tests/fuzzed/id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499 b/tests/fuzzed/id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499.buzz similarity index 100% rename from tests/fuzzed/id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499 rename to tests/fuzzed/id:000377,sig:11,src:002068,time:141307178,execs:596896,op:quick,pos:499.buzz diff --git a/tests/fuzzed/id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3 b/tests/fuzzed/id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3 rename to tests/fuzzed/id:000378,sig:06,src:002116,time:142070148,execs:600480,op:inf,rep:3.buzz diff --git a/tests/fuzzed/id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241 b/tests/fuzzed/id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241.buzz similarity index 100% rename from tests/fuzzed/id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241 rename to tests/fuzzed/id:000379,sig:06,src:002116,time:142136589,execs:600758,op:quick,pos:241.buzz diff --git a/tests/fuzzed/id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045 b/tests/fuzzed/id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045.buzz similarity index 100% rename from tests/fuzzed/id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045 rename to tests/fuzzed/id:000380,sig:06,src:002116,time:142357467,execs:601586,op:quick,pos:1045.buzz diff --git a/tests/fuzzed/id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58 b/tests/fuzzed/id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58.buzz similarity index 100% rename from tests/fuzzed/id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58 rename to tests/fuzzed/id:000381,sig:06,src:001669,time:142624841,execs:602729,op:quick,pos:58.buzz diff --git a/tests/fuzzed/id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542 b/tests/fuzzed/id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542.buzz similarity index 100% rename from tests/fuzzed/id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542 rename to tests/fuzzed/id:000382,sig:11,src:002198,time:143526968,execs:604368,op:quick,pos:542.buzz diff --git a/tests/fuzzed/id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2 b/tests/fuzzed/id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2 rename to tests/fuzzed/id:000383,sig:11,src:001621,time:144228542,execs:606645,op:inf,rep:2.buzz diff --git a/tests/fuzzed/id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707 b/tests/fuzzed/id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707.buzz similarity index 100% rename from tests/fuzzed/id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707 rename to tests/fuzzed/id:000384,sig:06,src:001621,time:144703637,execs:608378,op:quick,pos:1707.buzz diff --git a/tests/fuzzed/id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378 b/tests/fuzzed/id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378.buzz similarity index 100% rename from tests/fuzzed/id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378 rename to tests/fuzzed/id:000385,sig:06,src:002501,time:146592309,execs:616204,op:quick,pos:1378.buzz diff --git a/tests/fuzzed/id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361 b/tests/fuzzed/id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361.buzz similarity index 100% rename from tests/fuzzed/id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361 rename to tests/fuzzed/id:000386,sig:06,src:001974,time:150616543,execs:629065,op:quick,pos:1361.buzz diff --git a/tests/fuzzed/id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487 b/tests/fuzzed/id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487.buzz similarity index 100% rename from tests/fuzzed/id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487 rename to tests/fuzzed/id:000387,sig:06,src:000030,time:151244497,execs:631388,op:quick,pos:487.buzz diff --git a/tests/fuzzed/id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107 b/tests/fuzzed/id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107.buzz similarity index 100% rename from tests/fuzzed/id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107 rename to tests/fuzzed/id:000388,sig:06,src:000030,time:151507726,execs:632383,op:flip1,pos:107.buzz diff --git a/tests/fuzzed/id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1 b/tests/fuzzed/id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1 rename to tests/fuzzed/id:000389,sig:06,src:002882,time:152669967,execs:637308,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292 b/tests/fuzzed/id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292.buzz similarity index 100% rename from tests/fuzzed/id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292 rename to tests/fuzzed/id:000390,sig:06,src:002151,time:153376684,execs:640072,op:quick,pos:292.buzz diff --git a/tests/fuzzed/id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116 b/tests/fuzzed/id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116.buzz similarity index 100% rename from tests/fuzzed/id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116 rename to tests/fuzzed/id:000391,sig:06,src:001475,time:155189306,execs:648173,op:quick,pos:1116.buzz diff --git a/tests/fuzzed/id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173 b/tests/fuzzed/id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173.buzz similarity index 100% rename from tests/fuzzed/id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173 rename to tests/fuzzed/id:000392,sig:06,src:001475,time:155207778,execs:648242,op:quick,pos:1173.buzz diff --git a/tests/fuzzed/id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347 b/tests/fuzzed/id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347.buzz similarity index 100% rename from tests/fuzzed/id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347 rename to tests/fuzzed/id:000393,sig:06,src:001475,time:155257724,execs:648416,op:quick,pos:1347.buzz diff --git a/tests/fuzzed/id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260 b/tests/fuzzed/id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260 rename to tests/fuzzed/id:000394,sig:06,src:002597,time:157391485,execs:657110,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14 b/tests/fuzzed/id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14.buzz similarity index 100% rename from tests/fuzzed/id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14 rename to tests/fuzzed/id:000395,sig:06,src:002422,time:158098880,execs:659084,op:inf,rep:14.buzz diff --git a/tests/fuzzed/id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330 b/tests/fuzzed/id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330.buzz similarity index 100% rename from tests/fuzzed/id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330 rename to tests/fuzzed/id:000396,sig:06,src:002649,time:159900099,execs:665196,op:quick,pos:1330.buzz diff --git a/tests/fuzzed/id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266 b/tests/fuzzed/id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266.buzz similarity index 100% rename from tests/fuzzed/id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266 rename to tests/fuzzed/id:000397,sig:06,src:002710,time:161148628,execs:669334,op:quick,pos:1266.buzz diff --git a/tests/fuzzed/id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361 b/tests/fuzzed/id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361.buzz similarity index 100% rename from tests/fuzzed/id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361 rename to tests/fuzzed/id:000398,sig:06,src:002650,time:162701538,execs:674554,op:quick,pos:1361.buzz diff --git a/tests/fuzzed/id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2 b/tests/fuzzed/id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2 rename to tests/fuzzed/id:000399,sig:06,src:002884,time:163620812,execs:677989,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141 b/tests/fuzzed/id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141.buzz similarity index 100% rename from tests/fuzzed/id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141 rename to tests/fuzzed/id:000400,sig:06,src:002879,time:164057626,execs:679854,op:quick,pos:1141.buzz diff --git a/tests/fuzzed/id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3 b/tests/fuzzed/id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3.buzz similarity index 100% rename from tests/fuzzed/id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3 rename to tests/fuzzed/id:000401,sig:06,src:002879,time:164131427,execs:680152,op:arith8,pos:490,val:-3.buzz diff --git a/tests/fuzzed/id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6 b/tests/fuzzed/id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6.buzz similarity index 100% rename from tests/fuzzed/id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6 rename to tests/fuzzed/id:000402,sig:06,src:002879,time:164132603,execs:680156,op:arith8,pos:490,val:-6.buzz diff --git a/tests/fuzzed/id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206 b/tests/fuzzed/id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206.buzz similarity index 100% rename from tests/fuzzed/id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206 rename to tests/fuzzed/id:000403,sig:06,src:002295,time:169803629,execs:701244,op:quick,pos:1206.buzz diff --git a/tests/fuzzed/id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260 b/tests/fuzzed/id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260 rename to tests/fuzzed/id:000404,sig:06,src:001988,time:170873964,execs:705329,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292 b/tests/fuzzed/id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292.buzz similarity index 100% rename from tests/fuzzed/id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292 rename to tests/fuzzed/id:000405,sig:06,src:002705,time:174459313,execs:716841,op:quick,pos:1292.buzz diff --git a/tests/fuzzed/id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393 b/tests/fuzzed/id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393.buzz similarity index 100% rename from tests/fuzzed/id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393 rename to tests/fuzzed/id:000406,sig:06,src:002937,time:177187920,execs:729142,op:quick,pos:1393.buzz diff --git a/tests/fuzzed/id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260 b/tests/fuzzed/id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260 rename to tests/fuzzed/id:000407,sig:06,src:002641,time:178244890,execs:732799,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168 b/tests/fuzzed/id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168.buzz similarity index 100% rename from tests/fuzzed/id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168 rename to tests/fuzzed/id:000408,sig:06,src:000045,time:180296864,execs:738689,op:quick,pos:168.buzz diff --git a/tests/fuzzed/id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327 b/tests/fuzzed/id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327.buzz similarity index 100% rename from tests/fuzzed/id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327 rename to tests/fuzzed/id:000409,sig:06,src:000045,time:180342705,execs:738873,op:quick,pos:327.buzz diff --git a/tests/fuzzed/id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077 b/tests/fuzzed/id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077.buzz similarity index 100% rename from tests/fuzzed/id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077 rename to tests/fuzzed/id:000410,sig:11,src:000045,time:180550642,execs:739707,op:quick,pos:1077.buzz diff --git a/tests/fuzzed/id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076 b/tests/fuzzed/id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076.buzz similarity index 100% rename from tests/fuzzed/id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076 rename to tests/fuzzed/id:000411,sig:06,src:000045,time:180628496,execs:740022,op:flip1,pos:1076.buzz diff --git a/tests/fuzzed/id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445 b/tests/fuzzed/id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445.buzz similarity index 100% rename from tests/fuzzed/id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445 rename to tests/fuzzed/id:000412,sig:06,src:002993,time:181476520,execs:743732,op:quick,pos:445.buzz diff --git a/tests/fuzzed/id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078 b/tests/fuzzed/id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078.buzz similarity index 100% rename from tests/fuzzed/id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078 rename to tests/fuzzed/id:000413,sig:06,src:002993,time:181637390,execs:744389,op:quick,pos:1078.buzz diff --git a/tests/fuzzed/id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188 b/tests/fuzzed/id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188.buzz similarity index 100% rename from tests/fuzzed/id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188 rename to tests/fuzzed/id:000414,sig:06,src:002585,time:182796544,execs:748803,op:quick,pos:1188.buzz diff --git a/tests/fuzzed/id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474 b/tests/fuzzed/id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474.buzz similarity index 100% rename from tests/fuzzed/id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474 rename to tests/fuzzed/id:000415,sig:06,src:001465,time:183943666,execs:753180,op:quick,pos:1474.buzz diff --git a/tests/fuzzed/id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874 b/tests/fuzzed/id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874.buzz similarity index 100% rename from tests/fuzzed/id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874 rename to tests/fuzzed/id:000416,sig:06,src:002410,time:185380055,execs:759046,op:quick,pos:874.buzz diff --git a/tests/fuzzed/id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6 b/tests/fuzzed/id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6.buzz similarity index 100% rename from tests/fuzzed/id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6 rename to tests/fuzzed/id:000417,sig:06,src:002325,time:185947638,execs:762936,op:havoc,rep:6.buzz diff --git a/tests/fuzzed/id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6 b/tests/fuzzed/id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6.buzz similarity index 100% rename from tests/fuzzed/id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6 rename to tests/fuzzed/id:000418,sig:06,src:002325,time:185958855,execs:763200,op:havoc,rep:6.buzz diff --git a/tests/fuzzed/id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5 b/tests/fuzzed/id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5.buzz similarity index 100% rename from tests/fuzzed/id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5 rename to tests/fuzzed/id:000419,sig:06,src:002325,time:185965568,execs:763363,op:havoc,rep:5.buzz diff --git a/tests/fuzzed/id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260 b/tests/fuzzed/id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260 rename to tests/fuzzed/id:000420,sig:06,src:002287,time:186911538,execs:770090,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26 b/tests/fuzzed/id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26.buzz similarity index 100% rename from tests/fuzzed/id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26 rename to tests/fuzzed/id:000421,sig:06,src:002248,time:187689491,execs:773131,op:arith8,pos:468,val:+26.buzz diff --git a/tests/fuzzed/id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3 b/tests/fuzzed/id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3.buzz similarity index 100% rename from tests/fuzzed/id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3 rename to tests/fuzzed/id:000422,sig:06,src:002735,time:190089968,execs:782430,op:havoc,rep:3.buzz diff --git a/tests/fuzzed/id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479 b/tests/fuzzed/id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479.buzz similarity index 100% rename from tests/fuzzed/id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479 rename to tests/fuzzed/id:000423,sig:06,src:002915,time:190794291,execs:785175,op:quick,pos:479.buzz diff --git a/tests/fuzzed/id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141 b/tests/fuzzed/id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141.buzz similarity index 100% rename from tests/fuzzed/id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141 rename to tests/fuzzed/id:000424,sig:06,src:002915,time:191082029,execs:785861,op:quick,pos:1141.buzz diff --git a/tests/fuzzed/id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2 b/tests/fuzzed/id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2.buzz similarity index 100% rename from tests/fuzzed/id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2 rename to tests/fuzzed/id:000425,sig:06,src:003011,time:191163494,execs:786074,op:havoc,rep:2.buzz diff --git a/tests/fuzzed/id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8 b/tests/fuzzed/id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8.buzz similarity index 100% rename from tests/fuzzed/id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8 rename to tests/fuzzed/id:000426,sig:06,src:001840,time:194971765,execs:798509,op:havoc,rep:8.buzz diff --git a/tests/fuzzed/id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7 b/tests/fuzzed/id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7.buzz similarity index 100% rename from tests/fuzzed/id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7 rename to tests/fuzzed/id:000427,sig:06,src:001735,time:195386382,execs:799905,op:inf,rep:7.buzz diff --git a/tests/fuzzed/id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5 b/tests/fuzzed/id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5 rename to tests/fuzzed/id:000428,sig:06,src:001735,time:196135868,execs:802454,op:arith8,pos:1724,val:+5.buzz diff --git a/tests/fuzzed/id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5 b/tests/fuzzed/id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5.buzz similarity index 100% rename from tests/fuzzed/id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5 rename to tests/fuzzed/id:000429,sig:06,src:001972,time:197334718,execs:807322,op:quick,pos:1260,val:+5.buzz diff --git a/tests/fuzzed/id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046 b/tests/fuzzed/id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046.buzz similarity index 100% rename from tests/fuzzed/id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046 rename to tests/fuzzed/id:000430,sig:06,src:001511,time:199030599,execs:815681,op:quick,pos:2046.buzz diff --git a/tests/fuzzed/id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361 b/tests/fuzzed/id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361.buzz similarity index 100% rename from tests/fuzzed/id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361 rename to tests/fuzzed/id:000431,sig:06,src:002598,time:200437006,execs:821734,op:quick,pos:1361.buzz diff --git a/tests/fuzzed/id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391 b/tests/fuzzed/id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391.buzz similarity index 100% rename from tests/fuzzed/id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391 rename to tests/fuzzed/id:000432,sig:06,src:002653,time:201357285,execs:824741,op:quick,pos:1391.buzz diff --git a/tests/fuzzed/id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25 b/tests/fuzzed/id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25.buzz similarity index 100% rename from tests/fuzzed/id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25 rename to tests/fuzzed/id:000433,sig:06,src:001350,time:201706085,execs:825883,op:quick,pos:25.buzz diff --git a/tests/fuzzed/id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1 b/tests/fuzzed/id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1.buzz similarity index 100% rename from tests/fuzzed/id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1 rename to tests/fuzzed/id:000434,sig:06,src:000723,time:202384530,execs:828228,op:arith8,pos:276,val:-1.buzz diff --git a/tests/fuzzed/id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455 b/tests/fuzzed/id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455.buzz similarity index 100% rename from tests/fuzzed/id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455 rename to tests/fuzzed/id:000435,sig:06,src:001769,time:204369834,execs:835857,op:quick,pos:1455.buzz diff --git a/tests/fuzzed/id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24 b/tests/fuzzed/id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24.buzz similarity index 100% rename from tests/fuzzed/id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24 rename to tests/fuzzed/id:000436,sig:06,src:000962,time:204828758,execs:837480,op:quick,pos:24.buzz diff --git a/tests/fuzzed/id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289 b/tests/fuzzed/id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289.buzz similarity index 100% rename from tests/fuzzed/id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289 rename to tests/fuzzed/id:000437,sig:06,src:003062,time:208242945,execs:849859,op:quick,pos:1289.buzz diff --git a/tests/fuzzed/id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203 b/tests/fuzzed/id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203.buzz similarity index 100% rename from tests/fuzzed/id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203 rename to tests/fuzzed/id:000438,sig:06,src:002599,time:209225042,execs:854084,op:quick,pos:1203.buzz diff --git a/tests/fuzzed/id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260 b/tests/fuzzed/id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260 rename to tests/fuzzed/id:000439,sig:06,src:002667,time:210343357,execs:857721,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354 b/tests/fuzzed/id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354.buzz similarity index 100% rename from tests/fuzzed/id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354 rename to tests/fuzzed/id:000440,sig:06,src:000052,time:210997661,execs:860745,op:quick,pos:354.buzz diff --git a/tests/fuzzed/id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166 b/tests/fuzzed/id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166.buzz similarity index 100% rename from tests/fuzzed/id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166 rename to tests/fuzzed/id:000441,sig:06,src:001993,time:213386640,execs:870338,op:quick,pos:1166.buzz diff --git a/tests/fuzzed/id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260 b/tests/fuzzed/id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260 rename to tests/fuzzed/id:000442,sig:06,src:001993,time:213422391,execs:870432,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005 b/tests/fuzzed/id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005.buzz similarity index 100% rename from tests/fuzzed/id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005 rename to tests/fuzzed/id:000443,sig:06,src:000004,time:214461874,execs:873986,op:quick,pos:1005.buzz diff --git a/tests/fuzzed/id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379 b/tests/fuzzed/id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379.buzz similarity index 100% rename from tests/fuzzed/id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379 rename to tests/fuzzed/id:000444,sig:06,src:000004,time:214570605,execs:874386,op:quick,pos:1379.buzz diff --git a/tests/fuzzed/id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7 b/tests/fuzzed/id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7.buzz similarity index 100% rename from tests/fuzzed/id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7 rename to tests/fuzzed/id:000445,sig:06,src:003127,time:215881159,execs:879003,op:quick,pos:1804,val:+7.buzz diff --git a/tests/fuzzed/id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7 b/tests/fuzzed/id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7.buzz similarity index 100% rename from tests/fuzzed/id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7 rename to tests/fuzzed/id:000446,sig:11,src:003127,time:215934009,execs:879173,op:quick,pos:1974,val:+7.buzz diff --git a/tests/fuzzed/id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155 b/tests/fuzzed/id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155.buzz similarity index 100% rename from tests/fuzzed/id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155 rename to tests/fuzzed/id:000447,sig:06,src:003127,time:215979354,execs:879333,op:flip32,pos:155.buzz diff --git a/tests/fuzzed/id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260 b/tests/fuzzed/id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260 rename to tests/fuzzed/id:000448,sig:06,src:002583,time:219216696,execs:890847,op:quick,pos:1260.buzz diff --git a/tests/fuzzed/id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47 b/tests/fuzzed/id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47.buzz similarity index 100% rename from tests/fuzzed/id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47 rename to tests/fuzzed/id:000449,sig:06,src:000060,time:220362784,execs:895852,op:quick,pos:47.buzz diff --git a/tests/fuzzed/id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54 b/tests/fuzzed/id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54.buzz similarity index 100% rename from tests/fuzzed/id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54 rename to tests/fuzzed/id:000450,sig:06,src:000060,time:220369367,execs:895883,op:quick,pos:54.buzz diff --git a/tests/fuzzed/id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59 b/tests/fuzzed/id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59.buzz similarity index 100% rename from tests/fuzzed/id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59 rename to tests/fuzzed/id:000451,sig:06,src:000060,time:220370374,execs:895888,op:quick,pos:59.buzz diff --git a/tests/fuzzed/id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132 b/tests/fuzzed/id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132.buzz similarity index 100% rename from tests/fuzzed/id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132 rename to tests/fuzzed/id:000452,sig:06,src:000060,time:220494544,execs:896448,op:flip1,pos:132.buzz diff --git a/tests/fuzzed/id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347 b/tests/fuzzed/id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347.buzz similarity index 100% rename from tests/fuzzed/id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347 rename to tests/fuzzed/id:000453,sig:06,src:000060,time:220510164,execs:896521,op:flip2,pos:347.buzz diff --git a/tests/fuzzed/id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60 b/tests/fuzzed/id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60.buzz similarity index 100% rename from tests/fuzzed/id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60 rename to tests/fuzzed/id:000454,sig:06,src:003151,time:221247072,execs:900392,op:quick,pos:60.buzz diff --git a/tests/fuzzed/id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1 b/tests/fuzzed/id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1.buzz similarity index 100% rename from tests/fuzzed/id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1 rename to tests/fuzzed/id:000455,sig:06,src:003151,time:221475319,execs:901376,op:havoc,rep:1.buzz diff --git a/tests/fuzzed/id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260 b/tests/fuzzed/id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260.buzz similarity index 100% rename from tests/fuzzed/id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260 rename to tests/fuzzed/id:000456,sig:06,src:001977,time:223576476,execs:909947,op:quick,pos:1260.buzz From fe39649ef19f0ce6b08ce44fdfac4c694a8f742c Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 12 Nov 2025 13:35:57 +0100 Subject: [PATCH 11/17] fix(jit): JIT might not find break/continue label if outside of hostpot --- src/Codegen.zig | 1 - src/Jit.zig | 40 ++++------- ...:58585555,execs:254223,op:havoc,rep:2.buzz | 68 ------------------- ...execs:270152,op:quick,pos:341,val:+11.buzz | 53 --------------- 4 files changed, 14 insertions(+), 148 deletions(-) diff --git a/src/Codegen.zig b/src/Codegen.zig index 23c309d4..16308f4d 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -607,7 +607,6 @@ fn generateBinary(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o if (left_type.def_type == .Integer) { try self.OP_SUBTRACT_I(locations[node]); } else { - std.debug.assert(left_type.def_type == .Double); try self.OP_SUBTRACT_F(locations[node]); } }, diff --git a/src/Jit.zig b/src/Jit.zig index eaa3a2cd..5d3772a7 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -3230,9 +3230,14 @@ fn generateFor(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { return null; } -fn findBreakLabel(self: *Self, node: Ast.Node.Index) Break { - var i = self.state.?.breaks_label.items.len - 1; - while (i >= 0) : (i -= 1) { +fn findBreakLabel(self: *Self, node: Ast.Node.Index) Error!Break { + if (self.state.?.breaks_label.items.len == 0) { + // The label might be outside the hotspot being compiled + // FIXME: It would be better to find this out before compiling + return error.CantCompile; + } + + for (self.state.?.breaks_label.items.len - 1..0) |i| { const brk = self.state.?.breaks_label.items[i]; if (brk.node == node) { @@ -3240,15 +3245,16 @@ fn findBreakLabel(self: *Self, node: Ast.Node.Index) Break { } } - // Should not happen: searched when parsing - unreachable; + // The label might be outside the hotspot being compiled + // FIXME: It would be better to find this out before compiling + return error.CantCompile; } fn generateBreak(self: *Self, break_node: Ast.Node.Index) Error!?m.MIR_op_t { try self.closeScope(break_node); if (self.state.?.ast.nodes.items(.components)[break_node].Break.destination) |label_node| { - self.JMP(self.findBreakLabel(label_node).break_label); + self.JMP((try self.findBreakLabel(label_node)).break_label); } else { self.JMP(self.state.?.break_label.?); } @@ -3260,7 +3266,7 @@ fn generateContinue(self: *Self, continue_node: Ast.Node.Index) Error!?m.MIR_op_ try self.closeScope(continue_node); if (self.state.?.ast.nodes.items(.components)[continue_node].Continue.destination) |label_node| { - self.JMP(self.findBreakLabel(label_node).continue_label); + self.JMP((try self.findBreakLabel(label_node)).continue_label); } else { self.JMP(self.state.?.continue_label.?); } @@ -4970,25 +4976,7 @@ fn generateHotspotFunction(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t ), ); - _ = self.generateNode(node) catch |err| { - if (err == error.CantCompile) { - if (BuildOptions.jit_debug) { - io.print( - "Not compiling node {s}#{}, likely because it uses a fiber\n", - .{ - @tagName(self.state.?.ast.nodes.items(.tag)[self.state.?.ast_node]), - self.state.?.ast_node, - }, - ); - } - - m.MIR_finish_func(self.ctx); - - try self.blacklisted_nodes.put(self.vm.gc.allocator, self.state.?.ast_node, {}); - } - - return err; - }; + _ = try self.generateNode(node); // If we reach here, return 0 meaning there was no early return in the hotspot self.RET(m.MIR_new_int_op(self.ctx, 0)); diff --git a/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2.buzz b/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2.buzz index e9555ea7..c8bb726a 100644 --- a/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2.buzz +++ b/tests/fuzzed/id:000271,sig:06,src:000032,time:58585555,execs:254223,op:havoc,rep:2.buzz @@ -1,73 +1,5 @@ import "std"; -fun main() > void !> any { - // Async call, creates a new fiber, yield type must be nullable because resume will return null when nothing yielded - final counter = &count(10); - - // A fiber is over when a OP_RETURN as been executed - var sum = 0; - while (!counter.over()) { - // resume returns null if nothing was yielded and/or fiber is over - sum = sum + resume counter ?? 0; - } - - std\assert(counter.over(), message: "Fiber should be over now"); - - // resolve runs fiber until it's over and dismiss any yielded vaell along the way - std\assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); - std\assert(sum == 45, message: "Sum is good"); - - std\assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); - - std\assert(std\currentFiber().isMain(), message: "We recognize main fiber"); -} - -/// returns str, yields int -fun count(n: int) > str *> int? { - std\assert(std\currentFiber() is fib, message: "Can get current fiber"); - std\assert(!std\currentFiber().isMain(), message: "Can know if fiber is main one"); - - for (i: int = 0; i < n; i = i + 1) { - // error or yield is ignored if not called with a async call? - _ = yield i; - } - - return "Counting is done!"; -} - -fun fail() > bool !> str { - throw "This fiber failed"; - - return false; -} - -fun caughFiberFail() > bool !> str { - final fiber = &fail(); - - return resolve fiber; -} - -test "Throw inside a fiber" { - std\assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); -} - -fun closedUpvalue() > fun () > str { - final upvalue = "joe"; - - return fun () > str => "hello {upvalue}"; -} - -test "Opened upvalue in fiber" { - final upvalue = "world"; - - final fiberFn = fun () > str => "hello {upvalue}"; - std\assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); -} - -test "Closed upvalue in fiber" { - std\assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); -} - test "Wrapping call inside complex expressions" { final map = { "hlueo": fun () > str => "hello world", diff --git a/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11.buzz b/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11.buzz index ffed3ef3..f92caa75 100644 --- a/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11.buzz +++ b/tests/fuzzed/id:000284,sig:06,src:000059,time:62498218,execs:270152,op:quick,pos:341,val:+11.buzz @@ -1,23 +1,6 @@ -import "std"; - -test "labeled break" { - var i = 0; - while (i < 100) :here { - i = i + 1; - - if (i == 10) { - break here; - } - } - - std\assert(i == 10); -} - test "labeled break in nested loop" { var i = 0; foreach (_ in 0..100) :here { - _ = "hello"; - while (i < 100) { i|= i + 1; @@ -26,40 +9,4 @@ test "labeled break in nested loop" { } } } - - std\assert(i == 10); -} - -test "labeled break in deeply nested loop" { - var i = 0; - foreach (j in 0..100) :here { - _ = "hello"; - - while (j < 100) { - _ = "bye"; - - while (i < 100) { - i = i + 1; - - if (i == 10) { - break here; - } - } - } - } - - std\assert(i == 10); -} - -test "labeled continue" { - var i = 0; - foreach (j in 0..10) :here { - if (j == 3) { - continue here; - } - - i = i + j; - } - - std\assert(i == 42); } From c52bf2d3fc4b10f025338702855e92bcd84794e8 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 12 Nov 2025 14:47:46 +0100 Subject: [PATCH 12/17] fix(fiber): Prevent wrapping a nullable expression in async call --- src/TypeChecker.zig | 86 +++++++++++++++++++++------------- tests/behavior/038-fibers.buzz | 2 +- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/TypeChecker.zig b/src/TypeChecker.zig index afe40b68..4a9778aa 100644 --- a/src/TypeChecker.zig +++ b/src/TypeChecker.zig @@ -17,66 +17,66 @@ const NodeCheck = *const fn ( const checkers = [_]?NodeCheck{ null, // AnonymousObjectType, null, // As, - null, // AsyncCall, - checkBinary, // Binary, + checkAsyncCall, + checkBinary, null, // Block, null, // BlockExpression, null, // Boolean, null, // Break, - checkCall, // Call, + checkCall, null, // Continue, - checkDot, // Dot, - checkDoUntil, // DoUntil, - checkEnum, // Enum, + checkDot, + checkDoUntil, + checkEnum, null, // Export, null, // Expression, null, // FiberType, null, // Double, - checkFor, // For, - checkForceUnwrap, // ForceUnwrap, - checkForEach, // ForEach, - checkFunction, // Function, + checkFor, + checkForceUnwrap, + checkForEach, + checkFunction, null, // FunctionType, null, // FunDeclaration, - checkGenericResolve, // GenericResolve, + checkGenericResolve, null, // GenericResolveType, null, // GenericType, null, // Grouping, - checkIf, // If, + checkIf, null, // Import, null, // Integer, null, // Is, - checkList, // List, + checkList, null, // ListType, - checkMap, // Map, + checkMap, null, // MapType, null, // Namespace, - checkNamedVariable, // NamedVariable, + checkNamedVariable, null, // Null, - checkObjectDeclaration, // ObjectDeclaration, - checkObjectInit, // ObjectInit, + checkObjectDeclaration, + checkObjectInit, null, // Out, null, // Pattern, null, // ProtocolDeclaration, - checkRange, // Range, - checkResolve, // Resolve, - checkResume, // Resume, - checkReturn, // Return, + checkRange, + checkResolve, + checkResume, + checkReturn, null, // SimpleType, null, // String, null, // StringLiteral, - checkSubscript, // Subscript, + checkSubscript, null, // Throw, null, // Try, null, // TypeExpression, null, // TypeOfExpression, - checkUnary, // Unary, - checkUnwrap, // Unwrap, + checkUnary, + checkUnwrap, null, // UserType, - checkVarDeclaration, // VarDeclaration, + checkVarDeclaration, null, // Void, - checkWhile, // While, - checkYield, // Yield, + checkWhile, + checkYield, null, // Zdef, }; @@ -1972,13 +1972,33 @@ fn checkRange(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, return had_error; } -fn checkResolve(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { +fn checkAsyncCall(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { + const callee = ast.nodes.items(.components)[node].AsyncCall; + const callee_type_def = ast.nodes.items(.type_def)[callee] orelse gc.type_registry.any_type; + const locations = ast.nodes.items(.location); + const end_locations = ast.nodes.items(.end_location); + + if (callee_type_def.optional or ast.nodes.items(.patch_opt_jumps)[callee]) { + reporter.reportErrorAt( + .fiber, + ast.tokens.get(locations[callee]), + ast.tokens.get(end_locations[callee]), + "Not callable", + ); + + return false; + } + + return true; +} + +fn checkResolve(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { const fiber = ast.nodes.items(.components)[node].Resolve; - const fiber_type_def = ast.nodes.items(.type_def)[fiber].?; + const fiber_type_def = ast.nodes.items(.type_def)[fiber] orelse gc.type_registry.any_type; const locations = ast.nodes.items(.location); const end_locations = ast.nodes.items(.end_location); - if (fiber_type_def.def_type != .Fiber) { + if (fiber_type_def.def_type != .Fiber or fiber_type_def.optional or ast.nodes.items(.patch_opt_jumps)[fiber]) { reporter.reportErrorAt( .fiber, ast.tokens.get(locations[fiber]), @@ -1992,13 +2012,13 @@ fn checkResolve(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, return true; } -fn checkResume(ast: Ast.Slice, reporter: *Reporter, _: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { +fn checkResume(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, node: Ast.Node.Index) error{OutOfMemory}!bool { const fiber = ast.nodes.items(.components)[node].Resume; - const fiber_type_def = ast.nodes.items(.type_def)[fiber].?; + const fiber_type_def = ast.nodes.items(.type_def)[fiber] orelse gc.type_registry.any_type; const locations = ast.nodes.items(.location); const end_locations = ast.nodes.items(.end_location); - if (fiber_type_def.def_type != .Fiber) { + if (fiber_type_def.def_type != .Fiber or fiber_type_def.optional or ast.nodes.items(.patch_opt_jumps)[fiber]) { reporter.reportErrorAt( .fiber, ast.tokens.get(locations[fiber]), diff --git a/tests/behavior/038-fibers.buzz b/tests/behavior/038-fibers.buzz index 4799762b..62f44e30 100644 --- a/tests/behavior/038-fibers.buzz +++ b/tests/behavior/038-fibers.buzz @@ -73,5 +73,5 @@ test "Wrapping call inside complex expressions" { "hello": fun () > str => "hello world", }; - std\assert(resolve &map["hello"]?() == "hello world", message: "Could warp function call in a complex expression"); + std\assert(resolve &map["hello"]!() == "hello world", message: "Could warp function call in a complex expression"); } From 64cd78bd5d6f5fb04fba184e3ac0f9288f702cfd Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 12 Nov 2025 15:00:31 +0100 Subject: [PATCH 13/17] fix(build): Don't build fuzz step in the CI --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index c5340a0c..c5ca9088 100644 --- a/build.zig +++ b/build.zig @@ -179,7 +179,7 @@ pub fn build(b: *Build) !void { } // fuzz - const fuzz = if (!is_wasm) + const fuzz = if (!is_wasm and false) // Turn on manually as we don't want the CI to do this buildFuzz(b, target, build_mode, ext_deps) else null; From 41e8397c2977c7ad270263dc73e57541b0298adb Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 12 Nov 2025 23:11:44 +0100 Subject: [PATCH 14/17] chore(ci): Pin zig version --- .github/workflows/ci.yaml | 4 ++-- build.zig | 4 ++++ src/TypeChecker.zig | 3 --- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6e8418d1..38f4caec 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,7 +12,7 @@ jobs: fail-fast: false matrix: zig-version: - - "master" + - "0.16.0-dev.747+493ad58ff" operating-system: [ ubuntu-latest, macos-latest ] optimize: - "Debug" @@ -38,7 +38,7 @@ jobs: - name: Run tests ${{ matrix.optimize }} run: zig build -Doptimize=${{ matrix.optimize }} ${{ matrix.options }} test - name: Run behavior tests ${{ matrix.optimize }} - run: zig build -Doptimize=${{ matrix.optimize }} ${{ matrix.options }} test-behavior + run: zig build -Doptimize=${{ matrix.optimize }} ${{ matrix.options }} test-behavior -- --behavior --compile-error - name: Cleanup run: rm -rf zig-out zig-cache diff --git a/build.zig b/build.zig index c5ca9088..4b55de8a 100644 --- a/build.zig +++ b/build.zig @@ -118,6 +118,10 @@ pub fn build(b: *Build) !void { b.installArtifact(behavior_exe.?); const run_behavior = b.addRunArtifact(behavior_exe.?); run_behavior.step.dependOn(install_step); + run_behavior.step.dependOn(install_step); + if (b.args) |args| { + run_behavior.addArgs(args); + } b.step("test-behavior", "Test behavior").dependOn(&run_behavior.step); } diff --git a/src/TypeChecker.zig b/src/TypeChecker.zig index 4a9778aa..025b378f 100644 --- a/src/TypeChecker.zig +++ b/src/TypeChecker.zig @@ -192,8 +192,6 @@ fn checkBinary(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, "Unexpected binary operator.", ); - std.debug.print(">> {s}\n", .{@tagName(node_components.Binary.operator)}); - had_error = true; }, } @@ -307,7 +305,6 @@ fn checkBinary(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, ast.tokens.get(node_end_location), "Unexpected binary operator.", ); - std.debug.print(">> {s}\n", .{@tagName(node_components.Binary.operator)}); had_error = true; }, From 4f1339fc51c693d700bc56a20df3473be6b0e2c7 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 13 Nov 2025 07:19:17 +0100 Subject: [PATCH 15/17] fix(behavior): Removed resolved skipping --- .github/workflows/ci.yaml | 2 +- src/behavior.zig | 42 ------------ ...,execs:269873,op:quick,pos:93,val:+11.buzz | 65 ------------------- 3 files changed, 1 insertion(+), 108 deletions(-) delete mode 100644 tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11.buzz diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 38f4caec..eb56797e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,7 +38,7 @@ jobs: - name: Run tests ${{ matrix.optimize }} run: zig build -Doptimize=${{ matrix.optimize }} ${{ matrix.options }} test - name: Run behavior tests ${{ matrix.optimize }} - run: zig build -Doptimize=${{ matrix.optimize }} ${{ matrix.options }} test-behavior -- --behavior --compile-error + run: zig build -Doptimize=${{ matrix.optimize }} ${{ matrix.options }} test-behavior - name: Cleanup run: rm -rf zig-out zig-cache diff --git a/src/behavior.zig b/src/behavior.zig index d3efa348..a318b2fa 100644 --- a/src/behavior.zig +++ b/src/behavior.zig @@ -188,41 +188,7 @@ fn testCompileErrors(allocator: std.mem.Allocator, fail_fast: bool) !Result { fn testFuzzCrashes(allocator: std.mem.Allocator, fail_fast: bool) !Result { var result = Result{}; - // Get resolved tests - var resolved = std.StringArrayHashMapUnmanaged(void).empty; - - var resolved_file = try std.fs.cwd().createFile( - "dist/resolved.txt", - .{ - .truncate = false, - .read = true, - }, - ); - - const raw = try allocator.alloc(u8, (try resolved_file.stat()).size); - defer allocator.free(raw); - - _ = try resolved_file.readAll(raw); - - { - var it = std.mem.splitAny(u8, raw, "\n"); - while (it.next()) |r| { - try resolved.put(allocator, r, {}); - } - } - - resolved_file.close(); - // Re open in to write new resolved tests - resolved_file = try std.fs.cwd().openFile( - "dist/resolved.txt", - .{ .mode = .write_only }, - ); - defer resolved_file.close(); - try resolved_file.seekFromEnd(0); - - var resolved_writer = resolved_file.writer(&.{}); - const dir = "tests/fuzzed"; var test_dir = try std.fs.cwd().openDir( dir, @@ -234,11 +200,6 @@ fn testFuzzCrashes(allocator: std.mem.Allocator, fail_fast: bool) !Result { while (try it.next()) |file| : (result.total += 1) { if (file.kind == .file) { - // Was it resolved? - if (resolved.get(file.name) != null) { - continue; - } - var file_name = std.Io.Writer.Allocating.init(allocator); defer file_name.deinit(); try file_name.writer.print("{s}/{s}", .{ dir, file.name }); @@ -302,9 +263,6 @@ fn testFuzzCrashes(allocator: std.mem.Allocator, fail_fast: bool) !Result { if (fail_fast) { break; } - } else { - try resolved_writer.interface.print("{s}\n", .{file.name}); - try resolved_writer.interface.flush(); } } else { try result.hanged.append(allocator, try file_name.toOwnedSlice()); diff --git a/tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11.buzz b/tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11.buzz deleted file mode 100644 index d4be2903..00000000 --- a/tests/fuzzed/id:000117,src:000059,time:62436588,execs:269873,op:quick,pos:93,val:+11.buzz +++ /dev/null @@ -1,65 +0,0 @@ -import "std"; - -test "labeled break" { - var i = 0; - while (i < 100) :here { - i = 7 + 1; - - if (i == 10) { - break here; - } - } - - std\assert(i == 10); -} - -test "labeled break in nested loop" { - var i = 0; - foreach (_ in 0..100) :here { - _ = "hello"; - - while (i < 100) { - i = i + 1; - - if (i == 10) { - break here; - } - } - } - - std\assert(i == 10); -} - -test "labeled break in deeply nested loop" { - var i = 0; - foreach (j in 0..100) :here { - _ = "hello"; - - while (j < 100) { - _ = "bye"; - - while (i < 100) { - i = i + 1; - - if (i == 10) { - break here; - } - } - } - } - - std\assert(i == 10); -} - -test "labeled continue" { - var i = 0; - foreach (j in 0..10) :here { - if (j == 3) { - continue here; - } - - i = i + j; - } - - std\assert(i == 42); -} From 760f4a1beeb9b33dcf189d790e7fa93e1cfd158e Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 13 Nov 2025 11:04:35 +0100 Subject: [PATCH 16/17] fix: Bad type checking --- src/Ast.zig | 11 ++++++++++- src/Codegen.zig | 24 ++++++++++++------------ src/Jit.zig | 2 +- src/TypeChecker.zig | 7 ++++--- src/buzz_api.zig | 2 +- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/Ast.zig b/src/Ast.zig index 4d6c96ca..7a0dd4a6 100644 --- a/src/Ast.zig +++ b/src/Ast.zig @@ -702,7 +702,7 @@ pub const Slice = struct { } } - pub fn toValue( + pub fn typeCheckAndToValue( self: Self.Slice, node: Node.Index, reporter: *Reporter, @@ -718,6 +718,15 @@ pub const Slice = struct { return Value.Void; } + return self.toValue(node, reporter, gc); + } + + pub fn toValue( + self: Self.Slice, + node: Node.Index, + reporter: *Reporter, + gc: *GC, + ) Error!Value { const value = &self.nodes.items(.value)[node]; // const type_defs = self.nodes.items(.type_def); const components = self.nodes.items(.components); diff --git a/src/Codegen.zig b/src/Codegen.zig index 16308f4d..9a4fd122 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -441,7 +441,7 @@ fn nodeValue(self: *Self, node: Ast.Node.Index) Error!?Value { if (value.* == null) { if (self.ast.isConstant(node)) { - value.* = try self.ast.toValue( + value.* = try self.ast.typeCheckAndToValue( node, &self.reporter, self.gc, @@ -457,7 +457,7 @@ fn generateAs(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.O const node_location = locations[node]; const components = self.ast.nodes.items(.components)[node].As; - const constant = try self.ast.toValue( + const constant = try self.ast.typeCheckAndToValue( components.constant, &self.reporter, self.gc, @@ -1388,7 +1388,7 @@ fn generateEnum(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjF try self.OP_CONSTANT( locations[node], - try self.ast.toValue( + try self.ast.typeCheckAndToValue( node, &self.reporter, self.gc, @@ -1461,7 +1461,7 @@ fn generateExpression(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error fn generateFloat(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjFunction { try self.emitConstant( self.ast.nodes.items(.location)[node], - try self.ast.toValue( + try self.ast.typeCheckAndToValue( node, &self.reporter, self.gc, @@ -1481,7 +1481,7 @@ fn generateFor(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj. const node_components = self.ast.nodes.items(.components); const components = node_components[node].For; - if (try self.ast.isConstant(self.gc.allocator, components.condition) and !(try self.ast.toValue( + if (try self.ast.isConstant(self.gc.allocator, components.condition) and !(try self.ast.typeCheckAndToValue( components.condition, &self.reporter, self.gc, @@ -1587,7 +1587,7 @@ fn generateForEach(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?* // If iterable constant and empty, skip the node if (try self.ast.isConstant(self.gc.allocator, components.iterable)) { - const iterable_value = (try self.ast.toValue( + const iterable_value = (try self.ast.typeCheckAndToValue( components.iterable, &self.reporter, self.gc, @@ -1737,7 +1737,7 @@ fn generateFunction(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!? try node_type_def.resolved_type.?.Function.defaults.put( self.gc.allocator, try self.gc.copyString(self.ast.tokens.items(.lexeme)[argument.name]), - try self.ast.toValue( + try self.ast.typeCheckAndToValue( default, &self.reporter, self.gc, @@ -1995,7 +1995,7 @@ fn generateIf(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.O components.unwrapped_identifier == null and components.casted_type == null) { - const condition = try self.ast.toValue( + const condition = try self.ast.typeCheckAndToValue( components.condition, &self.reporter, self.gc, @@ -2074,7 +2074,7 @@ fn generateImport(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*o fn generateInteger(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjFunction { try self.emitConstant( self.ast.nodes.items(.location)[node], - try self.ast.toValue( + try self.ast.typeCheckAndToValue( node, &self.reporter, self.gc, @@ -2090,7 +2090,7 @@ fn generateInteger(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.O fn generateIs(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction { const components = self.ast.nodes.items(.components)[node].Is; const location = self.ast.nodes.items(.location)[node]; - const constant = try self.ast.toValue( + const constant = try self.ast.typeCheckAndToValue( components.constant, &self.reporter, self.gc, @@ -2411,7 +2411,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error fn generatePattern(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjFunction { try self.emitConstant( self.ast.nodes.items(.location)[node], - try self.ast.toValue( + try self.ast.typeCheckAndToValue( node, &self.reporter, self.gc, @@ -2955,7 +2955,7 @@ fn generateWhile(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*ob const location = locations[node]; // If condition constant and false, skip the node - if (try self.ast.isConstant(self.gc.allocator, components.condition) and !(try self.ast.toValue( + if (try self.ast.isConstant(self.gc.allocator, components.condition) and !(try self.ast.typeCheckAndToValue( components.condition, &self.reporter, self.gc, diff --git a/src/Jit.zig b/src/Jit.zig index 5d3772a7..48a22f15 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -2731,7 +2731,7 @@ fn buildBinary( }, else => unreachable, } - }, + }, .Star, .StarEqual => { switch (def_type) { .Integer => { diff --git a/src/TypeChecker.zig b/src/TypeChecker.zig index 025b378f..d59ced30 100644 --- a/src/TypeChecker.zig +++ b/src/TypeChecker.zig @@ -151,9 +151,9 @@ fn checkBinary(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, right_type, "Type mismatch", ); - } - had_error = true; + had_error = true; + } }, .Greater, @@ -247,8 +247,8 @@ fn checkBinary(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, ast.tokens.get(end_locations[node_components.Binary.left]), "Expected `int`.", ); + had_error = true; } - had_error = true; }, .Greater, .Less, @@ -614,6 +614,7 @@ fn checkDot(ast: Ast.Slice, reporter: *Reporter, gc: *GC, _: ?Ast.Node.Index, no ast.tokens.get(end_locations[node]), "Optional doesn't have field access", ); + had_error = true; } switch (callee_type.def_type) { diff --git a/src/buzz_api.zig b/src/buzz_api.zig index 3aa19776..ad52c348 100644 --- a/src/buzz_api.zig +++ b/src/buzz_api.zig @@ -749,7 +749,7 @@ pub export fn bz_call( return true; } - return false; + return true; } export fn bz_newQualifiedObjectInstance(self: *VM, qualified_name: [*]const u8, len: usize, mutable: bool) callconv(.c) v.Value { From d365ec5b1047e7b06c1212197e820ac8c751e75c Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 13 Nov 2025 23:05:46 +0100 Subject: [PATCH 17/17] fix: Prevent division by zero when folding constants --- src/Ast.zig | 11 +++++++++++ src/Codegen.zig | 15 +++++++-------- src/Jit.zig | 35 ++++++++++++++++++++++++++++++++++- src/Parser.zig | 3 ++- src/vm.zig | 7 +++++-- 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/Ast.zig b/src/Ast.zig index 7a0dd4a6..2bbd3600 100644 --- a/src/Ast.zig +++ b/src/Ast.zig @@ -683,6 +683,17 @@ pub const Slice = struct { return Value.fromInteger(right_integer.? *% left_integer.?); }, .Slash => { + if (right_float == 0 or right_integer == 0) { + reporter.reportErrorAt( + .runtime, + self.tokens.get(self.nodes.items(.location)[components.right]), + self.tokens.get(self.nodes.items(.end_location)[components.right]), + "Division by zero.", + ); + + return error.DivisionByZero; + } + if (right_float) |rf| { return Value.fromDouble(left_float.? / rf); } diff --git a/src/Codegen.zig b/src/Codegen.zig index 9a4fd122..f3bfdd77 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -23,6 +23,7 @@ const Self = @This(); pub const Error = error{ CantCompile, UnwrappedNull, + DivisionByZero, OutOfBound, ReachedMaximumMemoryUsage, WriteFailed, @@ -439,14 +440,12 @@ fn generateNode(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj fn nodeValue(self: *Self, node: Ast.Node.Index) Error!?Value { const value = &self.ast.nodes.items(.value)[node]; - if (value.* == null) { - if (self.ast.isConstant(node)) { - value.* = try self.ast.typeCheckAndToValue( - node, - &self.reporter, - self.gc, - ); - } + if (value.* == null and self.ast.isConstant(node)) { + value.* = try self.ast.typeCheckAndToValue( + node, + &self.reporter, + self.gc, + ); } return value.*; diff --git a/src/Jit.zig b/src/Jit.zig index 48a22f15..2b80e497 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -19,6 +19,7 @@ pub const Error = error{ CantCompile, UnwrappedNull, OutOfBound, + DivisionByZero, ReachedMaximumMemoryUsage, WriteFailed, } || std.mem.Allocator.Error || std.fmt.BufPrintError; @@ -2731,7 +2732,7 @@ fn buildBinary( }, else => unreachable, } - }, + }, .Star, .StarEqual => { switch (def_type) { .Integer => { @@ -2746,12 +2747,44 @@ fn buildBinary( } }, .Slash, .SlashEqual => { + const zero_label = m.MIR_new_label(self.ctx); + switch (def_type) { .Integer => { + self.BNE( + zero_label, + right_value, + m.MIR_new_uint_op(self.ctx, Value.fromInteger(0).val), + ); + + // Exit if division by zero + // FIXME: would be great to be able to report cleanly the error but how to have string constant in MIR? + try self.buildExternApiCall( + .exit, + null, + &[_]m.MIR_op_t{m.MIR_new_uint_op(self.ctx, 1)}, + ); + + self.append(zero_label); self.DIV(dest, left, right); try self.wrap(.Integer, dest, dest); }, .Double => { + self.BNE( + zero_label, + right_value, + m.MIR_new_uint_op(self.ctx, Value.fromDouble(0).val), + ); + + // Exit if division by zero + // FIXME: would be great to be able to report cleanly the error but how to have string constant in MIR? + try self.buildExternApiCall( + .exit, + null, + &[_]m.MIR_op_t{m.MIR_new_uint_op(self.ctx, 1)}, + ); + + self.append(zero_label); self.DDIV(left, left, right); try self.wrap(.Double, left, dest); }, diff --git a/src/Parser.zig b/src/Parser.zig index ffd73deb..52de029a 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -444,6 +444,7 @@ pub const Error = error{ ImportError, CantCompile, UnwrappedNull, + DivisionByZero, OutOfBound, ReachedMaximumMemoryUsage, WriteFailed, @@ -4887,7 +4888,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind .{ .tag = .Dot, .location = start_location, - .end_location = undefined, + .end_location = start_location, .components = .{ .Dot = .{ .callee = callee, diff --git a/src/vm.zig b/src/vm.zig index 3dcf4d33..e89d6ba3 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -428,6 +428,7 @@ pub const VM = struct { UnwrappedNull, OutOfBound, NumberOverflow, + DivisionByZero, NotInFiber, FiberOver, BadNumber, @@ -1532,7 +1533,9 @@ pub const VM = struct { catch_value, ) catch |err| { switch (err) { - Error.RuntimeError => return, + Error.RuntimeError, + Error.DivisionByZero, + => return, else => { self.panic("Out of memory"); unreachable; @@ -4800,7 +4803,7 @@ pub const VM = struct { } } - fn reportRuntimeErrorWithCurrentStack(self: *Self, message: []const u8) void { + pub fn reportRuntimeErrorWithCurrentStack(self: *Self, message: []const u8) void { self.reportRuntimeError( message, if (self.currentFrame()) |frame|