@elaraai/east 0.0.1-beta.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +15 -666
- package/README.md +113 -88
- package/dist/src/analyze.d.ts +3 -0
- package/dist/src/analyze.d.ts.map +1 -1
- package/dist/src/analyze.js +223 -111
- package/dist/src/analyze.js.map +1 -1
- package/dist/src/analyze.spec.d.ts +2 -0
- package/dist/src/analyze.spec.d.ts.map +1 -0
- package/dist/src/analyze.spec.js +445 -0
- package/dist/src/analyze.spec.js.map +1 -0
- package/dist/src/ast.d.ts +54 -35
- package/dist/src/ast.d.ts.map +1 -1
- package/dist/src/ast_to_ir.coerce_to.spec.d.ts +15 -0
- package/dist/src/ast_to_ir.coerce_to.spec.d.ts.map +1 -0
- package/dist/src/ast_to_ir.coerce_to.spec.js +420 -0
- package/dist/src/ast_to_ir.coerce_to.spec.js.map +1 -0
- package/dist/src/ast_to_ir.d.ts +18 -4
- package/dist/src/ast_to_ir.d.ts.map +1 -1
- package/dist/src/ast_to_ir.js +233 -178
- package/dist/src/ast_to_ir.js.map +1 -1
- package/dist/src/builtins.d.ts +1 -1
- package/dist/src/builtins.d.ts.map +1 -1
- package/dist/src/builtins.js +194 -2
- package/dist/src/builtins.js.map +1 -1
- package/dist/src/comparison.d.ts +2 -2
- package/dist/src/comparison.d.ts.map +1 -1
- package/dist/src/comparison.js +115 -40
- package/dist/src/comparison.js.map +1 -1
- package/dist/src/comparison.spec.d.ts +2 -0
- package/dist/src/comparison.spec.d.ts.map +1 -0
- package/dist/src/comparison.spec.js +1200 -0
- package/dist/src/comparison.spec.js.map +1 -0
- package/dist/src/compile.d.ts +31 -9
- package/dist/src/compile.d.ts.map +1 -1
- package/dist/src/compile.js +1048 -548
- package/dist/src/compile.js.map +1 -1
- package/dist/src/containers/matrix.d.ts +15 -0
- package/dist/src/containers/matrix.d.ts.map +1 -0
- package/dist/src/containers/matrix.js +15 -0
- package/dist/src/containers/matrix.js.map +1 -0
- package/dist/src/containers/ref.d.ts.map +1 -1
- package/dist/src/containers/ref.js +1 -1
- package/dist/src/containers/ref.js.map +1 -1
- package/dist/src/containers/sortedmap.spec.d.ts +2 -0
- package/dist/src/containers/sortedmap.spec.d.ts.map +1 -0
- package/dist/src/containers/sortedmap.spec.js +180 -0
- package/dist/src/containers/sortedmap.spec.js.map +1 -0
- package/dist/src/containers/sortedset.spec.d.ts +2 -0
- package/dist/src/containers/sortedset.spec.d.ts.map +1 -0
- package/dist/src/containers/sortedset.spec.js +228 -0
- package/dist/src/containers/sortedset.spec.js.map +1 -0
- package/dist/src/containers/variant.d.ts.map +1 -1
- package/dist/src/containers/variant.js +1 -1
- package/dist/src/containers/variant.js.map +1 -1
- package/dist/src/containers/variant.spec.d.ts +2 -0
- package/dist/src/containers/variant.spec.d.ts.map +1 -0
- package/dist/src/containers/variant.spec.js +217 -0
- package/dist/src/containers/variant.spec.js.map +1 -0
- package/dist/src/datetime_format/parse.spec.d.ts +6 -0
- package/dist/src/datetime_format/parse.spec.d.ts.map +1 -0
- package/dist/src/datetime_format/parse.spec.js +379 -0
- package/dist/src/datetime_format/parse.spec.js.map +1 -0
- package/dist/src/datetime_format/print.spec.d.ts +6 -0
- package/dist/src/datetime_format/print.spec.d.ts.map +1 -0
- package/dist/src/datetime_format/print.spec.js +257 -0
- package/dist/src/datetime_format/print.spec.js.map +1 -0
- package/dist/src/datetime_format/tokenize.spec.d.ts +2 -0
- package/dist/src/datetime_format/tokenize.spec.d.ts.map +1 -0
- package/dist/src/datetime_format/tokenize.spec.js +508 -0
- package/dist/src/datetime_format/tokenize.spec.js.map +1 -0
- package/dist/src/datetime_format/types.d.ts +23 -23
- package/dist/src/default.d.ts.map +1 -1
- package/dist/src/default.js +33 -0
- package/dist/src/default.js.map +1 -1
- package/dist/src/default.spec.d.ts +2 -0
- package/dist/src/default.spec.d.ts.map +1 -0
- package/dist/src/default.spec.js +178 -0
- package/dist/src/default.spec.js.map +1 -0
- package/dist/src/eastir.d.ts +7 -0
- package/dist/src/eastir.d.ts.map +1 -1
- package/dist/src/eastir.js +55 -7
- package/dist/src/eastir.js.map +1 -1
- package/dist/src/error.d.ts +14 -4
- package/dist/src/error.d.ts.map +1 -1
- package/dist/src/error.js +28 -3
- package/dist/src/error.js.map +1 -1
- package/dist/src/example.d.ts +87 -0
- package/dist/src/example.d.ts.map +1 -0
- package/dist/src/example.js +18 -0
- package/dist/src/example.js.map +1 -0
- package/dist/src/expr/array.d.ts +43 -1
- package/dist/src/expr/array.d.ts.map +1 -1
- package/dist/src/expr/array.js +103 -53
- package/dist/src/expr/array.js.map +1 -1
- package/dist/src/expr/ast.d.ts +1 -1
- package/dist/src/expr/ast.d.ts.map +1 -1
- package/dist/src/expr/ast.js +112 -54
- package/dist/src/expr/ast.js.map +1 -1
- package/dist/src/expr/asyncfunction.d.ts.map +1 -1
- package/dist/src/expr/asyncfunction.js +6 -4
- package/dist/src/expr/asyncfunction.js.map +1 -1
- package/dist/src/expr/blob.d.ts +48 -0
- package/dist/src/expr/blob.d.ts.map +1 -1
- package/dist/src/expr/blob.js +63 -8
- package/dist/src/expr/blob.js.map +1 -1
- package/dist/src/expr/block.d.ts +213 -12
- package/dist/src/expr/block.d.ts.map +1 -1
- package/dist/src/expr/block.js +796 -293
- package/dist/src/expr/block.js.map +1 -1
- package/dist/src/expr/boolean.d.ts +44 -0
- package/dist/src/expr/boolean.d.ts.map +1 -1
- package/dist/src/expr/boolean.js +58 -6
- package/dist/src/expr/boolean.js.map +1 -1
- package/dist/src/expr/datetime.d.ts +135 -0
- package/dist/src/expr/datetime.d.ts.map +1 -1
- package/dist/src/expr/datetime.js +184 -34
- package/dist/src/expr/datetime.js.map +1 -1
- package/dist/src/expr/dict.d.ts +47 -2
- package/dist/src/expr/dict.d.ts.map +1 -1
- package/dist/src/expr/dict.js +122 -61
- package/dist/src/expr/dict.js.map +1 -1
- package/dist/src/expr/expr.d.ts +3 -1
- package/dist/src/expr/expr.d.ts.map +1 -1
- package/dist/src/expr/expr.js +4 -3
- package/dist/src/expr/expr.js.map +1 -1
- package/dist/src/expr/float.d.ts +153 -0
- package/dist/src/expr/float.d.ts.map +1 -1
- package/dist/src/expr/float.js +191 -17
- package/dist/src/expr/float.js.map +1 -1
- package/dist/src/expr/function.d.ts +7 -2
- package/dist/src/expr/function.d.ts.map +1 -1
- package/dist/src/expr/function.js +6 -4
- package/dist/src/expr/function.js.map +1 -1
- package/dist/src/expr/index.d.ts +186 -2
- package/dist/src/expr/index.d.ts.map +1 -1
- package/dist/src/expr/index.js +183 -2
- package/dist/src/expr/index.js.map +1 -1
- package/dist/src/expr/integer.d.ts +180 -0
- package/dist/src/expr/integer.d.ts.map +1 -1
- package/dist/src/expr/integer.js +189 -18
- package/dist/src/expr/integer.js.map +1 -1
- package/dist/src/expr/libs/array.js +3 -3
- package/dist/src/expr/libs/array.js.map +1 -1
- package/dist/src/expr/libs/blob.js +3 -3
- package/dist/src/expr/libs/blob.js.map +1 -1
- package/dist/src/expr/libs/dict.js +1 -1
- package/dist/src/expr/libs/dict.js.map +1 -1
- package/dist/src/expr/libs/matrix.d.ts +17 -0
- package/dist/src/expr/libs/matrix.d.ts.map +1 -0
- package/dist/src/expr/libs/matrix.js +60 -0
- package/dist/src/expr/libs/matrix.js.map +1 -0
- package/dist/src/expr/libs/set.js +1 -1
- package/dist/src/expr/libs/set.js.map +1 -1
- package/dist/src/expr/libs/string.d.ts.map +1 -1
- package/dist/src/expr/libs/string.js +2 -1
- package/dist/src/expr/libs/string.js.map +1 -1
- package/dist/src/expr/libs/vector.d.ts +16 -0
- package/dist/src/expr/libs/vector.d.ts.map +1 -0
- package/dist/src/expr/libs/vector.js +44 -0
- package/dist/src/expr/libs/vector.js.map +1 -0
- package/dist/src/expr/matrix.d.ts +109 -0
- package/dist/src/expr/matrix.d.ts.map +1 -0
- package/dist/src/expr/matrix.js +224 -0
- package/dist/src/expr/matrix.js.map +1 -0
- package/dist/src/expr/recursive.d.ts +83 -0
- package/dist/src/expr/recursive.d.ts.map +1 -0
- package/dist/src/expr/recursive.js +99 -0
- package/dist/src/expr/recursive.js.map +1 -0
- package/dist/src/expr/ref.js +5 -5
- package/dist/src/expr/ref.js.map +1 -1
- package/dist/src/expr/set.d.ts +44 -2
- package/dist/src/expr/set.d.ts.map +1 -1
- package/dist/src/expr/set.js +102 -52
- package/dist/src/expr/set.js.map +1 -1
- package/dist/src/expr/string.d.ts +134 -0
- package/dist/src/expr/string.d.ts.map +1 -1
- package/dist/src/expr/string.js +173 -23
- package/dist/src/expr/string.js.map +1 -1
- package/dist/src/expr/struct.d.ts +1 -1
- package/dist/src/expr/struct.d.ts.map +1 -1
- package/dist/src/expr/struct.js +2 -2
- package/dist/src/expr/struct.js.map +1 -1
- package/dist/src/expr/types.d.ts +12 -9
- package/dist/src/expr/types.d.ts.map +1 -1
- package/dist/src/expr/variant.d.ts +108 -11
- package/dist/src/expr/variant.d.ts.map +1 -1
- package/dist/src/expr/variant.js +76 -38
- package/dist/src/expr/variant.js.map +1 -1
- package/dist/src/expr/vector.d.ts +102 -0
- package/dist/src/expr/vector.d.ts.map +1 -0
- package/dist/src/expr/vector.js +202 -0
- package/dist/src/expr/vector.js.map +1 -0
- package/dist/src/fuzz.d.ts +36 -2
- package/dist/src/fuzz.d.ts.map +1 -1
- package/dist/src/fuzz.js +409 -77
- package/dist/src/fuzz.js.map +1 -1
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/internal.d.ts +12 -2
- package/dist/src/internal.d.ts.map +1 -1
- package/dist/src/internal.js +13 -2
- package/dist/src/internal.js.map +1 -1
- package/dist/src/ir.d.ts +1754 -1484
- package/dist/src/ir.d.ts.map +1 -1
- package/dist/src/ir.js +51 -34
- package/dist/src/ir.js.map +1 -1
- package/dist/src/ir.spec.d.ts +2 -0
- package/dist/src/ir.spec.d.ts.map +1 -0
- package/dist/src/ir.spec.js +35 -0
- package/dist/src/ir.spec.js.map +1 -0
- package/dist/src/location.d.ts +56 -17
- package/dist/src/location.d.ts.map +1 -1
- package/dist/src/location.js +226 -29
- package/dist/src/location.js.map +1 -1
- package/dist/src/location.spec.d.ts +2 -0
- package/dist/src/location.spec.d.ts.map +1 -0
- package/dist/src/location.spec.js +102 -0
- package/dist/src/location.spec.js.map +1 -0
- package/dist/src/patch/apply.d.ts +15 -0
- package/dist/src/patch/apply.d.ts.map +1 -0
- package/dist/src/patch/apply.js +352 -0
- package/dist/src/patch/apply.js.map +1 -0
- package/dist/src/patch/compose.d.ts +15 -0
- package/dist/src/patch/compose.d.ts.map +1 -0
- package/dist/src/patch/compose.js +448 -0
- package/dist/src/patch/compose.js.map +1 -0
- package/dist/src/patch/diff.d.ts +15 -0
- package/dist/src/patch/diff.d.ts.map +1 -0
- package/dist/src/patch/diff.js +347 -0
- package/dist/src/patch/diff.js.map +1 -0
- package/dist/src/patch/fuzz.d.ts +73 -0
- package/dist/src/patch/fuzz.d.ts.map +1 -0
- package/dist/src/patch/fuzz.js +159 -0
- package/dist/src/patch/fuzz.js.map +1 -0
- package/dist/src/patch/index.d.ts +32 -0
- package/dist/src/patch/index.d.ts.map +1 -0
- package/dist/src/patch/index.js +48 -0
- package/dist/src/patch/index.js.map +1 -0
- package/dist/src/patch/invert.d.ts +15 -0
- package/dist/src/patch/invert.d.ts.map +1 -0
- package/dist/src/patch/invert.js +284 -0
- package/dist/src/patch/invert.js.map +1 -0
- package/dist/src/patch/merge.d.ts +56 -0
- package/dist/src/patch/merge.d.ts.map +1 -0
- package/dist/src/patch/merge.js +586 -0
- package/dist/src/patch/merge.js.map +1 -0
- package/dist/src/patch/merge.spec.d.ts +2 -0
- package/dist/src/patch/merge.spec.d.ts.map +1 -0
- package/dist/src/patch/merge.spec.js +1139 -0
- package/dist/src/patch/merge.spec.js.map +1 -0
- package/dist/src/patch/patch.spec.d.ts +2 -0
- package/dist/src/patch/patch.spec.d.ts.map +1 -0
- package/dist/src/patch/patch.spec.js +452 -0
- package/dist/src/patch/patch.spec.js.map +1 -0
- package/dist/src/patch/path.d.ts +115 -0
- package/dist/src/patch/path.d.ts.map +1 -0
- package/dist/src/patch/path.js +192 -0
- package/dist/src/patch/path.js.map +1 -0
- package/dist/src/patch/path.spec.d.ts +6 -0
- package/dist/src/patch/path.spec.d.ts.map +1 -0
- package/dist/src/patch/path.spec.js +322 -0
- package/dist/src/patch/path.spec.js.map +1 -0
- package/dist/src/patch/prune.d.ts +77 -0
- package/dist/src/patch/prune.d.ts.map +1 -0
- package/dist/src/patch/prune.js +115 -0
- package/dist/src/patch/prune.js.map +1 -0
- package/dist/src/patch/prune.spec.d.ts +6 -0
- package/dist/src/patch/prune.spec.d.ts.map +1 -0
- package/dist/src/patch/prune.spec.js +473 -0
- package/dist/src/patch/prune.spec.js.map +1 -0
- package/dist/src/patch/type_of_patch.d.ts +25 -0
- package/dist/src/patch/type_of_patch.d.ts.map +1 -0
- package/dist/src/patch/type_of_patch.js +144 -0
- package/dist/src/patch/type_of_patch.js.map +1 -0
- package/dist/src/patch/types.d.ts +220 -0
- package/dist/src/patch/types.d.ts.map +1 -0
- package/dist/src/patch/types.js +62 -0
- package/dist/src/patch/types.js.map +1 -0
- package/dist/src/patch/validate.d.ts +44 -0
- package/dist/src/patch/validate.d.ts.map +1 -0
- package/dist/src/patch/validate.js +190 -0
- package/dist/src/patch/validate.js.map +1 -0
- package/dist/src/patch/validate.spec.d.ts +6 -0
- package/dist/src/patch/validate.spec.d.ts.map +1 -0
- package/dist/src/patch/validate.spec.js +225 -0
- package/dist/src/patch/validate.spec.js.map +1 -0
- package/dist/src/patch/walk.d.ts +121 -0
- package/dist/src/patch/walk.d.ts.map +1 -0
- package/dist/src/patch/walk.js +385 -0
- package/dist/src/patch/walk.js.map +1 -0
- package/dist/src/patch/walk.spec.d.ts +6 -0
- package/dist/src/patch/walk.spec.d.ts.map +1 -0
- package/dist/src/patch/walk.spec.js +621 -0
- package/dist/src/patch/walk.spec.js.map +1 -0
- package/dist/src/platform.d.ts +6 -0
- package/dist/src/platform.d.ts.map +1 -1
- package/dist/src/platform.spec.d.ts +2 -0
- package/dist/src/platform.spec.d.ts.map +1 -0
- package/dist/src/platform.spec.js +330 -0
- package/dist/src/platform.spec.js.map +1 -0
- package/dist/src/serialization/beast.d.ts.map +1 -1
- package/dist/src/serialization/beast.js +12 -0
- package/dist/src/serialization/beast.js.map +1 -1
- package/dist/src/serialization/beast.spec.d.ts +6 -0
- package/dist/src/serialization/beast.spec.d.ts.map +1 -0
- package/dist/src/serialization/beast.spec.js +406 -0
- package/dist/src/serialization/beast.spec.js.map +1 -0
- package/dist/src/serialization/beast2/index.d.ts +50 -0
- package/dist/src/serialization/beast2/index.d.ts.map +1 -0
- package/dist/src/serialization/beast2/index.js +756 -0
- package/dist/src/serialization/beast2/index.js.map +1 -0
- package/dist/src/serialization/beast2/index.spec.d.ts +6 -0
- package/dist/src/serialization/beast2/index.spec.d.ts.map +1 -0
- package/dist/src/serialization/beast2/index.spec.js +528 -0
- package/dist/src/serialization/beast2/index.spec.js.map +1 -0
- package/dist/src/serialization/beast2/sourcemap-table.d.ts +29 -0
- package/dist/src/serialization/beast2/sourcemap-table.d.ts.map +1 -0
- package/dist/src/serialization/beast2/sourcemap-table.js +82 -0
- package/dist/src/serialization/beast2/sourcemap-table.js.map +1 -0
- package/dist/src/serialization/beast2/string-table.d.ts +16 -0
- package/dist/src/serialization/beast2/string-table.d.ts.map +1 -0
- package/dist/src/serialization/beast2/string-table.js +38 -0
- package/dist/src/serialization/beast2/string-table.js.map +1 -0
- package/dist/src/serialization/beast2/type-table.d.ts +86 -0
- package/dist/src/serialization/beast2/type-table.d.ts.map +1 -0
- package/dist/src/serialization/beast2/type-table.js +618 -0
- package/dist/src/serialization/beast2/type-table.js.map +1 -0
- package/dist/src/serialization/beast2/value-table.d.ts +40 -0
- package/dist/src/serialization/beast2/value-table.d.ts.map +1 -0
- package/dist/src/serialization/beast2/value-table.js +157 -0
- package/dist/src/serialization/beast2/value-table.js.map +1 -0
- package/dist/src/serialization/binary-utils.d.ts +33 -0
- package/dist/src/serialization/binary-utils.d.ts.map +1 -1
- package/dist/src/serialization/binary-utils.js +157 -0
- package/dist/src/serialization/binary-utils.js.map +1 -1
- package/dist/src/serialization/csv.d.ts +17 -17
- package/dist/src/serialization/csv.d.ts.map +1 -1
- package/dist/src/serialization/csv.js +10 -8
- package/dist/src/serialization/csv.js.map +1 -1
- package/dist/src/serialization/csv.spec.d.ts +2 -0
- package/dist/src/serialization/csv.spec.d.ts.map +1 -0
- package/dist/src/serialization/csv.spec.js +556 -0
- package/dist/src/serialization/csv.spec.js.map +1 -0
- package/dist/src/serialization/east-inferred.spec.d.ts +2 -0
- package/dist/src/serialization/east-inferred.spec.d.ts.map +1 -0
- package/dist/src/serialization/east-inferred.spec.js +322 -0
- package/dist/src/serialization/east-inferred.spec.js.map +1 -0
- package/dist/src/serialization/east.d.ts +1 -1
- package/dist/src/serialization/east.d.ts.map +1 -1
- package/dist/src/serialization/east.js +178 -26
- package/dist/src/serialization/east.js.map +1 -1
- package/dist/src/serialization/east.spec.d.ts +2 -0
- package/dist/src/serialization/east.spec.d.ts.map +1 -0
- package/dist/src/serialization/east.spec.js +1548 -0
- package/dist/src/serialization/east.spec.js.map +1 -0
- package/dist/src/serialization/index.d.ts +1 -2
- package/dist/src/serialization/index.d.ts.map +1 -1
- package/dist/src/serialization/index.js +1 -2
- package/dist/src/serialization/index.js.map +1 -1
- package/dist/src/serialization/json.d.ts +1 -1
- package/dist/src/serialization/json.d.ts.map +1 -1
- package/dist/src/serialization/json.js +123 -24
- package/dist/src/serialization/json.js.map +1 -1
- package/dist/src/serialization/json.spec.d.ts +2 -0
- package/dist/src/serialization/json.spec.d.ts.map +1 -0
- package/dist/src/serialization/json.spec.js +1297 -0
- package/dist/src/serialization/json.spec.js.map +1 -0
- package/dist/src/type_of_type.d.ts +72 -35
- package/dist/src/type_of_type.d.ts.map +1 -1
- package/dist/src/type_of_type.is_data.spec.d.ts +6 -0
- package/dist/src/type_of_type.is_data.spec.d.ts.map +1 -0
- package/dist/src/type_of_type.is_data.spec.js +221 -0
- package/dist/src/type_of_type.is_data.spec.js.map +1 -0
- package/dist/src/type_of_type.js +355 -80
- package/dist/src/type_of_type.js.map +1 -1
- package/dist/src/type_of_type.to_etv.spec.d.ts +6 -0
- package/dist/src/type_of_type.to_etv.spec.d.ts.map +1 -0
- package/dist/src/type_of_type.to_etv.spec.js +263 -0
- package/dist/src/type_of_type.to_etv.spec.js.map +1 -0
- package/dist/src/types.d.ts +82 -12
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.error.spec.d.ts +2 -0
- package/dist/src/types.error.spec.d.ts.map +1 -0
- package/dist/src/types.error.spec.js +665 -0
- package/dist/src/types.error.spec.js.map +1 -0
- package/dist/src/types.js +663 -156
- package/dist/src/types.js.map +1 -1
- package/dist/src/types.spec.d.ts +2 -0
- package/dist/src/types.spec.d.ts.map +1 -0
- package/dist/src/types.spec.js +946 -0
- package/dist/src/types.spec.js.map +1 -0
- package/dist/src/walker.d.ts +65 -0
- package/dist/src/walker.d.ts.map +1 -0
- package/dist/src/walker.js +165 -0
- package/dist/src/walker.js.map +1 -0
- package/dist/src/walker.spec.d.ts +6 -0
- package/dist/src/walker.spec.d.ts.map +1 -0
- package/dist/src/walker.spec.js +109 -0
- package/dist/src/walker.spec.js.map +1 -0
- package/package.json +16 -38
- package/dist/src/serialization/beast2-stream.d.ts +0 -38
- package/dist/src/serialization/beast2-stream.d.ts.map +0 -1
- package/dist/src/serialization/beast2-stream.js +0 -670
- package/dist/src/serialization/beast2-stream.js.map +0 -1
- package/dist/src/serialization/beast2.d.ts +0 -41
- package/dist/src/serialization/beast2.d.ts.map +0 -1
- package/dist/src/serialization/beast2.js +0 -495
- package/dist/src/serialization/beast2.js.map +0 -1
package/dist/src/fuzz.js
CHANGED
|
@@ -4,18 +4,37 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @remarks
|
|
6
6
|
*/
|
|
7
|
-
import { NullType, BooleanType, IntegerType, FloatType, StringType, DateTimeType, BlobType, ArrayType, SetType, DictType, StructType, VariantType, OptionType, } from "./types.js";
|
|
7
|
+
import { NullType, BooleanType, IntegerType, FloatType, StringType, DateTimeType, BlobType, ArrayType, SetType, DictType, StructType, VariantType, OptionType, RecursiveType, FunctionType, RefType, VectorType, MatrixType, } from "./types.js";
|
|
8
|
+
import { matrix } from "./containers/matrix.js";
|
|
8
9
|
import { isVariant, variant } from "./containers/variant.js";
|
|
9
10
|
import { printType } from "./types.js";
|
|
10
11
|
import { printFor } from "./serialization/east.js";
|
|
11
12
|
import { toEastTypeValue } from "./type_of_type.js";
|
|
12
13
|
import { ref } from "./containers/ref.js";
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Generates a random primitive East type.
|
|
16
|
+
*/
|
|
17
|
+
function randomPrimitiveType() {
|
|
18
|
+
const r = Math.random() * 7;
|
|
19
|
+
if (r < 1)
|
|
20
|
+
return NullType;
|
|
21
|
+
if (r < 2)
|
|
22
|
+
return BooleanType;
|
|
23
|
+
if (r < 3)
|
|
24
|
+
return IntegerType;
|
|
25
|
+
if (r < 4)
|
|
26
|
+
return FloatType;
|
|
27
|
+
if (r < 5)
|
|
28
|
+
return StringType;
|
|
29
|
+
if (r < 6)
|
|
30
|
+
return DateTimeType;
|
|
31
|
+
return BlobType;
|
|
32
|
+
}
|
|
15
33
|
/**
|
|
16
34
|
* Generates a random East type for fuzz testing.
|
|
17
35
|
*
|
|
18
36
|
* @param depth - Current nesting depth (used internally to limit recursion)
|
|
37
|
+
* @param options - Configuration options
|
|
19
38
|
* @returns A randomly generated {@link EastType}
|
|
20
39
|
*
|
|
21
40
|
* @remarks
|
|
@@ -25,34 +44,28 @@ import { ref } from "./containers/ref.js";
|
|
|
25
44
|
* - Sets and Dicts use {@link StringType} keys (immutability constraint)
|
|
26
45
|
* - Structs have 0-4 random fields
|
|
27
46
|
* - Variants have 1-3 random cases, with 30% chance of {@link OptionType}
|
|
47
|
+
* - Recursive types include linked lists, trees, and option-wrapped patterns
|
|
48
|
+
* - Function types have 0-3 arguments with random input/output types
|
|
28
49
|
*/
|
|
29
|
-
export function randomType(depth = 0) {
|
|
50
|
+
export function randomType(depth = 0, options = {}) {
|
|
51
|
+
const { includeRecursive = true, includeFunctions = true } = options;
|
|
30
52
|
// Limit nesting to avoid stack overflow and keep tests fast
|
|
31
53
|
const maxDepth = 3;
|
|
32
54
|
// Higher chance of primitives at deeper levels
|
|
33
55
|
const primitiveWeight = depth >= maxDepth ? 0.9 : 0.5;
|
|
34
56
|
if (Math.random() < primitiveWeight) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return FloatType;
|
|
45
|
-
if (r < 5)
|
|
46
|
-
return StringType;
|
|
47
|
-
if (r < 6)
|
|
48
|
-
return DateTimeType;
|
|
49
|
-
return BlobType;
|
|
50
|
-
}
|
|
51
|
-
// Complex type
|
|
52
|
-
const r = Math.random() * 5;
|
|
57
|
+
return randomPrimitiveType();
|
|
58
|
+
}
|
|
59
|
+
// Complex type - weights adjusted based on options
|
|
60
|
+
let totalWeight = 7; // Array, Set, Dict, Struct, Variant, Vector, Matrix
|
|
61
|
+
if (includeRecursive && depth === 0)
|
|
62
|
+
totalWeight += 1; // Recursive only at top level
|
|
63
|
+
if (includeFunctions)
|
|
64
|
+
totalWeight += 1;
|
|
65
|
+
const r = Math.random() * totalWeight;
|
|
53
66
|
if (r < 1) {
|
|
54
67
|
// Array
|
|
55
|
-
return ArrayType(randomType(depth + 1));
|
|
68
|
+
return ArrayType(randomType(depth + 1, { includeRecursive: false, includeFunctions: false }));
|
|
56
69
|
}
|
|
57
70
|
else if (r < 2) {
|
|
58
71
|
// Set (keys must be immutable)
|
|
@@ -60,39 +73,167 @@ export function randomType(depth = 0) {
|
|
|
60
73
|
}
|
|
61
74
|
else if (r < 3) {
|
|
62
75
|
// Dict (keys must be immutable)
|
|
63
|
-
return DictType(StringType, randomType(depth + 1));
|
|
76
|
+
return DictType(StringType, randomType(depth + 1, { includeRecursive: false, includeFunctions: false }));
|
|
64
77
|
}
|
|
65
78
|
else if (r < 4) {
|
|
66
79
|
// Struct with 0-4 fields
|
|
67
80
|
const fieldCount = Math.floor(Math.random() * 5);
|
|
68
81
|
const fields = {};
|
|
69
82
|
for (let i = 0; i < fieldCount; i++) {
|
|
70
|
-
fields[`field${i}`] = randomType(depth + 1);
|
|
83
|
+
fields[`field${i}`] = randomType(depth + 1, { includeRecursive: false, includeFunctions: false });
|
|
71
84
|
}
|
|
72
85
|
return StructType(fields);
|
|
73
86
|
}
|
|
74
|
-
else {
|
|
87
|
+
else if (r < 5) {
|
|
75
88
|
// Variant
|
|
76
89
|
if (Math.random() < 0.3) {
|
|
77
90
|
// Option type (common variant pattern)
|
|
78
|
-
return OptionType(randomType(depth + 1));
|
|
91
|
+
return OptionType(randomType(depth + 1, { includeRecursive: false, includeFunctions: false }));
|
|
79
92
|
}
|
|
80
93
|
else {
|
|
81
94
|
// Custom variant with 1-3 cases
|
|
82
95
|
const caseCount = 1 + Math.floor(Math.random() * 3);
|
|
83
96
|
const cases = {};
|
|
84
97
|
for (let i = 0; i < caseCount; i++) {
|
|
85
|
-
cases[`case${i}`] = randomType(depth + 1);
|
|
98
|
+
cases[`case${i}`] = randomType(depth + 1, { includeRecursive: false, includeFunctions: false });
|
|
86
99
|
}
|
|
87
100
|
return VariantType(cases);
|
|
88
101
|
}
|
|
89
102
|
}
|
|
103
|
+
else if (r < 6) {
|
|
104
|
+
// Vector with random numeric element type
|
|
105
|
+
const elemTypes = [FloatType, IntegerType, BooleanType];
|
|
106
|
+
return VectorType(elemTypes[Math.floor(Math.random() * elemTypes.length)]);
|
|
107
|
+
}
|
|
108
|
+
else if (r < 7) {
|
|
109
|
+
// Matrix with random numeric element type
|
|
110
|
+
const elemTypes = [FloatType, IntegerType, BooleanType];
|
|
111
|
+
return MatrixType(elemTypes[Math.floor(Math.random() * elemTypes.length)]);
|
|
112
|
+
}
|
|
113
|
+
else if (r < 8 && includeRecursive && depth === 0) {
|
|
114
|
+
// Recursive type - only at top level to avoid nested recursion complexity
|
|
115
|
+
return randomRecursiveType();
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// Function type
|
|
119
|
+
return randomFunctionType();
|
|
120
|
+
}
|
|
90
121
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Generates a random recursive type pattern.
|
|
124
|
+
*
|
|
125
|
+
* @returns A randomly generated {@link RecursiveType}
|
|
126
|
+
*
|
|
127
|
+
* @remarks
|
|
128
|
+
* Generates common recursive patterns:
|
|
129
|
+
* - Linked list: `rec t. <nil: Null, cons: (head: T, tail: t)>`
|
|
130
|
+
* - Tree: `rec t. (value: T, children: Array<t>)`
|
|
131
|
+
* - Option chain: `rec t. (value: T, next: Option<t>)`
|
|
132
|
+
* - Binary tree: `rec t. <leaf: T, node: (left: t, right: t)>`
|
|
133
|
+
* - Nested variant: `rec t. <a: T, b: (inner: t)>`
|
|
134
|
+
*/
|
|
135
|
+
export function randomRecursiveType() {
|
|
136
|
+
const innerType = randomPrimitiveType();
|
|
137
|
+
const pattern = Math.floor(Math.random() * 5);
|
|
138
|
+
switch (pattern) {
|
|
139
|
+
case 0:
|
|
140
|
+
// Linked list: rec t. <nil: Null, cons: (head: T, tail: t)>
|
|
141
|
+
return RecursiveType((self) => VariantType({
|
|
142
|
+
nil: NullType,
|
|
143
|
+
cons: StructType({ head: innerType, tail: self }),
|
|
144
|
+
}));
|
|
145
|
+
case 1:
|
|
146
|
+
// Tree with children array: rec t. (value: T, children: Array<t>)
|
|
147
|
+
return RecursiveType((self) => StructType({
|
|
148
|
+
value: innerType,
|
|
149
|
+
children: ArrayType(self),
|
|
150
|
+
}));
|
|
151
|
+
case 2:
|
|
152
|
+
// Option chain: rec t. (value: T, next: Option<t>)
|
|
153
|
+
return RecursiveType((self) => StructType({
|
|
154
|
+
value: innerType,
|
|
155
|
+
next: OptionType(self),
|
|
156
|
+
}));
|
|
157
|
+
case 3:
|
|
158
|
+
// Binary tree: rec t. <leaf: T, node: (left: t, right: t)>
|
|
159
|
+
return RecursiveType((self) => VariantType({
|
|
160
|
+
leaf: innerType,
|
|
161
|
+
node: StructType({ left: self, right: self }),
|
|
162
|
+
}));
|
|
163
|
+
case 4:
|
|
164
|
+
default:
|
|
165
|
+
// Nested variant with ref: rec t. <done: T, more: Ref<t>>
|
|
166
|
+
return RecursiveType((self) => VariantType({
|
|
167
|
+
done: innerType,
|
|
168
|
+
more: RefType(self),
|
|
169
|
+
}));
|
|
95
170
|
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Generates a random function type.
|
|
174
|
+
*
|
|
175
|
+
* @returns A randomly generated {@link FunctionType}
|
|
176
|
+
*
|
|
177
|
+
* @remarks
|
|
178
|
+
* Functions have 0-3 arguments with random primitive or simple types.
|
|
179
|
+
* Output types are also kept simple to avoid excessive nesting.
|
|
180
|
+
*/
|
|
181
|
+
export function randomFunctionType() {
|
|
182
|
+
const argCount = Math.floor(Math.random() * 4);
|
|
183
|
+
const args = [];
|
|
184
|
+
for (let i = 0; i < argCount; i++) {
|
|
185
|
+
// Use simple types for arguments to keep things manageable
|
|
186
|
+
const argType = Math.random() < 0.7
|
|
187
|
+
? randomPrimitiveType()
|
|
188
|
+
: ArrayType(randomPrimitiveType());
|
|
189
|
+
args.push(argType);
|
|
190
|
+
}
|
|
191
|
+
// Output type - also keep simple
|
|
192
|
+
const outputType = Math.random() < 0.7
|
|
193
|
+
? randomPrimitiveType()
|
|
194
|
+
: StructType({
|
|
195
|
+
result: randomPrimitiveType(),
|
|
196
|
+
status: BooleanType,
|
|
197
|
+
});
|
|
198
|
+
return FunctionType(args, outputType);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Check if a type contains any `.Recursive n` back-references.
|
|
202
|
+
* A type without recursive refs is "terminal" - it won't cause infinite recursion.
|
|
203
|
+
* @internal
|
|
204
|
+
*/
|
|
205
|
+
function containsRecursive(type) {
|
|
206
|
+
switch (type.type) {
|
|
207
|
+
case "Recursive":
|
|
208
|
+
return true;
|
|
209
|
+
case "Ref":
|
|
210
|
+
case "Array":
|
|
211
|
+
return containsRecursive(type.value);
|
|
212
|
+
case "Set":
|
|
213
|
+
return containsRecursive(type.value);
|
|
214
|
+
case "Dict":
|
|
215
|
+
return containsRecursive(type.value.key) || containsRecursive(type.value.value);
|
|
216
|
+
case "Struct":
|
|
217
|
+
return type.value.some(f => containsRecursive(f.type));
|
|
218
|
+
case "Variant":
|
|
219
|
+
return type.value.some(c => containsRecursive(c.type));
|
|
220
|
+
case "Vector":
|
|
221
|
+
case "Matrix":
|
|
222
|
+
default:
|
|
223
|
+
// Primitives, vectors, matrices, functions don't contain recursive refs
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Internal helper that generates random values with explicit depth passing.
|
|
229
|
+
* Returns a function that takes depth and produces a value.
|
|
230
|
+
*
|
|
231
|
+
* This design passes depth explicitly through all generators, avoiding the bug
|
|
232
|
+
* where shared mutable depth state was incorrectly restored after generating
|
|
233
|
+
* sibling fields in structs.
|
|
234
|
+
* @internal
|
|
235
|
+
*/
|
|
236
|
+
function buildValueGenerator(type, ctx) {
|
|
96
237
|
if (type.type === "Never") {
|
|
97
238
|
throw new Error("Cannot generate values for Never type");
|
|
98
239
|
}
|
|
@@ -100,13 +241,13 @@ export function randomValueFor(type) {
|
|
|
100
241
|
return () => null;
|
|
101
242
|
}
|
|
102
243
|
else if (type.type === "Boolean") {
|
|
103
|
-
return (
|
|
244
|
+
return () => Math.random() < 0.5;
|
|
104
245
|
}
|
|
105
246
|
else if (type.type === "Integer") {
|
|
106
|
-
return (
|
|
247
|
+
return () => BigInt(Math.floor(Math.random() * 200) - 100);
|
|
107
248
|
}
|
|
108
249
|
else if (type.type === "Float") {
|
|
109
|
-
return (
|
|
250
|
+
return () => {
|
|
110
251
|
const r = Math.random();
|
|
111
252
|
if (r < 0.05)
|
|
112
253
|
return NaN;
|
|
@@ -119,98 +260,287 @@ export function randomValueFor(type) {
|
|
|
119
260
|
if (r < 0.25)
|
|
120
261
|
return -0.0;
|
|
121
262
|
return Math.random() * 200 - 100;
|
|
122
|
-
}
|
|
263
|
+
};
|
|
123
264
|
}
|
|
124
265
|
else if (type.type === "String") {
|
|
125
|
-
return (
|
|
266
|
+
return () => {
|
|
126
267
|
const length = Math.floor(Math.random() * 20);
|
|
127
268
|
if (length === 0)
|
|
128
269
|
return "";
|
|
129
270
|
return Math.random().toString(36).substring(2, 2 + length);
|
|
130
|
-
}
|
|
271
|
+
};
|
|
131
272
|
}
|
|
132
273
|
else if (type.type === "DateTime") {
|
|
133
|
-
return (
|
|
274
|
+
return () => {
|
|
134
275
|
const year2025 = new Date("2025-01-01T00:00:00.000Z").valueOf();
|
|
135
276
|
const oneYear = 1000 * 60 * 60 * 24 * 365;
|
|
136
277
|
return new Date(year2025 + Math.floor(Math.random() * oneYear));
|
|
137
|
-
}
|
|
278
|
+
};
|
|
138
279
|
}
|
|
139
280
|
else if (type.type === "Blob") {
|
|
140
|
-
return (
|
|
141
|
-
const length = Math.floor(Math.random() * 100);
|
|
281
|
+
return () => {
|
|
282
|
+
const length = Math.floor(Math.random() * 100);
|
|
142
283
|
const arr = new Uint8Array(length);
|
|
143
284
|
for (let i = 0; i < length; i++) {
|
|
144
285
|
arr[i] = Math.floor(Math.random() * 256);
|
|
145
286
|
}
|
|
146
287
|
return arr;
|
|
147
|
-
}
|
|
288
|
+
};
|
|
148
289
|
}
|
|
149
290
|
else if (type.type === "Ref") {
|
|
150
|
-
|
|
151
|
-
|
|
291
|
+
// Create function shell, push, recurse, pop - like apply.ts pattern
|
|
292
|
+
let valueGen;
|
|
293
|
+
const ret = (depth) => ref(valueGen(depth));
|
|
294
|
+
valueGen = buildValueGenerator(type.value, ctx);
|
|
295
|
+
return ret;
|
|
152
296
|
}
|
|
153
297
|
else if (type.type === "Array") {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
298
|
+
let itemGen;
|
|
299
|
+
const ret = (depth) => {
|
|
300
|
+
const maxLen = depth >= ctx.maxDepth ? 0 : Math.max(1, 5 - depth);
|
|
301
|
+
const length = Math.floor(Math.random() * (maxLen + 1));
|
|
302
|
+
return Array.from({ length }, () => itemGen(depth));
|
|
303
|
+
};
|
|
304
|
+
itemGen = buildValueGenerator(type.value, ctx);
|
|
305
|
+
return ret;
|
|
159
306
|
}
|
|
160
307
|
else if (type.type === "Set") {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const
|
|
308
|
+
let itemGen;
|
|
309
|
+
const ret = (depth) => {
|
|
310
|
+
const maxLen = depth >= ctx.maxDepth ? 0 : 5;
|
|
311
|
+
const length = Math.floor(Math.random() * (maxLen + 1));
|
|
164
312
|
const set = new Set();
|
|
165
313
|
for (let i = 0; i < length; i++) {
|
|
166
|
-
set.add(
|
|
314
|
+
set.add(itemGen(depth));
|
|
167
315
|
}
|
|
168
316
|
return set;
|
|
169
|
-
}
|
|
317
|
+
};
|
|
318
|
+
itemGen = buildValueGenerator(type.value, ctx);
|
|
319
|
+
return ret;
|
|
170
320
|
}
|
|
171
321
|
else if (type.type === "Dict") {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const
|
|
322
|
+
let keyGen;
|
|
323
|
+
let valueGen;
|
|
324
|
+
const ret = (depth) => {
|
|
325
|
+
const maxLen = depth >= ctx.maxDepth ? 0 : 5;
|
|
326
|
+
const length = Math.floor(Math.random() * (maxLen + 1));
|
|
176
327
|
const dict = new Map();
|
|
177
328
|
for (let i = 0; i < length; i++) {
|
|
178
|
-
dict.set(
|
|
329
|
+
dict.set(keyGen(depth), valueGen(depth));
|
|
179
330
|
}
|
|
180
331
|
return dict;
|
|
181
|
-
}
|
|
332
|
+
};
|
|
333
|
+
keyGen = buildValueGenerator(type.value.key, ctx);
|
|
334
|
+
valueGen = buildValueGenerator(type.value.value, ctx);
|
|
335
|
+
return ret;
|
|
182
336
|
}
|
|
183
337
|
else if (type.type === "Struct") {
|
|
184
|
-
|
|
185
|
-
|
|
338
|
+
let fieldGens;
|
|
339
|
+
const ret = (depth) => {
|
|
186
340
|
const obj = {};
|
|
187
|
-
for (const
|
|
188
|
-
obj[
|
|
341
|
+
for (const { name, gen } of fieldGens) {
|
|
342
|
+
obj[name] = gen(depth);
|
|
189
343
|
}
|
|
190
344
|
return obj;
|
|
191
|
-
}
|
|
345
|
+
};
|
|
346
|
+
fieldGens = type.value.map(({ name, type: fieldType }) => ({
|
|
347
|
+
name,
|
|
348
|
+
gen: buildValueGenerator(fieldType, ctx),
|
|
349
|
+
}));
|
|
350
|
+
return ret;
|
|
192
351
|
}
|
|
193
352
|
else if (type.type === "Variant") {
|
|
194
|
-
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
353
|
+
let caseInfos;
|
|
354
|
+
const ret = (depth) => {
|
|
355
|
+
const terminalCases = caseInfos.filter((c) => c.isTerminal);
|
|
356
|
+
const nonTerminalCases = caseInfos.filter((c) => !c.isTerminal);
|
|
357
|
+
let chosen;
|
|
358
|
+
if (depth >= ctx.maxDepth && terminalCases.length > 0) {
|
|
359
|
+
chosen = terminalCases[Math.floor(Math.random() * terminalCases.length)];
|
|
360
|
+
}
|
|
361
|
+
else if (terminalCases.length > 0 && nonTerminalCases.length > 0) {
|
|
362
|
+
const terminalProb = Math.min(0.3 + depth * 0.2, 0.9);
|
|
363
|
+
if (Math.random() < terminalProb) {
|
|
364
|
+
chosen = terminalCases[Math.floor(Math.random() * terminalCases.length)];
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
chosen = nonTerminalCases[Math.floor(Math.random() * nonTerminalCases.length)];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
chosen = caseInfos[Math.floor(Math.random() * caseInfos.length)];
|
|
372
|
+
}
|
|
373
|
+
return variant(chosen.name, chosen.gen(depth));
|
|
374
|
+
};
|
|
375
|
+
caseInfos = type.value.map(({ name, type: caseType }) => ({
|
|
376
|
+
name,
|
|
377
|
+
gen: buildValueGenerator(caseType, ctx),
|
|
378
|
+
isTerminal: !containsRecursive(caseType),
|
|
379
|
+
}));
|
|
380
|
+
return ret;
|
|
381
|
+
}
|
|
382
|
+
else if (type.type === "Recursive" && type.value.type === "wrapper") {
|
|
383
|
+
// Recursive wrapper: register by id, build inner
|
|
384
|
+
let inner;
|
|
385
|
+
const ret = (...args) => inner(...args);
|
|
386
|
+
ctx.generators.set(type.value.value.id, ret);
|
|
387
|
+
inner = buildValueGenerator(type.value.value.inner, ctx);
|
|
388
|
+
return ret;
|
|
200
389
|
}
|
|
201
390
|
else if (type.type === "Recursive") {
|
|
202
|
-
|
|
391
|
+
// Look up the generator by type id
|
|
392
|
+
const id = type.value.value;
|
|
393
|
+
const generator = ctx.generators.get(id);
|
|
394
|
+
if (!generator) {
|
|
395
|
+
throw new Error(`Recursive generator not found for id ${id}`);
|
|
396
|
+
}
|
|
397
|
+
// Return a generator that calls the captured recursive generator with depth+1
|
|
398
|
+
return (depth) => generator(depth + 1);
|
|
203
399
|
}
|
|
204
400
|
else if (type.type === "Function") {
|
|
205
|
-
|
|
401
|
+
let outputGen;
|
|
402
|
+
const ret = (depth) => {
|
|
403
|
+
return (..._args) => outputGen(depth);
|
|
404
|
+
};
|
|
405
|
+
outputGen = buildValueGenerator(type.value.output, ctx);
|
|
406
|
+
return ret;
|
|
206
407
|
}
|
|
207
408
|
else if (type.type === "AsyncFunction") {
|
|
208
|
-
|
|
409
|
+
let outputGen;
|
|
410
|
+
const ret = (depth) => {
|
|
411
|
+
return (..._args) => Promise.resolve(outputGen(depth));
|
|
412
|
+
};
|
|
413
|
+
outputGen = buildValueGenerator(type.value.output, ctx);
|
|
414
|
+
return ret;
|
|
415
|
+
}
|
|
416
|
+
else if (type.type === "Vector") {
|
|
417
|
+
const elemType = type.value;
|
|
418
|
+
return () => {
|
|
419
|
+
const length = Math.floor(Math.random() * 10);
|
|
420
|
+
if (elemType.type === "Float") {
|
|
421
|
+
const arr = new Float64Array(length);
|
|
422
|
+
for (let i = 0; i < length; i++) {
|
|
423
|
+
const r = Math.random();
|
|
424
|
+
if (r < 0.05)
|
|
425
|
+
arr[i] = NaN;
|
|
426
|
+
else if (r < 0.10)
|
|
427
|
+
arr[i] = Infinity;
|
|
428
|
+
else if (r < 0.15)
|
|
429
|
+
arr[i] = -Infinity;
|
|
430
|
+
else
|
|
431
|
+
arr[i] = Math.random() * 200 - 100;
|
|
432
|
+
}
|
|
433
|
+
return arr;
|
|
434
|
+
}
|
|
435
|
+
else if (elemType.type === "Integer") {
|
|
436
|
+
const arr = new BigInt64Array(length);
|
|
437
|
+
for (let i = 0; i < length; i++)
|
|
438
|
+
arr[i] = BigInt(Math.floor(Math.random() * 200) - 100);
|
|
439
|
+
return arr;
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
const arr = new Uint8ClampedArray(length);
|
|
443
|
+
for (let i = 0; i < length; i++)
|
|
444
|
+
arr[i] = Math.random() < 0.5 ? 1 : 0;
|
|
445
|
+
return arr;
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
else if (type.type === "Matrix") {
|
|
450
|
+
const elemType = type.value;
|
|
451
|
+
return () => {
|
|
452
|
+
const rows = Math.floor(Math.random() * 5);
|
|
453
|
+
const cols = rows === 0 ? 0 : Math.floor(Math.random() * 5);
|
|
454
|
+
const totalLen = rows * cols;
|
|
455
|
+
if (elemType.type === "Float") {
|
|
456
|
+
const data = new Float64Array(totalLen);
|
|
457
|
+
for (let i = 0; i < totalLen; i++) {
|
|
458
|
+
const r = Math.random();
|
|
459
|
+
if (r < 0.05)
|
|
460
|
+
data[i] = NaN;
|
|
461
|
+
else if (r < 0.10)
|
|
462
|
+
data[i] = Infinity;
|
|
463
|
+
else if (r < 0.15)
|
|
464
|
+
data[i] = -Infinity;
|
|
465
|
+
else
|
|
466
|
+
data[i] = Math.random() * 200 - 100;
|
|
467
|
+
}
|
|
468
|
+
return matrix(data, rows, cols);
|
|
469
|
+
}
|
|
470
|
+
else if (elemType.type === "Integer") {
|
|
471
|
+
const data = new BigInt64Array(totalLen);
|
|
472
|
+
for (let i = 0; i < totalLen; i++)
|
|
473
|
+
data[i] = BigInt(Math.floor(Math.random() * 200) - 100);
|
|
474
|
+
return matrix(data, rows, cols);
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
const data = new Uint8ClampedArray(totalLen);
|
|
478
|
+
for (let i = 0; i < totalLen; i++)
|
|
479
|
+
data[i] = Math.random() < 0.5 ? 1 : 0;
|
|
480
|
+
return matrix(data, rows, cols);
|
|
481
|
+
}
|
|
482
|
+
};
|
|
209
483
|
}
|
|
210
484
|
else {
|
|
211
485
|
throw new Error(`Unhandled type: ${printType(type)}`);
|
|
212
486
|
}
|
|
213
487
|
}
|
|
488
|
+
/**
|
|
489
|
+
* Internal helper to handle RecursiveType before conversion.
|
|
490
|
+
* Sets up the context stack and builds the value generator.
|
|
491
|
+
*
|
|
492
|
+
* The key insight: we create the generator function first, register it in the
|
|
493
|
+
* context stack, then build the inner generator. This allows the inner generator
|
|
494
|
+
* to find the outer generator via de Bruijn index lookup when it hits a
|
|
495
|
+
* `.Recursive n` back-reference.
|
|
496
|
+
* @internal
|
|
497
|
+
*/
|
|
498
|
+
function randomValueForRecursive(innerNode, ctx) {
|
|
499
|
+
// The inner generator - will be set after building
|
|
500
|
+
let innerGen = null;
|
|
501
|
+
// Create the self-referential generator
|
|
502
|
+
// This will be called when we hit a .Recursive n back-reference
|
|
503
|
+
const selfGenerator = (depth) => {
|
|
504
|
+
if (!innerGen) {
|
|
505
|
+
throw new Error("Internal error: recursive generator not initialized");
|
|
506
|
+
}
|
|
507
|
+
// Hard limit to prevent stack overflow
|
|
508
|
+
if (depth > ctx.maxDepth + 5) {
|
|
509
|
+
throw new Error("Fuzz value generation exceeded max recursion depth");
|
|
510
|
+
}
|
|
511
|
+
return innerGen(depth);
|
|
512
|
+
};
|
|
513
|
+
// Push BEFORE building the inner generator so .Recursive can find it
|
|
514
|
+
// Convert inner node to EastTypeValue with recursive context
|
|
515
|
+
// Pass empty stack - the type structure will build up the stack naturally
|
|
516
|
+
// as it recurses. When self-references (RecursiveType pointing back) are hit,
|
|
517
|
+
// they'll find the struct in the stack and return .Recursive indices.
|
|
518
|
+
const innerTypeValue = toEastTypeValue(innerNode, [], true);
|
|
519
|
+
// Build the inner generator
|
|
520
|
+
innerGen = buildValueGenerator(innerTypeValue, ctx);
|
|
521
|
+
// Pop after building (generator is now self-contained via closure)
|
|
522
|
+
// Return a function that starts generation at depth 0
|
|
523
|
+
return () => selfGenerator(0);
|
|
524
|
+
}
|
|
525
|
+
export function randomValueFor(type) {
|
|
526
|
+
const ctx = {
|
|
527
|
+
generators: new Map(),
|
|
528
|
+
maxDepth: 5, // Limit recursion depth to avoid huge values
|
|
529
|
+
};
|
|
530
|
+
// Check if this is an EastType (not yet converted)
|
|
531
|
+
if (!isVariant(type)) {
|
|
532
|
+
// Handle RecursiveType specially before conversion
|
|
533
|
+
if (type.type === "Recursive") {
|
|
534
|
+
return randomValueForRecursive(type.node, ctx);
|
|
535
|
+
}
|
|
536
|
+
// Convert other EastTypes to EastTypeValue
|
|
537
|
+
const typeValue = toEastTypeValue(type);
|
|
538
|
+
const gen = buildValueGenerator(typeValue, ctx);
|
|
539
|
+
return () => gen(0);
|
|
540
|
+
}
|
|
541
|
+
const gen = buildValueGenerator(type, ctx);
|
|
542
|
+
return () => gen(0);
|
|
543
|
+
}
|
|
214
544
|
/**
|
|
215
545
|
* Runs a fuzz test over a generic function parameterized by a type.
|
|
216
546
|
*
|
|
@@ -247,7 +577,9 @@ export function randomValueFor(type) {
|
|
|
247
577
|
* );
|
|
248
578
|
* ```
|
|
249
579
|
*/
|
|
250
|
-
export async function fuzzerTest(fn, n_types = 100, n_samples = 10) {
|
|
580
|
+
export async function fuzzerTest(fn, n_types = 100, n_samples = 10, options = {}) {
|
|
581
|
+
// Default: include recursive types but NOT functions (can't generate values for functions)
|
|
582
|
+
const { includeRecursive = true, includeFunctions = false } = options;
|
|
251
583
|
let n_type_success = 0;
|
|
252
584
|
let n_type_fail = 0;
|
|
253
585
|
const type_cache = new Set();
|
|
@@ -258,7 +590,7 @@ export async function fuzzerTest(fn, n_types = 100, n_samples = 10) {
|
|
|
258
590
|
let type;
|
|
259
591
|
let attempts = 0;
|
|
260
592
|
while (true) {
|
|
261
|
-
type = randomType();
|
|
593
|
+
type = randomType(0, { includeRecursive, includeFunctions });
|
|
262
594
|
const typeStr = printType(type);
|
|
263
595
|
if (!type_cache.has(typeStr)) {
|
|
264
596
|
type_cache.add(typeStr);
|