@scriptc/compiler 0.0.35 → 0.1.1
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/ambient/scriptc-node-fallback.d.ts +14 -11
- package/ambient/scriptc-overrides.d.ts +0 -7
- package/ambient/scriptc.d.ts +1 -1
- package/dist/backend/build-cache.d.ts +44 -0
- package/dist/backend/build-cache.js +241 -0
- package/dist/backend/build-cache.js.map +1 -0
- package/dist/backend/{emission/emit-async.d.ts → c/async.d.ts} +21 -30
- package/dist/backend/{emission/emit-async.js → c/async.js} +270 -286
- package/dist/backend/c/async.js.map +1 -0
- package/dist/backend/{emission/emitter.d.ts → c/c-emitter.d.ts} +6 -23
- package/dist/backend/{emission/emitter.js → c/c-emitter.js} +53 -107
- package/dist/backend/c/c-emitter.js.map +1 -0
- package/dist/backend/c/exprs.d.ts +8 -0
- package/dist/backend/c/exprs.js +7937 -0
- package/dist/backend/c/exprs.js.map +1 -0
- package/dist/backend/{emission/emit-island.d.ts → c/island.d.ts} +5 -5
- package/dist/backend/{emission/emit-island.js → c/island.js} +24 -22
- package/dist/backend/c/island.js.map +1 -0
- package/dist/backend/{emission → c}/may-throw.d.ts +1 -1
- package/dist/backend/{emission → c}/may-throw.js +4 -1
- package/dist/backend/c/may-throw.js.map +1 -0
- package/dist/backend/{emission/emit-shapes.d.ts → c/shapes.d.ts} +19 -19
- package/dist/backend/{emission/emit-shapes.js → c/shapes.js} +78 -87
- package/dist/backend/c/shapes.js.map +1 -0
- package/dist/backend/{emission/emit-stmts.d.ts → c/stmts.d.ts} +12 -12
- package/dist/backend/{emission/emit-stmts.js → c/stmts.js} +395 -343
- package/dist/backend/c/stmts.js.map +1 -0
- package/dist/backend/{emission/emit-types.d.ts → c/types.d.ts} +1 -1
- package/dist/backend/{emission/emit-types.js → c/types.js} +42 -286
- package/dist/backend/c/types.js.map +1 -0
- package/dist/backend/c/types.test.js +25 -0
- package/dist/backend/c/types.test.js.map +1 -0
- package/dist/backend/{emission/emit-walkers.d.ts → c/walkers.d.ts} +19 -41
- package/dist/backend/{emission/emit-walkers.js → c/walkers.js} +242 -304
- package/dist/backend/c/walkers.js.map +1 -0
- package/dist/backend/external-c.d.ts +33 -0
- package/dist/backend/external-c.js +51 -0
- package/dist/backend/external-c.js.map +1 -0
- package/dist/backend/ffi-callbacks.d.ts +1 -1
- package/dist/backend/ffi-callbacks.js +4 -3
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/{library-identity.d.ts → library-identity-markers.d.ts} +0 -4
- package/dist/backend/{library-identity.js → library-identity-markers.js} +10 -9
- package/dist/backend/library-identity-markers.js.map +1 -0
- package/dist/backend/link-plan.d.ts +37 -0
- package/dist/backend/link-plan.js +26 -0
- package/dist/backend/link-plan.js.map +1 -0
- package/dist/backend/linker.d.ts +22 -0
- package/dist/backend/linker.js +236 -0
- package/dist/backend/linker.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +4 -0
- package/dist/backend/llvm/blocks.js +29 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +2 -19
- package/dist/backend/llvm/classes.js +20 -52
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +4 -0
- package/dist/backend/llvm/common.js +27 -0
- package/dist/backend/llvm/common.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +3 -8
- package/dist/backend/llvm/dyn.js +159 -224
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +4 -1
- package/dist/backend/llvm/emitter.js +548 -9988
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-async.d.ts +4 -0
- package/dist/backend/llvm/expr-async.js +726 -0
- package/dist/backend/llvm/expr-async.js.map +1 -0
- package/dist/backend/llvm/expr-bytes.d.ts +13 -0
- package/dist/backend/llvm/expr-bytes.js +456 -0
- package/dist/backend/llvm/expr-bytes.js.map +1 -0
- package/dist/backend/llvm/expr-callbacks.d.ts +22 -0
- package/dist/backend/llvm/expr-callbacks.js +520 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -0
- package/dist/backend/llvm/expr-calls.d.ts +2 -0
- package/dist/backend/llvm/expr-calls.js +618 -0
- package/dist/backend/llvm/expr-calls.js.map +1 -0
- package/dist/backend/llvm/expr-containers.d.ts +25 -0
- package/dist/backend/llvm/expr-containers.js +637 -0
- package/dist/backend/llvm/expr-containers.js.map +1 -0
- package/dist/backend/llvm/expr-context.d.ts +255 -0
- package/dist/backend/llvm/expr-context.js +2 -0
- package/dist/backend/llvm/expr-context.js.map +1 -0
- package/dist/backend/llvm/expr-control.d.ts +2 -0
- package/dist/backend/llvm/expr-control.js +473 -0
- package/dist/backend/llvm/expr-control.js.map +1 -0
- package/dist/backend/llvm/expr-dispatch.d.ts +4 -0
- package/dist/backend/llvm/expr-dispatch.js +153 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -0
- package/dist/backend/llvm/expr-dynamic.d.ts +2 -0
- package/dist/backend/llvm/expr-dynamic.js +810 -0
- package/dist/backend/llvm/expr-dynamic.js.map +1 -0
- package/dist/backend/llvm/expr-island.d.ts +15 -0
- package/dist/backend/llvm/expr-island.js +690 -0
- package/dist/backend/llvm/expr-island.js.map +1 -0
- package/dist/backend/llvm/expr-primitives.d.ts +6 -0
- package/dist/backend/llvm/expr-primitives.js +642 -0
- package/dist/backend/llvm/expr-primitives.js.map +1 -0
- package/dist/backend/llvm/expr-records.d.ts +9 -0
- package/dist/backend/llvm/expr-records.js +299 -0
- package/dist/backend/llvm/expr-records.js.map +1 -0
- package/dist/backend/llvm/expr-stream-bridges.d.ts +13 -0
- package/dist/backend/llvm/expr-stream-bridges.js +420 -0
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +12 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +360 -0
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -0
- package/dist/backend/llvm/lib-dispatch.d.ts +5 -0
- package/dist/backend/llvm/lib-dispatch.js +267 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -0
- package/dist/backend/llvm/lib-filesystem.d.ts +6 -0
- package/dist/backend/llvm/lib-filesystem.js +594 -0
- package/dist/backend/llvm/lib-filesystem.js.map +1 -0
- package/dist/backend/llvm/lib-network.d.ts +2 -0
- package/dist/backend/llvm/lib-network.js +429 -0
- package/dist/backend/llvm/lib-network.js.map +1 -0
- package/dist/backend/llvm/lib-process.d.ts +5 -0
- package/dist/backend/llvm/lib-process.js +585 -0
- package/dist/backend/llvm/lib-process.js.map +1 -0
- package/dist/backend/llvm/lib-shared.d.ts +6 -0
- package/dist/backend/llvm/lib-shared.js +687 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -0
- package/dist/backend/llvm/lib-stream.d.ts +2 -0
- package/dist/backend/llvm/lib-stream.js +470 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +12 -2
- package/dist/backend/llvm/shapes.js +66 -307
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +52 -0
- package/dist/backend/llvm/shapes.test.js.map +1 -0
- package/dist/backend/llvm/unsupported.d.ts +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -3
- package/dist/backend/llvm/walkers.js +195 -222
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +45 -0
- package/dist/backend/native-codegen.js +275 -0
- package/dist/backend/native-codegen.js.map +1 -0
- package/dist/backend/native-codegen.test.js +226 -0
- package/dist/backend/native-codegen.test.js.map +1 -0
- package/dist/backend/native-link-info.d.ts +96 -0
- package/dist/backend/native-link-info.js +243 -0
- package/dist/backend/native-link-info.js.map +1 -0
- package/dist/backend/native-link-info.test.d.ts +1 -0
- package/dist/backend/native-link-info.test.js +134 -0
- package/dist/backend/native-link-info.test.js.map +1 -0
- package/dist/backend/{cc.d.ts → native-toolchain.d.ts} +54 -34
- package/dist/backend/{cc.js → native-toolchain.js} +231 -810
- package/dist/backend/native-toolchain.js.map +1 -0
- package/dist/backend/native-toolchain.test.d.ts +1 -0
- package/dist/backend/{cc-cache.test.js → native-toolchain.test.js} +219 -7
- package/dist/backend/native-toolchain.test.js.map +1 -0
- package/dist/backend/object-localize.js +1 -1
- package/dist/backend/runtime-abi.d.ts +10 -0
- package/dist/backend/runtime-abi.js +11 -0
- package/dist/backend/runtime-abi.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.d.ts +1 -0
- package/dist/backend/runtime-pack-targets.test.js +54 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -0
- package/dist/backend/runtime-pack.d.ts +112 -0
- package/dist/backend/runtime-pack.js +305 -0
- package/dist/backend/runtime-pack.js.map +1 -0
- package/dist/backend/runtime-pack.test.d.ts +1 -0
- package/dist/backend/runtime-pack.test.js +473 -0
- package/dist/backend/runtime-pack.test.js.map +1 -0
- package/dist/backend/targets.d.ts +76 -0
- package/dist/backend/targets.js +262 -0
- package/dist/backend/targets.js.map +1 -0
- package/dist/backend/targets.test.d.ts +1 -0
- package/dist/backend/targets.test.js +41 -0
- package/dist/backend/targets.test.js.map +1 -0
- package/dist/backend/vendor-archives.d.ts +41 -0
- package/dist/backend/vendor-archives.js +462 -0
- package/dist/backend/vendor-archives.js.map +1 -0
- package/dist/compat/fetch-profile.d.ts +0 -1
- package/dist/compat/fetch-profile.js +0 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/coverage/report.js +3 -3
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +35 -33
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +11 -12
- package/dist/diagnostics/diagnostic.js +19 -17
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/render.d.ts +1 -1
- package/dist/diagnostics/render.js +1 -1
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/executable/{early-cache.d.ts → executable-cache.d.ts} +2 -2
- package/dist/executable/{early-cache.js → executable-cache.js} +36 -98
- package/dist/executable/executable-cache.js.map +1 -0
- package/dist/executable/executable-cache.test.d.ts +1 -0
- package/dist/executable/{early-cache.test.js → executable-cache.test.js} +3 -3
- package/dist/executable/executable-cache.test.js.map +1 -0
- package/dist/ffi/{profile.js → ffi-manifest.js} +1 -1
- package/dist/ffi/ffi-manifest.js.map +1 -0
- package/dist/frontend/builtin-modules.d.ts +21 -0
- package/dist/frontend/builtin-modules.js +82 -0
- package/dist/frontend/builtin-modules.js.map +1 -0
- package/dist/frontend/cjs-lexer.d.ts +7 -0
- package/dist/frontend/cjs-lexer.js +15 -17
- package/dist/frontend/cjs-lexer.js.map +1 -1
- package/dist/frontend/dts-paths.d.ts +26 -0
- package/dist/frontend/dts-paths.js +41 -0
- package/dist/frontend/dts-paths.js.map +1 -0
- package/dist/frontend/input-tracker.d.ts +0 -2
- package/dist/frontend/input-tracker.js +1 -4
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.d.ts +1 -5
- package/dist/frontend/lib-contract.js +1 -1
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.d.ts +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -0
- package/dist/frontend/lowering/array-values.js +60 -0
- package/dist/frontend/lowering/array-values.js.map +1 -0
- package/dist/frontend/lowering/call-position.d.ts +4 -0
- package/dist/frontend/lowering/call-position.js +7 -0
- package/dist/frontend/lowering/call-position.js.map +1 -0
- package/dist/frontend/lowering/callback-arg.d.ts +20 -0
- package/dist/frontend/lowering/callback-arg.js +44 -0
- package/dist/frontend/lowering/callback-arg.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.d.ts +1 -1
- package/dist/frontend/lowering/lib-boundary.js +34 -34
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.d.ts +22 -0
- package/dist/frontend/lowering/lower-array-sort.js +619 -0
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.d.ts +3 -3
- package/dist/frontend/lowering/lower-assert.js +214 -241
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +74 -146
- package/dist/frontend/lowering/lower-builtins.js +1285 -1233
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +59 -192
- package/dist/frontend/lowering/lower-calls.js +1644 -1506
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +62 -125
- package/dist/frontend/lowering/lower-classes.js +832 -866
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +5 -12
- package/dist/frontend/lowering/lower-comptime.js +32 -31
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +35 -135
- package/dist/frontend/lowering/lower-containers.js +1984 -2227
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +3 -7
- package/dist/frontend/lowering/lower-dgram.js +97 -111
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.d.ts +4 -4
- package/dist/frontend/lowering/lower-enums.js +30 -30
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/{lower-emitter.d.ts → lower-event-emitter.d.ts} +7 -18
- package/dist/frontend/lowering/{lower-emitter.js → lower-event-emitter.js} +172 -174
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -0
- package/dist/frontend/lowering/lower-expando.d.ts +5 -5
- package/dist/frontend/lowering/lower-expando.js +40 -40
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +60 -264
- package/dist/frontend/lowering/lower-exprs.js +2361 -1765
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -6
- package/dist/frontend/lowering/lower-generators.js +73 -72
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +5 -17
- package/dist/frontend/lowering/lower-inspect.js +273 -261
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +39 -49
- package/dist/frontend/lowering/lower-island.js +447 -513
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.d.ts +7 -10
- package/dist/frontend/lowering/lower-mixins.js +85 -85
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +12 -18
- package/dist/frontend/lowering/lower-modules.js +284 -283
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +23 -49
- package/dist/frontend/lowering/lower-namespaces.js +123 -115
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +18 -25
- package/dist/frontend/lowering/lower-server.js +909 -899
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +30 -149
- package/dist/frontend/lowering/lower-stmts.js +1463 -1285
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +12 -12
- package/dist/frontend/lowering/lower-stream.js +300 -301
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +5 -5
- package/dist/frontend/lowering/lower-test.js +82 -82
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +134 -22
- package/dist/frontend/lowering/lowerer.js +1277 -126
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.d.ts +11 -0
- package/dist/frontend/lowering/pairs-snapshot.js +85 -0
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -0
- package/dist/frontend/lowering/static-this.d.ts +6 -0
- package/dist/frontend/lowering/static-this.js +24 -0
- package/dist/frontend/lowering/static-this.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +24 -35
- package/dist/frontend/lowering/surfaces.js +78 -66
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-rewrite.js +6 -28
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +0 -10
- package/dist/frontend/npm-static.js +4 -7
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +0 -24
- package/dist/frontend/npm.js +11 -85
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.d.ts +3 -1
- package/dist/frontend/program.js +9 -4
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance-registry.d.ts +0 -2
- package/dist/frontend/provenance-registry.js +0 -10
- package/dist/frontend/provenance-registry.js.map +1 -1
- package/dist/frontend/provenance.js +4 -7
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/resolve.d.ts +7 -2
- package/dist/frontend/resolve.js +12 -17
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.d.ts +1 -0
- package/dist/frontend/resolve.test.js +29 -0
- package/dist/frontend/resolve.test.js.map +1 -0
- package/dist/frontend/ts7/adapter.d.ts +2 -2
- package/dist/frontend/ts7/adapter.js +1 -1
- package/dist/frontend/ts7/adapter.js.map +1 -1
- package/dist/frontend/ts7/checker.js +2 -36
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/enums.js +2 -1
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/{program.js → program-adapter.js} +7 -6
- package/dist/frontend/ts7/program-adapter.js.map +1 -0
- package/dist/frontend/ts7/world-check.d.ts +1 -3
- package/dist/frontend/ts7/world-check.js +3 -1
- package/dist/frontend/ts7/world-check.js.map +1 -1
- package/dist/frontend/tsc-codes.d.ts +8 -0
- package/dist/frontend/tsc-codes.js +109 -0
- package/dist/frontend/tsc-codes.js.map +1 -0
- package/dist/frontend/{types.d.ts → type-mapper.d.ts} +2 -25
- package/dist/frontend/{types.js → type-mapper.js} +12 -11
- package/dist/frontend/type-mapper.js.map +1 -0
- package/dist/frontend/workspace-registry.d.ts +26 -0
- package/dist/frontend/workspace-registry.js +71 -0
- package/dist/frontend/workspace-registry.js.map +1 -0
- package/dist/index.d.ts +113 -31
- package/dist/index.js +536 -128
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +37 -0
- package/dist/ir/analysis.js +118 -0
- package/dist/ir/analysis.js.map +1 -0
- package/dist/ir/analysis.test.d.ts +1 -0
- package/dist/ir/analysis.test.js +21 -0
- package/dist/ir/analysis.test.js.map +1 -0
- package/dist/ir/build.d.ts +9 -0
- package/dist/ir/build.js +33 -0
- package/dist/ir/build.js.map +1 -0
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/{nodes.d.ts → ir.d.ts} +119 -37
- package/dist/ir/{nodes.js → ir.js} +170 -166
- package/dist/ir/ir.js.map +1 -0
- package/dist/ir/ir.test.d.ts +1 -0
- package/dist/ir/ir.test.js +17 -0
- package/dist/ir/ir.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +2 -2
- package/dist/ir/serialize.js +3 -2
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.d.ts +1 -1
- package/dist/ir/validate.js +93 -41
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/cache-primitives.d.ts +24 -0
- package/dist/library/cache-primitives.js +83 -0
- package/dist/library/cache-primitives.js.map +1 -0
- package/dist/library/cache-reset.test.d.ts +1 -0
- package/dist/library/cache-reset.test.js +47 -0
- package/dist/library/cache-reset.test.js.map +1 -0
- package/dist/library/{implementation-identity.js → compiler-self-identity.js} +1 -1
- package/dist/library/compiler-self-identity.js.map +1 -0
- package/dist/library/fence-eval.d.ts +3 -1
- package/dist/library/fence-eval.js +8 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.d.ts +1 -36
- package/dist/library/int-infer.js +29 -18
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/{early-cache.d.ts → library-cache.d.ts} +1 -1
- package/dist/library/{early-cache.js → library-cache.js} +34 -89
- package/dist/library/library-cache.js.map +1 -0
- package/dist/library/library-cache.test.d.ts +1 -0
- package/dist/library/{early-cache.test.js → library-cache.test.js} +7 -7
- package/dist/library/library-cache.test.js.map +1 -0
- package/dist/library/{profile.d.ts → library-profile.d.ts} +4 -7
- package/dist/library/{profile.js → library-profile.js} +18 -11
- package/dist/library/library-profile.js.map +1 -0
- package/dist/library/semantic-source.js +2 -1
- package/dist/library/semantic-source.js.map +1 -1
- package/dist/library/sidecar.d.ts +5 -2
- package/dist/library/sidecar.js +11 -5
- package/dist/library/sidecar.js.map +1 -1
- package/dist/startup-cache.d.ts +11 -3
- package/dist/startup-cache.js +17 -2
- package/dist/startup-cache.js.map +1 -1
- package/package.json +19 -2
- package/surface-manifest.json +5 -5
- package/dist/backend/cc-cache.test.js.map +0 -1
- package/dist/backend/cc.js.map +0 -1
- package/dist/backend/emission/emit-async.js.map +0 -1
- package/dist/backend/emission/emit-exprs.d.ts +0 -13
- package/dist/backend/emission/emit-exprs.js +0 -7407
- package/dist/backend/emission/emit-exprs.js.map +0 -1
- package/dist/backend/emission/emit-island.js.map +0 -1
- package/dist/backend/emission/emit-shapes.js.map +0 -1
- package/dist/backend/emission/emit-stmts.js.map +0 -1
- package/dist/backend/emission/emit-types.js.map +0 -1
- package/dist/backend/emission/emit-walkers.js.map +0 -1
- package/dist/backend/emission/emitter.js.map +0 -1
- package/dist/backend/emission/may-throw.js.map +0 -1
- package/dist/backend/library-identity.js.map +0 -1
- package/dist/executable/early-cache.js.map +0 -1
- package/dist/executable/early-cache.test.js.map +0 -1
- package/dist/ffi/profile.js.map +0 -1
- package/dist/frontend/lowering/lower-emitter.js.map +0 -1
- package/dist/frontend/shared.d.ts +0 -82
- package/dist/frontend/shared.js +0 -308
- package/dist/frontend/shared.js.map +0 -1
- package/dist/frontend/ts7/program.js.map +0 -1
- package/dist/frontend/types.js.map +0 -1
- package/dist/ir/nodes.js.map +0 -1
- package/dist/library/early-cache.js.map +0 -1
- package/dist/library/early-cache.test.js.map +0 -1
- package/dist/library/implementation-identity.js.map +0 -1
- package/dist/library/profile.js.map +0 -1
- /package/dist/backend/{cc-cache.test.d.ts → c/types.test.d.ts} +0 -0
- /package/dist/{executable/early-cache.test.d.ts → backend/llvm/shapes.test.d.ts} +0 -0
- /package/dist/{library/early-cache.test.d.ts → backend/native-codegen.test.d.ts} +0 -0
- /package/dist/ffi/{profile.d.ts → ffi-manifest.d.ts} +0 -0
- /package/dist/frontend/ts7/{program.d.ts → program-adapter.d.ts} +0 -0
- /package/dist/library/{implementation-identity.d.ts → compiler-self-identity.d.ts} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { InternalCompilerError } from "../../errors.js";
|
|
1
2
|
/* The node:util inspect/format lowering (a spoke module like
|
|
2
3
|
* lower-assert.ts): STATIC util.inspect — one synthesized traversal
|
|
3
4
|
* helper per argument type (the deepStrictEqual precedent, interned per
|
|
@@ -35,15 +36,13 @@
|
|
|
35
36
|
* 36's existing stance). */
|
|
36
37
|
import * as ts from "../ts7/adapter.js";
|
|
37
38
|
import { isJsSourceFile } from "../program.js";
|
|
38
|
-
import { BOOL, DYN, F64, RUNTIME_ERROR_CLASSES, STRING, canConvertToDyn, canDynCheckTo, shapeHasAccessorSlots, typeKey } from "../../ir/
|
|
39
|
+
import { BOOL, DYN, F64, RUNTIME_ERROR_CLASSES, STRING, canConvertToDyn, canDynCheckTo, shapeHasAccessorSlots, typeKey } from "../../ir/ir.js";
|
|
39
40
|
import { pureReemittable } from "./lower-exprs.js";
|
|
41
|
+
import { boolLit, numLit, strLit, varRef } from "../../ir/build.js";
|
|
40
42
|
/* ── IR construction shorthand ───────────────────────────────────────── */
|
|
41
|
-
const str = (value, loc) => ({ kind: "strLit", value, type: STRING, loc });
|
|
42
|
-
const num = (value, loc) => ({ kind: "numLit", value, type: F64, loc });
|
|
43
|
-
const boolLit = (value, loc) => ({ kind: "boolLit", value, type: BOOL, loc });
|
|
44
43
|
function concatAll(parts, loc) {
|
|
45
44
|
if (parts.length === 0)
|
|
46
|
-
return
|
|
45
|
+
return strLit("", loc);
|
|
47
46
|
let out = parts[0];
|
|
48
47
|
for (let i = 1; i < parts.length; i++) {
|
|
49
48
|
out = { kind: "strConcat", left: out, right: parts[i], type: STRING, loc };
|
|
@@ -54,7 +53,7 @@ function concatAll(parts, loc) {
|
|
|
54
53
|
/** strEscape's quote ladder over a COMPILE-TIME string (record field
|
|
55
54
|
* names, format-string chunks never pass through here — only keys).
|
|
56
55
|
* Mirrors scr_inspect.c's insp_quote_into byte-for-byte. */
|
|
57
|
-
|
|
56
|
+
function inspectQuote(s) {
|
|
58
57
|
const hasSingle = s.includes("'");
|
|
59
58
|
const quote = !hasSingle ? "'" : !s.includes('"') ? '"' : !s.includes("`") && !s.includes("${") ? "`" : "'";
|
|
60
59
|
let body = "";
|
|
@@ -111,15 +110,15 @@ function errorRenderable(info) {
|
|
|
111
110
|
return false;
|
|
112
111
|
return info.subclasses.every((s) => errorRenderable(s));
|
|
113
112
|
}
|
|
114
|
-
function isErrorClass(
|
|
113
|
+
function isErrorClass(lowerer, className) {
|
|
115
114
|
if (RUNTIME_ERROR_CLASSES.has(className))
|
|
116
115
|
return true;
|
|
117
|
-
return
|
|
116
|
+
return lowerer.isSubclassOf(className, "%Error");
|
|
118
117
|
}
|
|
119
118
|
/** inspUnsupportedReason: the deepUnsupportedReason twin. Fences name the
|
|
120
119
|
* FIRST unsupported constituent. `visiting` terminates recursive shapes
|
|
121
120
|
* and records their existence (the depth-null gate). */
|
|
122
|
-
function inspectSupport(
|
|
121
|
+
function inspectSupport(lowerer, t, visiting, out) {
|
|
123
122
|
switch (t.kind) {
|
|
124
123
|
case "f64":
|
|
125
124
|
case "string":
|
|
@@ -132,7 +131,7 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
132
131
|
case "jsval":
|
|
133
132
|
return null;
|
|
134
133
|
case "array":
|
|
135
|
-
return inspectSupport(
|
|
134
|
+
return inspectSupport(lowerer, t.elem, visiting, out);
|
|
136
135
|
case "bytes":
|
|
137
136
|
return "typed arrays inside composites have no inspect lowering yet (Buffer's <Buffer ..> form vs Uint8Array's is not recorded in the static type here)";
|
|
138
137
|
case "record": {
|
|
@@ -141,7 +140,7 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
141
140
|
return null;
|
|
142
141
|
}
|
|
143
142
|
visiting.add(t.shapeId);
|
|
144
|
-
const shape =
|
|
143
|
+
const shape = lowerer.shapes.get(t.shapeId);
|
|
145
144
|
if (!shape)
|
|
146
145
|
return "this record shape has no inspect lowering";
|
|
147
146
|
// Accessor-carrying shapes: Node prints the accessor names as
|
|
@@ -161,14 +160,14 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
161
160
|
if (shape.fields.length > 0) {
|
|
162
161
|
return "index-signature records with declared fields have no inspect lowering yet (JS interleaves integer keys across the declared and dynamic key sets)";
|
|
163
162
|
}
|
|
164
|
-
const why = inspectSupport(
|
|
163
|
+
const why = inspectSupport(lowerer, shape.indexValue, visiting, out);
|
|
165
164
|
if (why !== null)
|
|
166
165
|
return why;
|
|
167
166
|
visiting.delete(t.shapeId);
|
|
168
167
|
return null;
|
|
169
168
|
}
|
|
170
169
|
for (const f of shape.fields) {
|
|
171
|
-
const why = inspectSupport(
|
|
170
|
+
const why = inspectSupport(lowerer, f.type, visiting, out);
|
|
172
171
|
if (why !== null)
|
|
173
172
|
return why;
|
|
174
173
|
}
|
|
@@ -176,15 +175,15 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
176
175
|
return null;
|
|
177
176
|
}
|
|
178
177
|
case "map": {
|
|
179
|
-
const keyWhy = inspectSupport(
|
|
178
|
+
const keyWhy = inspectSupport(lowerer, t.key, visiting, out);
|
|
180
179
|
if (keyWhy !== null)
|
|
181
180
|
return keyWhy;
|
|
182
|
-
return inspectSupport(
|
|
181
|
+
return inspectSupport(lowerer, t.value, visiting, out);
|
|
183
182
|
}
|
|
184
183
|
case "set":
|
|
185
|
-
return inspectSupport(
|
|
184
|
+
return inspectSupport(lowerer, t.elem, visiting, out);
|
|
186
185
|
case "union": {
|
|
187
|
-
const def =
|
|
186
|
+
const def = lowerer.unions.get(t.unionId);
|
|
188
187
|
if (!def)
|
|
189
188
|
return "this union has no inspect lowering";
|
|
190
189
|
if (visiting.has(t.unionId)) {
|
|
@@ -193,7 +192,7 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
193
192
|
}
|
|
194
193
|
visiting.add(t.unionId);
|
|
195
194
|
for (const arm of def.arms) {
|
|
196
|
-
const why = inspectSupport(
|
|
195
|
+
const why = inspectSupport(lowerer, arm, visiting, out);
|
|
197
196
|
if (why !== null)
|
|
198
197
|
return why;
|
|
199
198
|
}
|
|
@@ -203,10 +202,10 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
203
202
|
case "func":
|
|
204
203
|
return "function values have no inspect lowering (no runtime name exists — Node prints '[Function: name]'; pass the function's declared identifier directly to util.inspect for the baked form)";
|
|
205
204
|
case "object": {
|
|
206
|
-
const info =
|
|
205
|
+
const info = lowerer.classes.get(t.className);
|
|
207
206
|
if (!info)
|
|
208
207
|
return `class '${t.className}' has no inspect lowering`;
|
|
209
|
-
if (isErrorClass(
|
|
208
|
+
if (isErrorClass(lowerer, t.className)) {
|
|
210
209
|
return errorRenderable(info)
|
|
211
210
|
? null
|
|
212
211
|
: "error subclasses with declared fields have no inspect lowering yet (the extra own properties are runtime-dynamic)";
|
|
@@ -224,7 +223,7 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
224
223
|
for (const f of info.def.fields) {
|
|
225
224
|
if (f.name.startsWith("#"))
|
|
226
225
|
continue;
|
|
227
|
-
const why = inspectSupport(
|
|
226
|
+
const why = inspectSupport(lowerer, f.type, visiting, out);
|
|
228
227
|
if (why !== null)
|
|
229
228
|
return why;
|
|
230
229
|
}
|
|
@@ -232,17 +231,17 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
232
231
|
return null;
|
|
233
232
|
}
|
|
234
233
|
default:
|
|
235
|
-
return `'${
|
|
234
|
+
return `'${lowerer.fmt(t)}' values have no inspect lowering`;
|
|
236
235
|
}
|
|
237
236
|
}
|
|
238
237
|
/* ── the per-type rendering expression ───────────────────────────────── */
|
|
239
238
|
/** True when a runtime value of `t` at index expr `v` answers
|
|
240
239
|
* `typeof v === 'number'` — the grid-grouping order flag. */
|
|
241
|
-
function isNumberFlag(
|
|
240
|
+
function isNumberFlag(lowerer, t, v, loc) {
|
|
242
241
|
if (t.kind === "f64")
|
|
243
242
|
return boolLit(true, loc);
|
|
244
243
|
if (t.kind === "union") {
|
|
245
|
-
const def =
|
|
244
|
+
const def = lowerer.unions.get(t.unionId);
|
|
246
245
|
const tag = def ? def.arms.findIndex((a) => a.kind === "f64") : -1;
|
|
247
246
|
if (tag >= 0) {
|
|
248
247
|
return { kind: "unionIsTag", unionId: t.unionId, tag, negated: false, value: v(), type: BOOL, loc };
|
|
@@ -253,7 +252,7 @@ function isNumberFlag(L, t, v, loc) {
|
|
|
253
252
|
/** The rendering of one value of type `t` at runtime depth `recurse`
|
|
254
253
|
* with the depth budget `depth` — a direct scalar libCall or a call of
|
|
255
254
|
* the interned per-type helper. */
|
|
256
|
-
function inspectExpr(
|
|
255
|
+
function inspectExpr(lowerer, t, value, recurse, depth, loc) {
|
|
257
256
|
switch (t.kind) {
|
|
258
257
|
case "f64":
|
|
259
258
|
return { kind: "libCall", fn: "insp.f64", args: [value], type: STRING, loc };
|
|
@@ -262,9 +261,9 @@ function inspectExpr(L, t, value, recurse, depth, loc) {
|
|
|
262
261
|
case "bool":
|
|
263
262
|
return { kind: "toString", operand: value, type: STRING, loc };
|
|
264
263
|
case "undefinedT":
|
|
265
|
-
return
|
|
264
|
+
return strLit("undefined", loc);
|
|
266
265
|
case "nullT":
|
|
267
|
-
return
|
|
266
|
+
return strLit("null", loc);
|
|
268
267
|
case "regex":
|
|
269
268
|
return { kind: "libCall", fn: "insp.regex", args: [value], type: STRING, loc };
|
|
270
269
|
case "symbol":
|
|
@@ -278,12 +277,12 @@ function inspectExpr(L, t, value, recurse, depth, loc) {
|
|
|
278
277
|
case "jsval":
|
|
279
278
|
return { kind: "libCall", fn: "insp.jsval", args: [value, recurse, depth], type: STRING, loc };
|
|
280
279
|
case "object":
|
|
281
|
-
if (isErrorClass(
|
|
280
|
+
if (isErrorClass(lowerer, t.className)) {
|
|
282
281
|
return { kind: "libCall", fn: "insp.error", args: [value, recurse, depth], type: STRING, loc };
|
|
283
282
|
}
|
|
284
|
-
return { kind: "call", callee: inspectHelper(
|
|
283
|
+
return { kind: "call", callee: inspectHelper(lowerer, t, loc), args: [value, recurse, depth], type: STRING, loc };
|
|
285
284
|
default:
|
|
286
|
-
return { kind: "call", callee: inspectHelper(
|
|
285
|
+
return { kind: "call", callee: inspectHelper(lowerer, t, loc), args: [value, recurse, depth], type: STRING, loc };
|
|
287
286
|
}
|
|
288
287
|
}
|
|
289
288
|
/** True when a VALUE of `t` can contain itself — t's type graph reaches t
|
|
@@ -292,14 +291,14 @@ function inspectExpr(L, t, value, recurse, depth, loc) {
|
|
|
292
291
|
* helpers over such types run Node's circular machinery (seen stack +
|
|
293
292
|
* <ref *N>/[Circular *N]); everything acyclic keeps the zero-cost path
|
|
294
293
|
* (a value of an acyclic type can never repeat on its own path). */
|
|
295
|
-
export function typeReachesItself(
|
|
294
|
+
export function typeReachesItself(lowerer, t) {
|
|
296
295
|
const root = typeKey(t);
|
|
297
296
|
const seen = new Set();
|
|
298
297
|
const walk = (u) => {
|
|
299
298
|
const constituents = [];
|
|
300
299
|
switch (u.kind) {
|
|
301
300
|
case "record": {
|
|
302
|
-
const shape =
|
|
301
|
+
const shape = lowerer.shapes.get(u.shapeId);
|
|
303
302
|
if (!shape)
|
|
304
303
|
return false;
|
|
305
304
|
constituents.push(...shape.fields.map((f) => f.type));
|
|
@@ -315,13 +314,13 @@ export function typeReachesItself(L, t) {
|
|
|
315
314
|
constituents.push(u.key, u.value);
|
|
316
315
|
break;
|
|
317
316
|
case "union": {
|
|
318
|
-
const def =
|
|
317
|
+
const def = lowerer.unions.get(u.unionId);
|
|
319
318
|
if (def)
|
|
320
319
|
constituents.push(...def.arms);
|
|
321
320
|
break;
|
|
322
321
|
}
|
|
323
322
|
case "object": {
|
|
324
|
-
const info =
|
|
323
|
+
const info = lowerer.classes.get(u.className);
|
|
325
324
|
if (info)
|
|
326
325
|
constituents.push(...info.def.fields.map((f) => f.type));
|
|
327
326
|
break;
|
|
@@ -350,18 +349,17 @@ export function typeReachesItself(L, t) {
|
|
|
350
349
|
* `[Set]`/`[ClassName]`, and non-empty composites drive the runtime
|
|
351
350
|
* frame engine (begin / entry / end). Registered in the cache BEFORE the
|
|
352
351
|
* body builds, so recursive shapes call themselves by name. */
|
|
353
|
-
function inspectHelper(
|
|
352
|
+
function inspectHelper(lowerer, t, loc) {
|
|
354
353
|
const key = `insp:${typeKey(t)}`;
|
|
355
|
-
const existing =
|
|
354
|
+
const existing = lowerer.inspectHelpers.get(key);
|
|
356
355
|
if (existing)
|
|
357
356
|
return existing;
|
|
358
|
-
const name = `%util.insp.${
|
|
359
|
-
|
|
360
|
-
const
|
|
361
|
-
const
|
|
362
|
-
const
|
|
363
|
-
const
|
|
364
|
-
const rPlus1 = () => ({ kind: "bin", op: "+", left: r(), right: num(1, loc), type: F64, loc });
|
|
357
|
+
const name = `%util.insp.${lowerer.inspectHelpers.size}`;
|
|
358
|
+
lowerer.inspectHelpers.set(key, name);
|
|
359
|
+
const v = () => varRef("v.0", t, loc);
|
|
360
|
+
const r = () => varRef("r.0", F64, loc);
|
|
361
|
+
const d = () => varRef("d.0", F64, loc);
|
|
362
|
+
const rPlus1 = () => ({ kind: "bin", op: "+", left: r(), right: numLit(1, loc), type: F64, loc });
|
|
365
363
|
const ret = (value) => ({ kind: "return", value, loc });
|
|
366
364
|
const exprStmt = (expr) => ({ kind: "exprStmt", expr, loc });
|
|
367
365
|
// CYCLE-CAPABLE composites (typeReachesItself) run Node's circular
|
|
@@ -371,7 +369,7 @@ function inspectHelper(L, t, loc) {
|
|
|
371
369
|
// <ref *N> prefix on values the walk found circular). Acyclic types
|
|
372
370
|
// keep the zero-cost path.
|
|
373
371
|
const onCycle = (t.kind === "record" || t.kind === "array" || t.kind === "map" || t.kind === "object") &&
|
|
374
|
-
typeReachesItself(
|
|
372
|
+
typeReachesItself(lowerer, t);
|
|
375
373
|
const begin = () => [
|
|
376
374
|
exprStmt({ kind: "libCall", fn: "insp.begin", args: [rPlus1()], type: { kind: "void" }, loc }),
|
|
377
375
|
...(onCycle
|
|
@@ -395,11 +393,11 @@ function inspectHelper(L, t, loc) {
|
|
|
395
393
|
const depthGate = (placeholder) => ({
|
|
396
394
|
kind: "if",
|
|
397
395
|
cond: { kind: "bin", op: ">", left: r(), right: d(), type: BOOL, loc },
|
|
398
|
-
then: [ret(
|
|
396
|
+
then: [ret(strLit(placeholder, loc))],
|
|
399
397
|
else_: null,
|
|
400
398
|
loc,
|
|
401
399
|
});
|
|
402
|
-
const child = (elemT, value) => inspectExpr(
|
|
400
|
+
const child = (elemT, value) => inspectExpr(lowerer, elemT, value, rPlus1(), d(), loc);
|
|
403
401
|
const locals = [
|
|
404
402
|
{ id: "v.0", name: "v", type: t, mutable: false },
|
|
405
403
|
{ id: "r.0", name: "r", type: F64, mutable: false },
|
|
@@ -409,68 +407,82 @@ function inspectHelper(L, t, loc) {
|
|
|
409
407
|
let rebuildShapeOrderBody = null;
|
|
410
408
|
switch (t.kind) {
|
|
411
409
|
case "array": {
|
|
412
|
-
const
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
const
|
|
416
|
-
const
|
|
417
|
-
const
|
|
418
|
-
|
|
410
|
+
const at = (index) => ({ kind: "arrayGet", arr: v(), index, type: t.elem, loc });
|
|
411
|
+
const state = (index) => ({ kind: "arrayState", arr: v(), index, type: F64, loc });
|
|
412
|
+
const eq = (left, right) => ({ kind: "bin", op: "===", left, right, type: BOOL, loc });
|
|
413
|
+
const lt = (left, right) => ({ kind: "bin", op: "<", left, right, type: BOOL, loc });
|
|
414
|
+
const add = (left, right) => ({ kind: "bin", op: "+", left, right, type: F64, loc });
|
|
415
|
+
const sub = (left, right) => ({ kind: "bin", op: "-", left, right, type: F64, loc });
|
|
416
|
+
locals.push({ id: "n.0", name: "n", type: F64, mutable: false }, { id: "s.0", name: "s", type: F64, mutable: true }, { id: "i.0", name: "i", type: F64, mutable: true }, { id: "next.0", name: "next", type: F64, mutable: false });
|
|
417
|
+
const n = () => varRef("n.0", F64, loc);
|
|
418
|
+
const shown = () => varRef("s.0", F64, loc);
|
|
419
|
+
const i = () => varRef("i.0", F64, loc);
|
|
420
|
+
const next = () => varRef("next.0", F64, loc);
|
|
421
|
+
const hasMore = () => lt(i(), n());
|
|
422
|
+
const isNumber = () => ({
|
|
423
|
+
kind: "ternary", cond: eq(state(i()), numLit(1, loc)),
|
|
424
|
+
then: isNumberFlag(lowerer, t.elem, () => at(i()), loc),
|
|
425
|
+
else_: boolLit(false, loc), type: BOOL, loc,
|
|
426
|
+
});
|
|
427
|
+
const holes = () => ({
|
|
428
|
+
kind: "strConcat", left: strLit("<", loc),
|
|
429
|
+
right: {
|
|
430
|
+
kind: "strConcat", left: { kind: "toString", operand: sub(next(), i()), type: STRING, loc },
|
|
431
|
+
right: { kind: "ternary", cond: eq(sub(next(), i()), numLit(1, loc)), then: strLit(" empty item>", loc), else_: strLit(" empty items>", loc), type: STRING, loc },
|
|
432
|
+
type: STRING, loc,
|
|
433
|
+
}, type: STRING, loc,
|
|
434
|
+
});
|
|
419
435
|
body = [
|
|
420
|
-
{ kind: "varDecl", localId: "n.0", init:
|
|
421
|
-
{
|
|
422
|
-
kind: "if",
|
|
423
|
-
cond: { kind: "bin", op: "===", left: n(), right: num(0, loc), type: BOOL, loc },
|
|
424
|
-
then: [ret(str("[]", loc))],
|
|
425
|
-
else_: null,
|
|
426
|
-
loc,
|
|
427
|
-
},
|
|
436
|
+
{ kind: "varDecl", localId: "n.0", init: { kind: "arrIntrinsic", method: "length", receiver: v(), args: [], type: F64, loc }, loc },
|
|
437
|
+
{ kind: "if", cond: eq(n(), numLit(0, loc)), then: [ret(strLit("[]", loc))], else_: null, loc },
|
|
428
438
|
depthGate("[Array]"),
|
|
429
|
-
{ kind: "varDecl", localId: "s.0", init:
|
|
439
|
+
{ kind: "varDecl", localId: "s.0", init: numLit(0, loc), loc },
|
|
440
|
+
{ kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
|
|
430
441
|
...begin(),
|
|
431
442
|
{
|
|
432
|
-
kind: "
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
443
|
+
kind: "while",
|
|
444
|
+
cond: { kind: "logical", op: "&&", left: hasMore(), right: lt(shown(), numLit(100, loc)), type: BOOL, loc },
|
|
445
|
+
body: [
|
|
446
|
+
{
|
|
447
|
+
kind: "if", cond: eq(state(i()), numLit(0, loc)),
|
|
448
|
+
then: [
|
|
449
|
+
{ kind: "varDecl", localId: "next.0", init: { kind: "arrIntrinsic", method: "nextPresent", receiver: v(), args: [i()], type: F64, loc }, loc },
|
|
450
|
+
entry(holes(), boolLit(false, loc)),
|
|
451
|
+
{ kind: "assign", localId: "i.0", value: next(), loc },
|
|
452
|
+
],
|
|
453
|
+
else_: [
|
|
454
|
+
entry({ kind: "ternary", cond: eq(state(i()), numLit(1, loc)), then: child(t.elem, at(i())), else_: strLit("undefined", loc), type: STRING, loc }, isNumber()),
|
|
455
|
+
{ kind: "assign", localId: "i.0", value: add(i(), numLit(1, loc)), loc },
|
|
456
|
+
], loc,
|
|
457
|
+
},
|
|
458
|
+
{ kind: "assign", localId: "s.0", value: add(shown(), numLit(1, loc)), loc },
|
|
459
|
+
], loc,
|
|
438
460
|
},
|
|
439
461
|
{
|
|
440
|
-
kind: "if",
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
entry({
|
|
444
|
-
kind: "libCall",
|
|
445
|
-
fn: "insp.moreItems",
|
|
446
|
-
args: [{ kind: "bin", op: "-", left: n(), right: num(100, loc), type: F64, loc }],
|
|
447
|
-
type: STRING,
|
|
448
|
-
loc,
|
|
449
|
-
}, isNumberFlag(L, t.elem, () => at(num(100, loc)), loc)),
|
|
450
|
-
],
|
|
451
|
-
else_: null,
|
|
452
|
-
loc,
|
|
462
|
+
kind: "if", cond: hasMore(),
|
|
463
|
+
then: [entry({ kind: "libCall", fn: "insp.moreItems", args: [sub(n(), i())], type: STRING, loc }, isNumber())],
|
|
464
|
+
else_: null, loc,
|
|
453
465
|
},
|
|
454
|
-
ret(end(
|
|
466
|
+
ret(end(strLit("", loc), strLit("[", loc), strLit("]", loc), true, hasMore())),
|
|
455
467
|
];
|
|
456
468
|
break;
|
|
457
469
|
}
|
|
458
470
|
case "record": {
|
|
459
|
-
const shape =
|
|
471
|
+
const shape = lowerer.shapes.get(t.shapeId);
|
|
460
472
|
if (!shape)
|
|
461
|
-
throw new
|
|
473
|
+
throw new InternalCompilerError(`inspect of unknown shape ${t.shapeId}`);
|
|
462
474
|
const get = (field, type) => ({ kind: "recordGet", obj: v(), shapeId: t.shapeId, field, type, loc });
|
|
463
475
|
if (shape.tuple) {
|
|
464
476
|
// Tuples ARE arrays to Node: bracket form, array-extras grouping.
|
|
465
477
|
if (shape.fields.length === 0) {
|
|
466
|
-
body = [ret(
|
|
478
|
+
body = [ret(strLit("[]", loc))];
|
|
467
479
|
break;
|
|
468
480
|
}
|
|
469
481
|
body = [depthGate("[Array]"), ...begin()];
|
|
470
482
|
for (const f of shape.fields) {
|
|
471
|
-
body.push(entry(child(f.type, get(f.name, f.type)), isNumberFlag(
|
|
483
|
+
body.push(entry(child(f.type, get(f.name, f.type)), isNumberFlag(lowerer, f.type, () => get(f.name, f.type), loc)));
|
|
472
484
|
}
|
|
473
|
-
body.push(ret(end(
|
|
485
|
+
body.push(ret(end(strLit("", loc), strLit("[", loc), strLit("]", loc), true, boolLit(false, loc))));
|
|
474
486
|
break;
|
|
475
487
|
}
|
|
476
488
|
if (shape.indexValue && shape.fields.length === 0) {
|
|
@@ -483,18 +495,18 @@ function inspectHelper(L, t, loc) {
|
|
|
483
495
|
const iv = shape.indexValue;
|
|
484
496
|
const ksT = { kind: "array", elem: STRING };
|
|
485
497
|
locals.push({ id: "ks.0", name: "ks", type: ksT, mutable: false }, { id: "n.0", name: "n", type: F64, mutable: false }, { id: "i.0", name: "i", type: F64, mutable: true }, { id: "k.0", name: "k", type: STRING, mutable: false });
|
|
486
|
-
const ks = () =>
|
|
487
|
-
const n = () =>
|
|
488
|
-
const i = () =>
|
|
489
|
-
const k = () =>
|
|
498
|
+
const ks = () => varRef("ks.0", ksT, loc);
|
|
499
|
+
const n = () => varRef("n.0", F64, loc);
|
|
500
|
+
const i = () => varRef("i.0", F64, loc);
|
|
501
|
+
const k = () => varRef("k.0", STRING, loc);
|
|
490
502
|
const keyedRead = () => ({ kind: "recordKeyGet", obj: v(), shapeId: t.shapeId, key: k(), overflowOnly: true, type: iv, loc });
|
|
491
503
|
body = [
|
|
492
504
|
{ kind: "varDecl", localId: "ks.0", init: { kind: "recordOvfKeys", obj: v(), shapeId: t.shapeId, type: ksT, loc }, loc },
|
|
493
505
|
{ kind: "varDecl", localId: "n.0", init: { kind: "arrIntrinsic", method: "length", receiver: ks(), args: [], type: F64, loc }, loc },
|
|
494
506
|
{
|
|
495
507
|
kind: "if",
|
|
496
|
-
cond: { kind: "bin", op: "===", left: n(), right:
|
|
497
|
-
then: [ret(
|
|
508
|
+
cond: { kind: "bin", op: "===", left: n(), right: numLit(0, loc), type: BOOL, loc },
|
|
509
|
+
then: [ret(strLit("{}", loc))],
|
|
498
510
|
else_: null,
|
|
499
511
|
loc,
|
|
500
512
|
},
|
|
@@ -502,32 +514,32 @@ function inspectHelper(L, t, loc) {
|
|
|
502
514
|
...begin(),
|
|
503
515
|
{
|
|
504
516
|
kind: "for",
|
|
505
|
-
init: { kind: "varDecl", localId: "i.0", init:
|
|
517
|
+
init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
|
|
506
518
|
cond: { kind: "bin", op: "<", left: i(), right: n(), type: BOOL, loc },
|
|
507
|
-
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right:
|
|
519
|
+
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right: numLit(1, loc), type: F64, loc }, loc },
|
|
508
520
|
body: [
|
|
509
521
|
{ kind: "varDecl", localId: "k.0", init: { kind: "arrayGet", arr: ks(), index: i(), type: STRING, loc }, loc },
|
|
510
522
|
entry(concatAll([
|
|
511
523
|
{ kind: "libCall", fn: "insp.key", args: [k()], type: STRING, loc },
|
|
512
|
-
|
|
524
|
+
strLit(": ", loc),
|
|
513
525
|
child(iv, keyedRead()),
|
|
514
526
|
], loc), boolLit(false, loc)),
|
|
515
527
|
],
|
|
516
528
|
loc,
|
|
517
529
|
},
|
|
518
|
-
ret(end(
|
|
530
|
+
ret(end(strLit("", loc), strLit("{", loc), strLit("}", loc), false, boolLit(false, loc))),
|
|
519
531
|
];
|
|
520
532
|
break;
|
|
521
533
|
}
|
|
522
534
|
if (shape.fields.length === 0) {
|
|
523
|
-
body = [ret(
|
|
535
|
+
body = [ret(strLit("{}", loc))];
|
|
524
536
|
break;
|
|
525
537
|
}
|
|
526
538
|
// Object.keys' declared order (SEMANTICS.md 36's stance). Retained
|
|
527
539
|
// reachability can settle this shape after the helper is first
|
|
528
540
|
// interned, so rebuild the field walk once metadata is final.
|
|
529
541
|
rebuildShapeOrderBody = () => {
|
|
530
|
-
const current =
|
|
542
|
+
const current = lowerer.shapes.get(t.shapeId) ?? shape;
|
|
531
543
|
const order = current.declaredOrder ?? current.fields.map((f) => f.name);
|
|
532
544
|
const byName = new Map(current.fields.map((f) => [f.name, f.type]));
|
|
533
545
|
body = [depthGate("[Object]"), ...begin()];
|
|
@@ -535,9 +547,9 @@ function inspectHelper(L, t, loc) {
|
|
|
535
547
|
const ft = byName.get(fname);
|
|
536
548
|
if (!ft)
|
|
537
549
|
continue;
|
|
538
|
-
body.push(entry(concatAll([
|
|
550
|
+
body.push(entry(concatAll([strLit(`${inspectKey(fname)}: `, loc), child(ft, get(fname, ft))], loc), boolLit(false, loc)));
|
|
539
551
|
}
|
|
540
|
-
body.push(ret(end(
|
|
552
|
+
body.push(ret(end(strLit("", loc), strLit("{", loc), strLit("}", loc), false, boolLit(false, loc))));
|
|
541
553
|
};
|
|
542
554
|
rebuildShapeOrderBody();
|
|
543
555
|
break;
|
|
@@ -549,36 +561,36 @@ function inspectHelper(L, t, loc) {
|
|
|
549
561
|
? { kind: "mapIntrinsic", method: method, receiver: v(), args, type, loc }
|
|
550
562
|
: { kind: "setIntrinsic", method: method, receiver: v(), args, type, loc };
|
|
551
563
|
locals.push({ id: "n.0", name: "n", type: F64, mutable: false }, { id: "i.0", name: "i", type: F64, mutable: true }, { id: "c.0", name: "c", type: F64, mutable: true });
|
|
552
|
-
const n = () =>
|
|
553
|
-
const i = () =>
|
|
554
|
-
const c = () =>
|
|
564
|
+
const n = () => varRef("n.0", F64, loc);
|
|
565
|
+
const i = () => varRef("i.0", F64, loc);
|
|
566
|
+
const c = () => varRef("c.0", F64, loc);
|
|
555
567
|
const label = isMap ? "Map" : "Set";
|
|
556
568
|
const keyT = isMap ? t.key : t.elem;
|
|
557
|
-
const hasMore = () => ({ kind: "bin", op: ">", left: n(), right:
|
|
569
|
+
const hasMore = () => ({ kind: "bin", op: ">", left: n(), right: numLit(100, loc), type: BOOL, loc });
|
|
558
570
|
const entryValue = () => {
|
|
559
571
|
const k = child(keyT, mi("iterKey", [i()], keyT));
|
|
560
572
|
if (!isMap)
|
|
561
573
|
return k;
|
|
562
574
|
const valueT = t.value;
|
|
563
|
-
return concatAll([k,
|
|
575
|
+
return concatAll([k, strLit(" => ", loc), child(valueT, mi("iterValue", [i()], valueT))], loc);
|
|
564
576
|
};
|
|
565
577
|
body = [
|
|
566
578
|
{ kind: "varDecl", localId: "n.0", init: mi("size", [], F64), loc },
|
|
567
579
|
{
|
|
568
580
|
kind: "if",
|
|
569
|
-
cond: { kind: "bin", op: "===", left: n(), right:
|
|
570
|
-
then: [ret(
|
|
581
|
+
cond: { kind: "bin", op: "===", left: n(), right: numLit(0, loc), type: BOOL, loc },
|
|
582
|
+
then: [ret(strLit(`${label}(0) {}`, loc))],
|
|
571
583
|
else_: null,
|
|
572
584
|
loc,
|
|
573
585
|
},
|
|
574
586
|
depthGate(`[${label}]`),
|
|
575
587
|
...begin(),
|
|
576
|
-
{ kind: "varDecl", localId: "c.0", init:
|
|
588
|
+
{ kind: "varDecl", localId: "c.0", init: numLit(0, loc), loc },
|
|
577
589
|
{
|
|
578
590
|
kind: "for",
|
|
579
|
-
init: { kind: "varDecl", localId: "i.0", init:
|
|
591
|
+
init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
|
|
580
592
|
cond: { kind: "bin", op: "<", left: i(), right: mi("iterCount", [], F64), type: BOOL, loc },
|
|
581
|
-
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right:
|
|
593
|
+
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right: numLit(1, loc), type: F64, loc }, loc },
|
|
582
594
|
body: [
|
|
583
595
|
{
|
|
584
596
|
kind: "if",
|
|
@@ -589,13 +601,13 @@ function inspectHelper(L, t, loc) {
|
|
|
589
601
|
},
|
|
590
602
|
{
|
|
591
603
|
kind: "if",
|
|
592
|
-
cond: { kind: "bin", op: "===", left: c(), right:
|
|
604
|
+
cond: { kind: "bin", op: "===", left: c(), right: numLit(100, loc), type: BOOL, loc },
|
|
593
605
|
then: [{ kind: "break", loc }],
|
|
594
606
|
else_: null,
|
|
595
607
|
loc,
|
|
596
608
|
},
|
|
597
609
|
entry(entryValue(), boolLit(false, loc)),
|
|
598
|
-
{ kind: "assign", localId: "c.0", value: { kind: "bin", op: "+", left: c(), right:
|
|
610
|
+
{ kind: "assign", localId: "c.0", value: { kind: "bin", op: "+", left: c(), right: numLit(1, loc), type: F64, loc }, loc },
|
|
599
611
|
],
|
|
600
612
|
loc,
|
|
601
613
|
},
|
|
@@ -606,7 +618,7 @@ function inspectHelper(L, t, loc) {
|
|
|
606
618
|
entry({
|
|
607
619
|
kind: "libCall",
|
|
608
620
|
fn: "insp.moreItems",
|
|
609
|
-
args: [{ kind: "bin", op: "-", left: n(), right:
|
|
621
|
+
args: [{ kind: "bin", op: "-", left: n(), right: numLit(100, loc), type: F64, loc }],
|
|
610
622
|
type: STRING,
|
|
611
623
|
loc,
|
|
612
624
|
}, boolLit(false, loc)),
|
|
@@ -614,14 +626,14 @@ function inspectHelper(L, t, loc) {
|
|
|
614
626
|
else_: null,
|
|
615
627
|
loc,
|
|
616
628
|
},
|
|
617
|
-
ret(end(
|
|
629
|
+
ret(end(strLit("", loc), concatAll([strLit(`${label}(`, loc), { kind: "toString", operand: n(), type: STRING, loc }, strLit(") {", loc)], loc), strLit("}", loc), false, hasMore())),
|
|
618
630
|
];
|
|
619
631
|
break;
|
|
620
632
|
}
|
|
621
633
|
case "union": {
|
|
622
|
-
const def =
|
|
634
|
+
const def = lowerer.unions.get(t.unionId);
|
|
623
635
|
if (!def)
|
|
624
|
-
throw new
|
|
636
|
+
throw new InternalCompilerError(`inspect of unknown union ${t.unionId}`);
|
|
625
637
|
body = [];
|
|
626
638
|
def.arms.forEach((arm, tag) => {
|
|
627
639
|
// The union wrapper is not a nesting level: arms render at the
|
|
@@ -630,18 +642,18 @@ function inspectHelper(L, t, loc) {
|
|
|
630
642
|
body.push({
|
|
631
643
|
kind: "if",
|
|
632
644
|
cond: { kind: "unionIsTag", unionId: t.unionId, tag, negated: false, value: v(), type: BOOL, loc },
|
|
633
|
-
then: [ret(inspectExpr(
|
|
645
|
+
then: [ret(inspectExpr(lowerer, arm, narrowed, r(), d(), loc))],
|
|
634
646
|
else_: null,
|
|
635
647
|
loc,
|
|
636
648
|
});
|
|
637
649
|
});
|
|
638
|
-
body.push(ret(
|
|
650
|
+
body.push(ret(strLit("", loc))); // unreachable: some arm always matches
|
|
639
651
|
break;
|
|
640
652
|
}
|
|
641
653
|
case "object": {
|
|
642
|
-
const info =
|
|
654
|
+
const info = lowerer.classes.get(t.className);
|
|
643
655
|
if (!info)
|
|
644
|
-
throw new
|
|
656
|
+
throw new InternalCompilerError(`inspect of unknown class ${t.className}`);
|
|
645
657
|
// Node prints the class's OWN name — the declaration's, never the
|
|
646
658
|
// IR name's module qualifier (`m0.Timer` is the frontend's spelling
|
|
647
659
|
// for a class declared in a non-entry module).
|
|
@@ -651,7 +663,7 @@ function inspectHelper(L, t, loc) {
|
|
|
651
663
|
// so a class whose only fields are private prints as `C {}`.
|
|
652
664
|
const visible = info.def.fields.filter((f) => !f.name.startsWith("#"));
|
|
653
665
|
if (visible.length === 0) {
|
|
654
|
-
body = [ret(
|
|
666
|
+
body = [ret(strLit(`${display} {}`, loc))];
|
|
655
667
|
break;
|
|
656
668
|
}
|
|
657
669
|
const get = (field, type) => ({ kind: "fieldGet", obj: v(), className: t.className, field, type, loc });
|
|
@@ -670,13 +682,13 @@ function inspectHelper(L, t, loc) {
|
|
|
670
682
|
];
|
|
671
683
|
for (const f of ordered) {
|
|
672
684
|
const key = symNames.has(f.name) ? f.name : inspectKey(f.name);
|
|
673
|
-
body.push(entry(concatAll([
|
|
685
|
+
body.push(entry(concatAll([strLit(`${key}: `, loc), child(f.type, get(f.name, f.type))], loc), boolLit(false, loc)));
|
|
674
686
|
}
|
|
675
|
-
body.push(ret(end(
|
|
687
|
+
body.push(ret(end(strLit("", loc), strLit(`${display} {`, loc), strLit("}", loc), false, boolLit(false, loc))));
|
|
676
688
|
break;
|
|
677
689
|
}
|
|
678
690
|
default:
|
|
679
|
-
throw new
|
|
691
|
+
throw new InternalCompilerError(`inspect helper over unexpected type ${typeKey(t)}`);
|
|
680
692
|
}
|
|
681
693
|
let prependCycleGuard = null;
|
|
682
694
|
if (onCycle) {
|
|
@@ -685,7 +697,7 @@ function inspectHelper(L, t, loc) {
|
|
|
685
697
|
// [Circular *N] and descends no further — Node's formatValue order
|
|
686
698
|
// (a circular target beyond the depth budget still says Circular).
|
|
687
699
|
locals.push({ id: "cc.0", name: "cc", type: F64, mutable: false });
|
|
688
|
-
const cc = () =>
|
|
700
|
+
const cc = () => varRef("cc.0", F64, loc);
|
|
689
701
|
prependCycleGuard = () => {
|
|
690
702
|
body.unshift({
|
|
691
703
|
kind: "varDecl",
|
|
@@ -694,7 +706,7 @@ function inspectHelper(L, t, loc) {
|
|
|
694
706
|
loc,
|
|
695
707
|
}, {
|
|
696
708
|
kind: "if",
|
|
697
|
-
cond: { kind: "bin", op: ">", left: cc(), right:
|
|
709
|
+
cond: { kind: "bin", op: ">", left: cc(), right: numLit(0, loc), type: BOOL, loc },
|
|
698
710
|
then: [ret({ kind: "libCall", fn: "insp.circular", args: [cc()], type: STRING, loc })],
|
|
699
711
|
else_: null,
|
|
700
712
|
loc,
|
|
@@ -715,13 +727,13 @@ function inspectHelper(L, t, loc) {
|
|
|
715
727
|
loc,
|
|
716
728
|
};
|
|
717
729
|
if (rebuildShapeOrderBody !== null) {
|
|
718
|
-
|
|
730
|
+
lowerer.shapeOrderHelperFinalizers.push(() => {
|
|
719
731
|
rebuildShapeOrderBody();
|
|
720
732
|
prependCycleGuard?.();
|
|
721
733
|
fn.body = body;
|
|
722
734
|
});
|
|
723
735
|
}
|
|
724
|
-
|
|
736
|
+
lowerer.liftedFns.push(fn);
|
|
725
737
|
return name;
|
|
726
738
|
}
|
|
727
739
|
/* ── the console/format top-level value rendering ────────────────────── */
|
|
@@ -732,7 +744,7 @@ function inspectHelper(L, t, loc) {
|
|
|
732
744
|
* exactly as inspect at the given depth. Unions dispatch per arm AT
|
|
733
745
|
* RUNTIME through an interned helper, so a string arm stays verbatim
|
|
734
746
|
* while its sibling arms inspect. Callers check inspectSupport first. */
|
|
735
|
-
|
|
747
|
+
function formatValueExpr(lowerer, t, value, depth, loc) {
|
|
736
748
|
switch (t.kind) {
|
|
737
749
|
case "string":
|
|
738
750
|
return value;
|
|
@@ -741,33 +753,33 @@ export function formatValueExpr(L, t, value, depth, loc) {
|
|
|
741
753
|
case "bool":
|
|
742
754
|
return { kind: "toString", operand: value, type: STRING, loc };
|
|
743
755
|
case "undefinedT":
|
|
744
|
-
return
|
|
756
|
+
return strLit("undefined", loc);
|
|
745
757
|
case "nullT":
|
|
746
|
-
return
|
|
758
|
+
return strLit("null", loc);
|
|
747
759
|
case "symbol":
|
|
748
760
|
return { kind: "libCall", fn: "sym.toString", args: [value], type: STRING, loc };
|
|
749
761
|
case "dyn":
|
|
750
|
-
return { kind: "libCall", fn: "insp.dynS", args: [value,
|
|
762
|
+
return { kind: "libCall", fn: "insp.dynS", args: [value, numLit(depth, loc)], type: STRING, loc };
|
|
751
763
|
case "union":
|
|
752
|
-
return { kind: "call", callee: formatUnionHelper(
|
|
764
|
+
return { kind: "call", callee: formatUnionHelper(lowerer, t, depth, loc), args: [value], type: STRING, loc };
|
|
753
765
|
default:
|
|
754
|
-
return inspectExpr(
|
|
766
|
+
return inspectExpr(lowerer, t, value, numLit(0, loc), numLit(depth, loc), loc);
|
|
755
767
|
}
|
|
756
768
|
}
|
|
757
769
|
/** `%util.fmtv.<n>(v): string` — formatValueExpr's runtime dispatch over a
|
|
758
770
|
* union's arms (interned per union + depth, the inspectHelper pattern).
|
|
759
771
|
* The TOP-LEVEL union rule only: nested unions inside composites keep
|
|
760
772
|
* inspect's own rendering, where string arms quote — exactly Node. */
|
|
761
|
-
function formatUnionHelper(
|
|
773
|
+
function formatUnionHelper(lowerer, t, depth, loc) {
|
|
762
774
|
const key = `fmtv:${typeKey(t)}:${depth}`;
|
|
763
|
-
const existing =
|
|
775
|
+
const existing = lowerer.inspectHelpers.get(key);
|
|
764
776
|
if (existing)
|
|
765
777
|
return existing;
|
|
766
|
-
const name = `%util.fmtv.${
|
|
767
|
-
|
|
768
|
-
const def =
|
|
778
|
+
const name = `%util.fmtv.${lowerer.inspectHelpers.size}`;
|
|
779
|
+
lowerer.inspectHelpers.set(key, name);
|
|
780
|
+
const def = lowerer.unions.get(t.unionId);
|
|
769
781
|
if (!def)
|
|
770
|
-
throw new
|
|
782
|
+
throw new InternalCompilerError(`format value over unknown union ${t.unionId}`);
|
|
771
783
|
const v = () => ({ kind: "varRef", localId: "v.0", type: t, loc });
|
|
772
784
|
const body = [];
|
|
773
785
|
def.arms.forEach((arm, tag) => {
|
|
@@ -775,13 +787,13 @@ function formatUnionHelper(L, t, depth, loc) {
|
|
|
775
787
|
body.push({
|
|
776
788
|
kind: "if",
|
|
777
789
|
cond: { kind: "unionIsTag", unionId: t.unionId, tag, negated: false, value: v(), type: BOOL, loc },
|
|
778
|
-
then: [{ kind: "return", value: formatValueExpr(
|
|
790
|
+
then: [{ kind: "return", value: formatValueExpr(lowerer, arm, narrowed, depth, loc), loc }],
|
|
779
791
|
else_: null,
|
|
780
792
|
loc,
|
|
781
793
|
});
|
|
782
794
|
});
|
|
783
|
-
body.push({ kind: "return", value:
|
|
784
|
-
|
|
795
|
+
body.push({ kind: "return", value: strLit("", loc), loc }); // unreachable: some arm always matches
|
|
796
|
+
lowerer.liftedFns.push({
|
|
785
797
|
name,
|
|
786
798
|
params: [{ localId: "v.0", name: "v", type: t }],
|
|
787
799
|
returnType: STRING,
|
|
@@ -797,53 +809,53 @@ function formatUnionHelper(L, t, depth, loc) {
|
|
|
797
809
|
* site): the rendered STRING under Node's console semantics — inspect at
|
|
798
810
|
* the rest-args depth 2 — or the honest fence naming the first
|
|
799
811
|
* unsupported constituent. */
|
|
800
|
-
export function lowerConsoleInspectArg(
|
|
812
|
+
export function lowerConsoleInspectArg(lowerer, node, value, surface, loc) {
|
|
801
813
|
const t = value.type;
|
|
802
814
|
if (t.kind === "undefinedT" || t.kind === "nullT") {
|
|
803
815
|
// The baked text ("undefined"/"null"): the operand is a literal or a
|
|
804
816
|
// pure read, so dropping its evaluation loses nothing. Effectful
|
|
805
817
|
// unit-typed operands keep a fence — a silent skip is banned.
|
|
806
818
|
if (value.kind !== "unitLit" && !pureReemittable(value)) {
|
|
807
|
-
|
|
819
|
+
lowerer.unsupported("SC1090", node, `${surface} of an effectful '${lowerer.fmt(t)}'-typed expression (evaluate it first: const v = ...; ${surface}(v))`);
|
|
808
820
|
}
|
|
809
|
-
return
|
|
821
|
+
return strLit(t.kind === "undefinedT" ? "undefined" : "null", loc);
|
|
810
822
|
}
|
|
811
823
|
if (t.kind === "bytes") {
|
|
812
824
|
// One runtime representation serves Buffer AND Uint8Array; their
|
|
813
825
|
// renderings differ, so the argument's checker type picks — and only
|
|
814
826
|
// Buffer lowers (lowerInspectCall's stance).
|
|
815
|
-
const tname =
|
|
827
|
+
const tname = lowerer.checker.typeToString(lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(node)));
|
|
816
828
|
const isBuffer = tname === "Buffer" || tname === "NonSharedBuffer" || tname.startsWith("Buffer<") || tname.startsWith("NonSharedBuffer<");
|
|
817
829
|
if (t.elem !== "u8" || !isBuffer) {
|
|
818
|
-
|
|
830
|
+
lowerer.unsupported("SC1090", node, `${surface} of '${tname}' values (Buffer's <Buffer ..> form is the lowered typed-array rendering; other typed arrays fence)`);
|
|
819
831
|
}
|
|
820
|
-
return inspectExpr(
|
|
832
|
+
return inspectExpr(lowerer, t, value, numLit(0, loc), numLit(2, loc), loc);
|
|
821
833
|
}
|
|
822
834
|
if (t.kind === "void") {
|
|
823
835
|
// Node prints "undefined" for a void call's result; a void expression
|
|
824
836
|
// is not a value here, so the composition fences with the rewrite.
|
|
825
|
-
|
|
837
|
+
lowerer.unsupported("SC1090", node, `${surface} of a void call result (call it as its own statement, then ${surface}(undefined))`);
|
|
826
838
|
}
|
|
827
839
|
const walk = { recursive: false };
|
|
828
|
-
const reason = inspectSupport(
|
|
840
|
+
const reason = inspectSupport(lowerer, t, new Set(), walk);
|
|
829
841
|
if (reason !== null) {
|
|
830
|
-
|
|
842
|
+
lowerer.unsupported("SC1090", node, `${surface} of '${lowerer.fmt(t)}' values (${reason})`);
|
|
831
843
|
}
|
|
832
|
-
return formatValueExpr(
|
|
844
|
+
return formatValueExpr(lowerer, t, value, 2, loc);
|
|
833
845
|
}
|
|
834
846
|
/* ── the callsite: options, direct function/class names ──────────────── */
|
|
835
847
|
/** The parsed options literal: the resolved depth (numeric; Infinity for
|
|
836
848
|
* `null`), with every non-default knob fenced by name. */
|
|
837
|
-
function parseInspectOptions(
|
|
849
|
+
function parseInspectOptions(lowerer, node, recursive) {
|
|
838
850
|
if (!node || (ts.isIdentifier(node) && node.text === "undefined"))
|
|
839
851
|
return 2;
|
|
840
852
|
if (!ts.isObjectLiteralExpression(node)) {
|
|
841
|
-
|
|
853
|
+
lowerer.noLowering("util.inspect with a non-literal options argument", node, "the options must be an object literal ({ depth, colors: false, ... }) so the knobs resolve at compile time");
|
|
842
854
|
}
|
|
843
855
|
let depth = 2;
|
|
844
856
|
for (const prop of node.properties) {
|
|
845
857
|
if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) {
|
|
846
|
-
|
|
858
|
+
lowerer.noLowering("util.inspect options in this form", prop, "plain `key: literal` entries are the lowered options");
|
|
847
859
|
}
|
|
848
860
|
const key = prop.name.text;
|
|
849
861
|
const value = prop.initializer;
|
|
@@ -866,28 +878,28 @@ function parseInspectOptions(L, node, recursive) {
|
|
|
866
878
|
else if (!(ts.isIdentifier(value) && value.text === "undefined")) {
|
|
867
879
|
const n = numeric();
|
|
868
880
|
if (n === null) {
|
|
869
|
-
|
|
881
|
+
lowerer.noLowering("util.inspect with a non-literal depth option", value, "depth must be a numeric literal (or null)");
|
|
870
882
|
}
|
|
871
883
|
depth = n;
|
|
872
884
|
}
|
|
873
885
|
}
|
|
874
886
|
else if (key === "colors") {
|
|
875
887
|
if (value.kind !== ts.SyntaxKind.FalseKeyword) {
|
|
876
|
-
|
|
888
|
+
lowerer.noLowering("util.inspect with colors: true", value, "ANSI styling has no lowering — only colors: false");
|
|
877
889
|
}
|
|
878
890
|
}
|
|
879
891
|
else if (key === "compact") {
|
|
880
892
|
if (numeric() !== 3) {
|
|
881
|
-
|
|
893
|
+
lowerer.noLowering("util.inspect with a non-default compact option", value, "only the default compact: 3 is lowered");
|
|
882
894
|
}
|
|
883
895
|
}
|
|
884
896
|
else if (key === "breakLength") {
|
|
885
897
|
if (numeric() !== 80) {
|
|
886
|
-
|
|
898
|
+
lowerer.noLowering("util.inspect with a non-default breakLength option", value, "only the default breakLength: 80 is lowered");
|
|
887
899
|
}
|
|
888
900
|
}
|
|
889
901
|
else {
|
|
890
|
-
|
|
902
|
+
lowerer.noLowering(`util.inspect with the '${key}' option`, prop, "the lowered options are depth (numeric literal or null), colors: false, compact: 3, and breakLength: 80");
|
|
891
903
|
}
|
|
892
904
|
}
|
|
893
905
|
return depth;
|
|
@@ -896,13 +908,13 @@ function parseInspectOptions(L, node, recursive) {
|
|
|
896
908
|
* naming a declared function or class: the name is compile-time truth,
|
|
897
909
|
* so `[Function: name]` / `[class X extends Y]` bake as literals. Null
|
|
898
910
|
* when the identifier is not such a declaration. */
|
|
899
|
-
function directCallableInspect(
|
|
911
|
+
function directCallableInspect(lowerer, node, loc) {
|
|
900
912
|
if (!ts.isIdentifier(node))
|
|
901
913
|
return null;
|
|
902
|
-
const sym =
|
|
914
|
+
const sym = lowerer.resolveValueSymbol(node);
|
|
903
915
|
if (!sym)
|
|
904
916
|
return null;
|
|
905
|
-
const cls =
|
|
917
|
+
const cls = lowerer.classBySymbol.get(sym) ?? lowerer.builtinErrorInfoOf(sym);
|
|
906
918
|
// A rebindable decorated name is not compile-time truth — the binding
|
|
907
919
|
// holds the decoration result; no literal folds.
|
|
908
920
|
if (cls?.classDecorators?.valueGlobalId !== undefined)
|
|
@@ -910,16 +922,16 @@ function directCallableInspect(L, node, loc) {
|
|
|
910
922
|
if (cls) {
|
|
911
923
|
if (cls.builtinError) {
|
|
912
924
|
// Node's Error constructors are native functions, not classes.
|
|
913
|
-
return
|
|
925
|
+
return strLit(`[Function: ${cls.def.name.replace(/^%/, "")}]`, loc);
|
|
914
926
|
}
|
|
915
927
|
const base = cls.base ? ` extends ${cls.base.def.name.replace(/^%/, "")}` : "";
|
|
916
|
-
return
|
|
928
|
+
return strLit(`[class ${cls.def.name}${base}]`, loc);
|
|
917
929
|
}
|
|
918
|
-
const decl =
|
|
930
|
+
const decl = lowerer.checker.declarationsOf(sym)[0];
|
|
919
931
|
if (!decl)
|
|
920
932
|
return null;
|
|
921
933
|
if (ts.isFunctionDeclaration(decl) && decl.name) {
|
|
922
|
-
return
|
|
934
|
+
return strLit(`[Function: ${decl.name.text}]`, loc);
|
|
923
935
|
}
|
|
924
936
|
if (ts.isVariableDeclaration(decl) &&
|
|
925
937
|
ts.isIdentifier(decl.name) &&
|
|
@@ -928,57 +940,57 @@ function directCallableInspect(L, node, loc) {
|
|
|
928
940
|
// JS name inference: the binding names the function value — unless
|
|
929
941
|
// the function expression carries its OWN name, which wins.
|
|
930
942
|
const own = ts.isFunctionExpression(decl.initializer) ? decl.initializer.name?.text : undefined;
|
|
931
|
-
return
|
|
943
|
+
return strLit(`[Function: ${own ?? decl.name.text}]`, loc);
|
|
932
944
|
}
|
|
933
945
|
return null;
|
|
934
946
|
}
|
|
935
947
|
/** util.inspect(value[, options]) — the spoke's inspect entry. */
|
|
936
|
-
function lowerInspectCall(
|
|
948
|
+
function lowerInspectCall(lowerer, expr, loc) {
|
|
937
949
|
if (expr.arguments.length < 1 || expr.arguments.length > 2) {
|
|
938
|
-
|
|
950
|
+
lowerer.noLowering(`util.inspect with ${expr.arguments.length} arguments`, expr, "the supported forms are inspect(value) and inspect(value, options)");
|
|
939
951
|
}
|
|
940
952
|
const valueNode = expr.arguments[0];
|
|
941
953
|
// Inline function/class literals and direct declared names render as
|
|
942
954
|
// their baked forms; other function-typed values fence below.
|
|
943
|
-
const direct = directCallableInspect(
|
|
955
|
+
const direct = directCallableInspect(lowerer, valueNode, loc);
|
|
944
956
|
if (direct) {
|
|
945
|
-
parseInspectOptions(
|
|
957
|
+
parseInspectOptions(lowerer, expr.arguments[1], false);
|
|
946
958
|
return direct;
|
|
947
959
|
}
|
|
948
960
|
if (ts.isArrowFunction(valueNode) || ts.isFunctionExpression(valueNode)) {
|
|
949
|
-
parseInspectOptions(
|
|
950
|
-
return
|
|
961
|
+
parseInspectOptions(lowerer, expr.arguments[1], false);
|
|
962
|
+
return strLit(valueNode.kind === ts.SyntaxKind.FunctionExpression && valueNode.name ? `[Function: ${valueNode.name.text}]` : "[Function (anonymous)]", loc);
|
|
951
963
|
}
|
|
952
|
-
const value =
|
|
964
|
+
const value = lowerer.lowerExpr(valueNode);
|
|
953
965
|
if (value.type.kind === "bytes") {
|
|
954
966
|
// One runtime representation serves Buffer AND Uint8Array; their
|
|
955
967
|
// renderings differ (<Buffer aa> vs Uint8Array(1) [ 170 ]), so the
|
|
956
968
|
// TOP-LEVEL argument's checker type picks — and only Buffer lowers.
|
|
957
969
|
// Nested bytes fence in inspectSupport (no checker type survives
|
|
958
970
|
// into shapes).
|
|
959
|
-
const tname =
|
|
971
|
+
const tname = lowerer.checker.typeToString(lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(valueNode)));
|
|
960
972
|
const isBuffer = tname === "Buffer" || tname === "NonSharedBuffer" || tname.startsWith("Buffer<") || tname.startsWith("NonSharedBuffer<");
|
|
961
973
|
if (value.type.elem !== "u8" || !isBuffer) {
|
|
962
|
-
|
|
974
|
+
lowerer.noLowering(`util.inspect of '${tname}' values`, valueNode, "Buffer's <Buffer ..> form is the lowered typed-array rendering; other typed arrays fence");
|
|
963
975
|
}
|
|
964
|
-
const bufDepth = parseInspectOptions(
|
|
976
|
+
const bufDepth = parseInspectOptions(lowerer, expr.arguments[1], false);
|
|
965
977
|
void bufDepth; // Buffers render fully at any depth (custom inspect)
|
|
966
|
-
return inspectExpr(
|
|
978
|
+
return inspectExpr(lowerer, value.type, value, numLit(0, loc), numLit(2, loc), loc);
|
|
967
979
|
}
|
|
968
980
|
const walk = { recursive: false };
|
|
969
|
-
const reason = inspectSupport(
|
|
981
|
+
const reason = inspectSupport(lowerer, value.type, new Set(), walk);
|
|
970
982
|
if (reason !== null) {
|
|
971
|
-
|
|
983
|
+
lowerer.noLowering(`util.inspect of '${lowerer.fmt(value.type)}' values`, valueNode, reason);
|
|
972
984
|
}
|
|
973
|
-
const depth = parseInspectOptions(
|
|
974
|
-
return inspectExpr(
|
|
985
|
+
const depth = parseInspectOptions(lowerer, expr.arguments[1], walk.recursive);
|
|
986
|
+
return inspectExpr(lowerer, value.type, value, numLit(0, loc), numLit(depth, loc), loc);
|
|
975
987
|
}
|
|
976
988
|
/* ── util.format / util.formatWithOptions ────────────────────────────── */
|
|
977
989
|
/** One argument as format's %s conversion (Node: numbers via
|
|
978
990
|
* formatNumber, strings verbatim, objects through inspect at the given
|
|
979
991
|
* depth). Null = fence with the given reason. */
|
|
980
|
-
function formatSArg(
|
|
981
|
-
const value =
|
|
992
|
+
function formatSArg(lowerer, node, depth, loc) {
|
|
993
|
+
const value = lowerer.lowerExpr(node);
|
|
982
994
|
const t = value.type;
|
|
983
995
|
if (t.kind === "string")
|
|
984
996
|
return value;
|
|
@@ -987,91 +999,91 @@ function formatSArg(L, node, depth, loc) {
|
|
|
987
999
|
if (t.kind === "bool")
|
|
988
1000
|
return { kind: "toString", operand: value, type: STRING, loc };
|
|
989
1001
|
if (t.kind === "undefinedT")
|
|
990
|
-
return
|
|
1002
|
+
return strLit("undefined", loc);
|
|
991
1003
|
if (t.kind === "nullT")
|
|
992
|
-
return
|
|
1004
|
+
return strLit("null", loc);
|
|
993
1005
|
// %s of a symbol prints inspect's text ("Symbol(foo)") — String(sym)'s
|
|
994
1006
|
// answer too, one runtime call either way.
|
|
995
1007
|
if (t.kind === "symbol")
|
|
996
1008
|
return { kind: "libCall", fn: "sym.toString", args: [value], type: STRING, loc };
|
|
997
1009
|
if (t.kind === "dyn") {
|
|
998
|
-
return { kind: "libCall", fn: "insp.dynS", args: [value,
|
|
1010
|
+
return { kind: "libCall", fn: "insp.dynS", args: [value, numLit(depth, loc)], type: STRING, loc };
|
|
999
1011
|
}
|
|
1000
1012
|
// A UNION argument dispatches per arm at runtime: a string arm prints
|
|
1001
1013
|
// VERBATIM (typeof arg === 'string' in Node's formatter — inspect's
|
|
1002
1014
|
// quoting never applies at the top level), every other arm inspects.
|
|
1003
1015
|
if (t.kind === "union") {
|
|
1004
1016
|
const walk = { recursive: false };
|
|
1005
|
-
const reason = inspectSupport(
|
|
1017
|
+
const reason = inspectSupport(lowerer, t, new Set(), walk);
|
|
1006
1018
|
if (reason !== null)
|
|
1007
|
-
|
|
1008
|
-
return formatValueExpr(
|
|
1019
|
+
lowerer.noLowering(`util.format %s of '${lowerer.fmt(t)}' values`, node, reason);
|
|
1020
|
+
return formatValueExpr(lowerer, t, value, depth, loc);
|
|
1009
1021
|
}
|
|
1010
|
-
if (t.kind === "object" && !isErrorClass(
|
|
1022
|
+
if (t.kind === "object" && !isErrorClass(lowerer, t.className)) {
|
|
1011
1023
|
// hasBuiltInToString: a class with its OWN toString goes through
|
|
1012
1024
|
// String(arg) in Node, not inspect — call it explicitly instead.
|
|
1013
|
-
for (let info =
|
|
1025
|
+
for (let info = lowerer.classes.get(t.className) ?? null; info; info = info.base) {
|
|
1014
1026
|
if (info.methods.has("toString")) {
|
|
1015
|
-
|
|
1027
|
+
lowerer.noLowering("util.format %s over a class with its own toString", node, "Node calls the override (String(arg)) — call it explicitly");
|
|
1016
1028
|
}
|
|
1017
1029
|
}
|
|
1018
1030
|
}
|
|
1019
1031
|
if (t.kind === "bytes") {
|
|
1020
|
-
|
|
1032
|
+
lowerer.noLowering(`util.format %s of typed-array values`, node, "pass util.inspect(buf) explicitly");
|
|
1021
1033
|
}
|
|
1022
1034
|
const walk = { recursive: false };
|
|
1023
|
-
const reason = inspectSupport(
|
|
1035
|
+
const reason = inspectSupport(lowerer, t, new Set(), walk);
|
|
1024
1036
|
if (reason !== null)
|
|
1025
|
-
|
|
1026
|
-
return inspectExpr(
|
|
1037
|
+
lowerer.noLowering(`util.format %s of '${lowerer.fmt(t)}' values`, node, reason);
|
|
1038
|
+
return inspectExpr(lowerer, t, value, numLit(0, loc), numLit(depth, loc), loc);
|
|
1027
1039
|
}
|
|
1028
1040
|
/** %O (depth 2) / %o (showHidden, depth 4) — inspect with the spec's
|
|
1029
1041
|
* option deltas; %o fences over arrays (showHidden adds their hidden
|
|
1030
1042
|
* [length] entry, which has no lowering). */
|
|
1031
|
-
function formatOArg(
|
|
1032
|
-
const value =
|
|
1043
|
+
function formatOArg(lowerer, node, depth, loc) {
|
|
1044
|
+
const value = lowerer.lowerExpr(node);
|
|
1033
1045
|
if (value.type.kind === "bytes") {
|
|
1034
|
-
|
|
1046
|
+
lowerer.noLowering(`util.format %${depth === 4 ? "o" : "O"} of typed-array values`, node, "pass util.inspect(buf) explicitly");
|
|
1035
1047
|
}
|
|
1036
1048
|
const walk = { recursive: false };
|
|
1037
|
-
const reason = inspectSupport(
|
|
1049
|
+
const reason = inspectSupport(lowerer, value.type, new Set(), walk);
|
|
1038
1050
|
if (reason !== null)
|
|
1039
|
-
|
|
1040
|
-
if (depth === 4 && typeTreeHasArray(
|
|
1041
|
-
|
|
1051
|
+
lowerer.noLowering(`util.format %${depth === 4 ? "o" : "O"} of '${lowerer.fmt(value.type)}' values`, node, reason);
|
|
1052
|
+
if (depth === 4 && typeTreeHasArray(lowerer, value.type, new Set())) {
|
|
1053
|
+
lowerer.noLowering("util.format %o over arrays", node, "%o renders with showHidden (arrays gain a hidden [length] entry) — use %O for the default rendering");
|
|
1042
1054
|
}
|
|
1043
|
-
return inspectExpr(
|
|
1055
|
+
return inspectExpr(lowerer, value.type, value, numLit(0, loc), numLit(depth, loc), loc);
|
|
1044
1056
|
}
|
|
1045
1057
|
/** util.format(...) / util.formatWithOptions({}, ...): the compile-time
|
|
1046
1058
|
* %-substitution over a literal format string (formatWithOptionsInternal
|
|
1047
1059
|
* ported exactly — the arg cursor, the args-exhausted guard, %c's
|
|
1048
1060
|
* consume-and-drop), with per-static-type conversions. Non-literal
|
|
1049
1061
|
* format strings lower only in the substitution-free shapes. */
|
|
1050
|
-
export function lowerFormatCall(
|
|
1062
|
+
export function lowerFormatCall(lowerer, expr, loc, withOptions) {
|
|
1051
1063
|
const argNodes = [...expr.arguments];
|
|
1052
1064
|
if (withOptions) {
|
|
1053
1065
|
const opts = argNodes.shift();
|
|
1054
1066
|
if (!opts || !ts.isObjectLiteralExpression(opts) || opts.properties.length > 0) {
|
|
1055
|
-
|
|
1067
|
+
lowerer.noLowering("util.formatWithOptions with a non-empty options literal", opts ?? expr, "only the empty literal {} (the defaults — exactly util.format) is lowered");
|
|
1056
1068
|
}
|
|
1057
1069
|
}
|
|
1058
1070
|
if (argNodes.length === 0)
|
|
1059
|
-
return
|
|
1071
|
+
return strLit("", loc);
|
|
1060
1072
|
const first = argNodes[0];
|
|
1061
1073
|
const firstIsLiteral = ts.isStringLiteral(first) || ts.isNoSubstitutionTemplateLiteral(first);
|
|
1062
1074
|
/** The rest-args tail: ` ` + (strings verbatim, everything else
|
|
1063
1075
|
* inspected at the default depth). */
|
|
1064
|
-
const restArg = (node) => formatSArg(
|
|
1076
|
+
const restArg = (node) => formatSArg(lowerer, node, 2, loc);
|
|
1065
1077
|
if (!firstIsLiteral) {
|
|
1066
|
-
const firstT =
|
|
1078
|
+
const firstT = lowerer.mapTypeOf(lowerer.typeOf(first));
|
|
1067
1079
|
if (firstT?.kind === "string" && argNodes.length > 1) {
|
|
1068
|
-
|
|
1080
|
+
lowerer.noLowering("util.format with a runtime format string and further arguments", first, "the %-substitution positions are runtime-dependent — use a string literal");
|
|
1069
1081
|
}
|
|
1070
1082
|
// No substitutions possible: every argument joins with spaces.
|
|
1071
1083
|
const parts = [];
|
|
1072
1084
|
for (let i = 0; i < argNodes.length; i++) {
|
|
1073
1085
|
if (i > 0)
|
|
1074
|
-
parts.push(
|
|
1086
|
+
parts.push(strLit(" ", loc));
|
|
1075
1087
|
parts.push(restArg(argNodes[i]));
|
|
1076
1088
|
}
|
|
1077
1089
|
return concatAll(parts, loc);
|
|
@@ -1080,7 +1092,7 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1080
1092
|
// Node's early return: a lone string first argument passes VERBATIM —
|
|
1081
1093
|
// no substitution runs, "%%" stays "%%".
|
|
1082
1094
|
if (argNodes.length === 1)
|
|
1083
|
-
return
|
|
1095
|
+
return strLit(fmt, loc);
|
|
1084
1096
|
const parts = [];
|
|
1085
1097
|
let a = 0; // the arg cursor over argNodes (0 = the format string)
|
|
1086
1098
|
let lastPos = 0;
|
|
@@ -1088,12 +1100,12 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1088
1100
|
const convert = (spec, node) => {
|
|
1089
1101
|
switch (spec) {
|
|
1090
1102
|
case 115: // %s
|
|
1091
|
-
return formatSArg(
|
|
1103
|
+
return formatSArg(lowerer, node, 0, loc);
|
|
1092
1104
|
case 100: {
|
|
1093
1105
|
// %d — Number(arg) formatted: numbers as-is, booleans 1/0,
|
|
1094
1106
|
// strings through the runtime's ECMA-exact StringToNumber
|
|
1095
1107
|
// (num.fromString — the same lowering Number(aString) takes).
|
|
1096
|
-
const value =
|
|
1108
|
+
const value = lowerer.lowerExpr(node);
|
|
1097
1109
|
if (value.type.kind === "f64")
|
|
1098
1110
|
return { kind: "libCall", fn: "insp.f64", args: [value], type: STRING, loc };
|
|
1099
1111
|
if (value.type.kind === "string") {
|
|
@@ -1104,7 +1116,7 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1104
1116
|
return {
|
|
1105
1117
|
kind: "libCall",
|
|
1106
1118
|
fn: "insp.f64",
|
|
1107
|
-
args: [{ kind: "ternary", cond: value, then:
|
|
1119
|
+
args: [{ kind: "ternary", cond: value, then: numLit(1, loc), else_: numLit(0, loc), type: F64, loc }],
|
|
1108
1120
|
type: STRING,
|
|
1109
1121
|
loc,
|
|
1110
1122
|
};
|
|
@@ -1123,34 +1135,34 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1123
1135
|
loc,
|
|
1124
1136
|
};
|
|
1125
1137
|
}
|
|
1126
|
-
|
|
1138
|
+
lowerer.noLowering(`util.format %d of '${lowerer.fmt(value.type)}' values`, node, "numbers, booleans, and strings lower; ToNumber over other types has no static lowering");
|
|
1127
1139
|
break;
|
|
1128
1140
|
}
|
|
1129
1141
|
case 105: {
|
|
1130
1142
|
// %i — parseInt(ToString(arg)): the spec-exact composition.
|
|
1131
|
-
const value =
|
|
1143
|
+
const value = lowerer.lowerExpr(node);
|
|
1132
1144
|
if (value.type.kind === "f64" || value.type.kind === "bool" || value.type.kind === "string") {
|
|
1133
1145
|
const text = value.type.kind === "string" ? value : { kind: "toString", operand: value, type: STRING, loc };
|
|
1134
|
-
const parsed = { kind: "libCall", fn: "num.parseInt", args: [text,
|
|
1146
|
+
const parsed = { kind: "libCall", fn: "num.parseInt", args: [text, numLit(0, loc)], type: F64, loc };
|
|
1135
1147
|
return { kind: "libCall", fn: "insp.f64", args: [parsed], type: STRING, loc };
|
|
1136
1148
|
}
|
|
1137
|
-
|
|
1149
|
+
lowerer.noLowering(`util.format %i of '${lowerer.fmt(value.type)}' values`, node);
|
|
1138
1150
|
break;
|
|
1139
1151
|
}
|
|
1140
1152
|
case 106: {
|
|
1141
1153
|
// %j — JSON.stringify; undefined-valued args print "undefined"
|
|
1142
1154
|
// (Node appends the non-string result of tryStringify).
|
|
1143
|
-
const value =
|
|
1155
|
+
const value = lowerer.lowerExpr(node);
|
|
1144
1156
|
if (value.type.kind === "undefinedT")
|
|
1145
|
-
return
|
|
1157
|
+
return strLit("undefined", loc);
|
|
1146
1158
|
// JSON.stringify(sym) is undefined in Node — %j prints the
|
|
1147
1159
|
// "undefined" text. Folding drops the operand, so only
|
|
1148
1160
|
// side-effect-free reads compose (the typeof-fold stance).
|
|
1149
1161
|
if (value.type.kind === "symbol") {
|
|
1150
1162
|
if (!pureReemittable(value)) {
|
|
1151
|
-
|
|
1163
|
+
lowerer.noLowering(`util.format %j of computed symbol values`, node, "bind the symbol to a const first (the %j text is always \"undefined\")");
|
|
1152
1164
|
}
|
|
1153
|
-
return
|
|
1165
|
+
return strLit("undefined", loc);
|
|
1154
1166
|
}
|
|
1155
1167
|
// A checked-dynamic argument (`console.error('headers: %j',
|
|
1156
1168
|
// headers)` — the suite's http logging idiom): the runtime dyn
|
|
@@ -1159,17 +1171,17 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1159
1171
|
if (value.type.kind === "dyn") {
|
|
1160
1172
|
return { kind: "libCall", fn: "insp.jsonDyn", args: [value], type: STRING, loc };
|
|
1161
1173
|
}
|
|
1162
|
-
if (!
|
|
1163
|
-
|
|
1174
|
+
if (!lowerer.jsonStringifySafe(value.type)) {
|
|
1175
|
+
lowerer.noLowering(`util.format %j of '${lowerer.fmt(value.type)}' values`, node, "only JSON-safe static types lower");
|
|
1164
1176
|
}
|
|
1165
1177
|
return { kind: "jsonStringify", value, type: STRING, loc };
|
|
1166
1178
|
}
|
|
1167
1179
|
case 79: // %O — inspect at the defaults
|
|
1168
|
-
return formatOArg(
|
|
1180
|
+
return formatOArg(lowerer, node, 2, loc);
|
|
1169
1181
|
case 111: // %o — showHidden semantics; depth 4
|
|
1170
|
-
return formatOArg(
|
|
1182
|
+
return formatOArg(lowerer, node, 4, loc);
|
|
1171
1183
|
}
|
|
1172
|
-
throw new
|
|
1184
|
+
throw new InternalCompilerError("unreachable format spec");
|
|
1173
1185
|
};
|
|
1174
1186
|
for (let i = 0; i < fmt.length - 1; i++) {
|
|
1175
1187
|
if (fmt.charCodeAt(i) === 37 /* % */) {
|
|
@@ -1184,22 +1196,22 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1184
1196
|
case 105: { // i
|
|
1185
1197
|
const node = args[++a];
|
|
1186
1198
|
if (lastPos !== i - 1)
|
|
1187
|
-
parts.push(
|
|
1199
|
+
parts.push(strLit(fmt.slice(lastPos, i - 1), loc));
|
|
1188
1200
|
parts.push(convert(nextChar, node));
|
|
1189
1201
|
lastPos = i + 1;
|
|
1190
1202
|
continue;
|
|
1191
1203
|
}
|
|
1192
1204
|
case 102: // f — parseFloat's full grammar has no static lowering
|
|
1193
|
-
|
|
1205
|
+
lowerer.noLowering("util.format %f", expr, "parseFloat has no static lowering (it runs with --dynamic)");
|
|
1194
1206
|
break;
|
|
1195
1207
|
case 99: // c — consumes its argument, contributes nothing
|
|
1196
1208
|
a += 1;
|
|
1197
1209
|
if (lastPos !== i - 1)
|
|
1198
|
-
parts.push(
|
|
1210
|
+
parts.push(strLit(fmt.slice(lastPos, i - 1), loc));
|
|
1199
1211
|
lastPos = i + 1;
|
|
1200
1212
|
continue;
|
|
1201
1213
|
case 37: // %%
|
|
1202
|
-
parts.push(
|
|
1214
|
+
parts.push(strLit(fmt.slice(lastPos, i), loc));
|
|
1203
1215
|
lastPos = i + 1;
|
|
1204
1216
|
continue;
|
|
1205
1217
|
default:
|
|
@@ -1207,7 +1219,7 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1207
1219
|
}
|
|
1208
1220
|
}
|
|
1209
1221
|
else if (nextChar === 37) {
|
|
1210
|
-
parts.push(
|
|
1222
|
+
parts.push(strLit(fmt.slice(lastPos, i), loc));
|
|
1211
1223
|
lastPos = i + 1;
|
|
1212
1224
|
}
|
|
1213
1225
|
}
|
|
@@ -1215,22 +1227,22 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1215
1227
|
if (lastPos !== 0) {
|
|
1216
1228
|
a++;
|
|
1217
1229
|
if (lastPos < fmt.length)
|
|
1218
|
-
parts.push(
|
|
1230
|
+
parts.push(strLit(fmt.slice(lastPos), loc));
|
|
1219
1231
|
}
|
|
1220
1232
|
else {
|
|
1221
1233
|
// No substitution touched the format string: it joins verbatim, and
|
|
1222
1234
|
// the cursor advances past it.
|
|
1223
|
-
parts.push(
|
|
1235
|
+
parts.push(strLit(fmt, loc));
|
|
1224
1236
|
a++;
|
|
1225
1237
|
}
|
|
1226
1238
|
for (; a < args.length; a++) {
|
|
1227
|
-
parts.push(
|
|
1239
|
+
parts.push(strLit(" ", loc));
|
|
1228
1240
|
parts.push(restArg(args[a]));
|
|
1229
1241
|
}
|
|
1230
1242
|
return concatAll(parts, loc);
|
|
1231
1243
|
}
|
|
1232
1244
|
/** Arrays anywhere in the tree — the %o (showHidden) gate. */
|
|
1233
|
-
function typeTreeHasArray(
|
|
1245
|
+
function typeTreeHasArray(lowerer, t, visiting) {
|
|
1234
1246
|
switch (t.kind) {
|
|
1235
1247
|
case "array":
|
|
1236
1248
|
return true;
|
|
@@ -1238,26 +1250,26 @@ function typeTreeHasArray(L, t, visiting) {
|
|
|
1238
1250
|
if (visiting.has(t.shapeId))
|
|
1239
1251
|
return false;
|
|
1240
1252
|
visiting.add(t.shapeId);
|
|
1241
|
-
const shape =
|
|
1253
|
+
const shape = lowerer.shapes.get(t.shapeId);
|
|
1242
1254
|
if (shape?.tuple)
|
|
1243
1255
|
return true;
|
|
1244
|
-
return (shape?.fields ?? []).some((f) => typeTreeHasArray(
|
|
1256
|
+
return (shape?.fields ?? []).some((f) => typeTreeHasArray(lowerer, f.type, visiting));
|
|
1245
1257
|
}
|
|
1246
1258
|
case "map":
|
|
1247
|
-
return typeTreeHasArray(
|
|
1259
|
+
return typeTreeHasArray(lowerer, t.key, visiting) || typeTreeHasArray(lowerer, t.value, visiting);
|
|
1248
1260
|
case "set":
|
|
1249
|
-
return typeTreeHasArray(
|
|
1261
|
+
return typeTreeHasArray(lowerer, t.elem, visiting);
|
|
1250
1262
|
case "union": {
|
|
1251
1263
|
if (visiting.has(t.unionId))
|
|
1252
1264
|
return false;
|
|
1253
1265
|
visiting.add(t.unionId);
|
|
1254
|
-
return (
|
|
1266
|
+
return (lowerer.unions.get(t.unionId)?.arms ?? []).some((a) => typeTreeHasArray(lowerer, a, visiting));
|
|
1255
1267
|
}
|
|
1256
1268
|
case "object": {
|
|
1257
1269
|
if (visiting.has(t.className))
|
|
1258
1270
|
return false;
|
|
1259
1271
|
visiting.add(t.className);
|
|
1260
|
-
return (
|
|
1272
|
+
return (lowerer.classes.get(t.className)?.def.fields ?? []).some((f) => typeTreeHasArray(lowerer, f.type, visiting));
|
|
1261
1273
|
}
|
|
1262
1274
|
case "bytes":
|
|
1263
1275
|
return true;
|
|
@@ -1269,20 +1281,20 @@ function typeTreeHasArray(L, t, visiting) {
|
|
|
1269
1281
|
/** The spoke's entry, called from both the named-import and namespace/
|
|
1270
1282
|
* default-import call paths. Null for other modules and members (the
|
|
1271
1283
|
* module tables' fence takes over). */
|
|
1272
|
-
export function lowerUtilModuleCall(
|
|
1284
|
+
export function lowerUtilModuleCall(lowerer, expr, bi, loc) {
|
|
1273
1285
|
if (bi.module !== "util")
|
|
1274
1286
|
return null;
|
|
1275
1287
|
switch (bi.member) {
|
|
1276
1288
|
case "inspect":
|
|
1277
|
-
return lowerInspectCall(
|
|
1289
|
+
return lowerInspectCall(lowerer, expr, loc);
|
|
1278
1290
|
case "format":
|
|
1279
|
-
return lowerFormatCall(
|
|
1291
|
+
return lowerFormatCall(lowerer, expr, loc, false);
|
|
1280
1292
|
case "formatWithOptions":
|
|
1281
|
-
return lowerFormatCall(
|
|
1293
|
+
return lowerFormatCall(lowerer, expr, loc, true);
|
|
1282
1294
|
case "parseArgs":
|
|
1283
|
-
return lowerParseArgsCall(
|
|
1295
|
+
return lowerParseArgsCall(lowerer, expr, loc);
|
|
1284
1296
|
case "getCallSites":
|
|
1285
|
-
return lowerGetCallSitesCall(
|
|
1297
|
+
return lowerGetCallSitesCall(lowerer, expr, loc);
|
|
1286
1298
|
default:
|
|
1287
1299
|
return null;
|
|
1288
1300
|
}
|
|
@@ -1292,9 +1304,9 @@ export function lowerUtilModuleCall(L, expr, bi, loc) {
|
|
|
1292
1304
|
* parser returns the same tree-shaped result Node does (including token
|
|
1293
1305
|
* variants and a null-prototype values object); statically typed member
|
|
1294
1306
|
* reads leave that tree through the ordinary dyn checks. */
|
|
1295
|
-
function lowerParseArgsCall(
|
|
1307
|
+
function lowerParseArgsCall(lowerer, expr, loc) {
|
|
1296
1308
|
if (expr.arguments.length > 1 || expr.arguments.some(ts.isSpreadElement)) {
|
|
1297
|
-
|
|
1309
|
+
lowerer.noLowering(`util.parseArgs with ${expr.arguments.length} arguments`, expr, "the lowered form is parseArgs() or parseArgs(config)");
|
|
1298
1310
|
}
|
|
1299
1311
|
let config;
|
|
1300
1312
|
const configNode = expr.arguments[0];
|
|
@@ -1302,14 +1314,14 @@ function lowerParseArgsCall(L, expr, loc) {
|
|
|
1302
1314
|
config = { kind: "dynObjLit", fields: [], type: DYN, loc };
|
|
1303
1315
|
}
|
|
1304
1316
|
else {
|
|
1305
|
-
const raw =
|
|
1317
|
+
const raw = lowerer.lowerExpr(configNode);
|
|
1306
1318
|
if (raw.type.kind === "dyn") {
|
|
1307
1319
|
config = raw;
|
|
1308
1320
|
}
|
|
1309
1321
|
else if (raw.type.kind === "jsval") {
|
|
1310
1322
|
config = { kind: "dynFromJsval", value: raw, type: DYN, loc };
|
|
1311
1323
|
}
|
|
1312
|
-
else if (canConvertToDyn(raw.type, (id) =>
|
|
1324
|
+
else if (canConvertToDyn(raw.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
1313
1325
|
// parseArgs assigns descriptor default arrays directly into the
|
|
1314
1326
|
// returned values object. Keep mutable config composites in typed-ref
|
|
1315
1327
|
// capsules so that default arrays can leave the dyn result as the
|
|
@@ -1326,7 +1338,7 @@ function lowerParseArgsCall(L, expr, loc) {
|
|
|
1326
1338
|
};
|
|
1327
1339
|
}
|
|
1328
1340
|
else {
|
|
1329
|
-
|
|
1341
|
+
lowerer.noLowering(`util.parseArgs with a '${lowerer.fmt(raw.type)}' configuration`, configNode, "pass the documented JSON-safe config object (args/options and boolean flags)");
|
|
1330
1342
|
}
|
|
1331
1343
|
}
|
|
1332
1344
|
const parsed = {
|
|
@@ -1336,9 +1348,9 @@ function lowerParseArgsCall(L, expr, loc) {
|
|
|
1336
1348
|
type: DYN,
|
|
1337
1349
|
loc,
|
|
1338
1350
|
};
|
|
1339
|
-
const result =
|
|
1351
|
+
const result = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
1340
1352
|
if (result !== null && result.kind !== "dyn" && result.kind !== "jsval" && result.kind !== "void" &&
|
|
1341
|
-
canDynCheckTo(result, (id) =>
|
|
1353
|
+
canDynCheckTo(result, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
1342
1354
|
return { kind: "dynCheck", value: parsed, type: result, loc };
|
|
1343
1355
|
}
|
|
1344
1356
|
return parsed;
|
|
@@ -1352,7 +1364,7 @@ function lowerParseArgsCall(L, expr, loc) {
|
|
|
1352
1364
|
* failure text — read a printable value instead of throwing). Argument
|
|
1353
1365
|
* forms and TypeScript keep the SC2020 fence: a typed consumer asserting
|
|
1354
1366
|
* real frames must fail loudly at compile time, not read placeholders. */
|
|
1355
|
-
function lowerGetCallSitesCall(
|
|
1367
|
+
function lowerGetCallSitesCall(lowerer, expr, loc) {
|
|
1356
1368
|
if (expr.arguments.length !== 0)
|
|
1357
1369
|
return null;
|
|
1358
1370
|
if (!isJsSourceFile(expr.getSourceFile()))
|