xbintsc 0.5.23 → 0.5.32
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/AGENTS.md +11 -2
- package/README.md +47 -16
- package/README.zh-CN.md +21 -2
- package/dist/scripts/support-matrix.d.ts +18 -0
- package/dist/scripts/support-matrix.js +141 -0
- package/dist/scripts/support-matrix.js.map +1 -0
- package/dist/src/ast/common.d.ts +2 -2
- package/dist/src/ast/declarations.d.ts +7 -1
- package/dist/src/ast/expressions.d.ts +5 -0
- package/dist/src/ast/kinds.d.ts +2 -0
- package/dist/src/ast/kinds.js +2 -0
- package/dist/src/ast/kinds.js.map +1 -1
- package/dist/src/binder/binder.d.ts +2 -1
- package/dist/src/binder/binder.js +2 -0
- package/dist/src/binder/binder.js.map +1 -1
- package/dist/src/binder/declarations.d.ts +9 -0
- package/dist/src/binder/declarations.js +64 -0
- package/dist/src/binder/declarations.js.map +1 -1
- package/dist/src/binder/references.js +99 -4
- package/dist/src/binder/references.js.map +1 -1
- package/dist/src/binder/types.d.ts +32 -0
- package/dist/src/binder/types.js.map +1 -1
- package/dist/src/canonical.d.ts +29 -0
- package/dist/src/canonical.js +35 -0
- package/dist/src/canonical.js.map +1 -0
- package/dist/src/checker/assignability.d.ts +13 -0
- package/dist/src/checker/assignability.js +146 -0
- package/dist/src/checker/assignability.js.map +1 -0
- package/dist/src/checker/calls.d.ts +13 -0
- package/dist/src/checker/calls.js +127 -0
- package/dist/src/checker/calls.js.map +1 -0
- package/dist/src/checker/checker.d.ts +26 -0
- package/dist/src/checker/checker.js +31 -0
- package/dist/src/checker/checker.js.map +1 -0
- package/dist/src/checker/declarations.d.ts +9 -0
- package/dist/src/checker/declarations.js +15 -0
- package/dist/src/checker/declarations.js.map +1 -0
- package/dist/src/checker/flow.d.ts +21 -0
- package/dist/src/checker/flow.js +241 -0
- package/dist/src/checker/flow.js.map +1 -0
- package/dist/src/checker/globals.d.ts +9 -0
- package/dist/src/checker/globals.js +29 -0
- package/dist/src/checker/globals.js.map +1 -0
- package/dist/src/checker/source.d.ts +38 -0
- package/dist/src/checker/source.js +48 -0
- package/dist/src/checker/source.js.map +1 -0
- package/dist/src/checker/type-infer.d.ts +18 -0
- package/dist/src/checker/type-infer.js +173 -0
- package/dist/src/checker/type-infer.js.map +1 -0
- package/dist/src/checker/type-model.d.ts +73 -0
- package/dist/src/checker/type-model.js +151 -0
- package/dist/src/checker/type-model.js.map +1 -0
- package/dist/src/checker/type-system.d.ts +58 -0
- package/dist/src/checker/type-system.js +569 -0
- package/dist/src/checker/type-system.js.map +1 -0
- package/dist/src/checker/typecheck-types.d.ts +22 -0
- package/dist/src/checker/typecheck-types.js +109 -0
- package/dist/src/checker/typecheck-types.js.map +1 -0
- package/dist/src/checker/typecheck.d.ts +62 -0
- package/dist/src/checker/typecheck.js +574 -0
- package/dist/src/checker/typecheck.js.map +1 -0
- package/dist/src/checker/undefined.d.ts +14 -0
- package/dist/src/checker/undefined.js +32 -0
- package/dist/src/checker/undefined.js.map +1 -0
- package/dist/src/checker/walk.d.ts +10 -0
- package/dist/src/checker/walk.js +15 -0
- package/dist/src/checker/walk.js.map +1 -0
- package/dist/src/cli/help.d.ts +7 -0
- package/dist/src/cli/help.js +64 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/hints.js +2 -1
- package/dist/src/cli/hints.js.map +1 -1
- package/dist/src/cli/main.js +12 -48
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/calls/access.js +8 -8
- package/dist/src/codegen/generator/calls/access.js.map +1 -1
- package/dist/src/codegen/generator/calls/invocation.js +9 -4
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
- package/dist/src/codegen/generator/calls/super.d.ts +9 -1
- package/dist/src/codegen/generator/calls/super.js +56 -5
- package/dist/src/codegen/generator/calls/super.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +13 -2
- package/dist/src/codegen/generator/context.js +25 -19
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/debug.js +2 -1
- package/dist/src/codegen/generator/debug.js.map +1 -1
- package/dist/src/codegen/generator/expressions/primary.d.ts +4 -1
- package/dist/src/codegen/generator/expressions/primary.js +68 -8
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
- package/dist/src/codegen/generator/generator.js +11 -1
- package/dist/src/codegen/generator/generator.js.map +1 -1
- package/dist/src/codegen/generator/module.d.ts +3 -0
- package/dist/src/codegen/generator/module.js +116 -26
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/state.d.ts +11 -1
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/variables.js +26 -7
- package/dist/src/codegen/generator/statements/variables.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +2 -0
- package/dist/src/codegen/generator/tables.js +4 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/driver/build-key.d.ts +2 -0
- package/dist/src/driver/build-key.js +1 -0
- package/dist/src/driver/build-key.js.map +1 -1
- package/dist/src/driver/bundler/graph.js +5 -1
- package/dist/src/driver/bundler/graph.js.map +1 -1
- package/dist/src/driver/bundler/merge.js +16 -1
- package/dist/src/driver/bundler/merge.js.map +1 -1
- package/dist/src/driver/bundler/types.d.ts +12 -0
- package/dist/src/driver/compiler.d.ts +1 -1
- package/dist/src/driver/compiler.js +3 -0
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/fingerprint.js +2 -1
- package/dist/src/driver/fingerprint.js.map +1 -1
- package/dist/src/driver/frontend.d.ts +8 -6
- package/dist/src/driver/frontend.js +4 -0
- package/dist/src/driver/frontend.js.map +1 -1
- package/dist/src/driver/options.d.ts +6 -0
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/src/extensions/gui/css.d.ts +26 -0
- package/dist/src/extensions/gui/css.js +100 -0
- package/dist/src/extensions/gui/css.js.map +1 -0
- package/dist/src/extensions/gui/html.js +28 -7
- package/dist/src/extensions/gui/html.js.map +1 -1
- package/dist/src/extensions/gui/index.js +79 -2
- package/dist/src/extensions/gui/index.js.map +1 -1
- package/dist/src/extensions/gui/three.d.ts +16 -0
- package/dist/src/extensions/gui/three.js +22 -0
- package/dist/src/extensions/gui/three.js.map +1 -0
- package/dist/src/extensions/media/index.d.ts +6 -5
- package/dist/src/extensions/media/index.js +12 -14
- package/dist/src/extensions/media/index.js.map +1 -1
- package/dist/src/extensions/registry.d.ts +38 -0
- package/dist/src/extensions/registry.js +10 -0
- package/dist/src/extensions/registry.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/declarations/classes.js +7 -0
- package/dist/src/parser/declarations/classes.js.map +1 -1
- package/dist/src/parser/expressions.js +14 -1
- package/dist/src/parser/expressions.js.map +1 -1
- package/dist/src/parser/literals.js +6 -2
- package/dist/src/parser/literals.js.map +1 -1
- package/dist/tests/binder/binder.test.js +29 -0
- package/dist/tests/binder/binder.test.js.map +1 -1
- package/dist/tests/canonical.test.d.ts +1 -0
- package/dist/tests/canonical.test.js +19 -0
- package/dist/tests/canonical.test.js.map +1 -0
- package/dist/tests/checker/checker.test.d.ts +1 -0
- package/dist/tests/checker/checker.test.js +245 -0
- package/dist/tests/checker/checker.test.js.map +1 -0
- package/dist/tests/cli/check.test.js +20 -0
- package/dist/tests/cli/check.test.js.map +1 -1
- package/dist/tests/conformance/matrix.test.d.ts +6 -0
- package/dist/tests/conformance/matrix.test.js +23 -0
- package/dist/tests/conformance/matrix.test.js.map +1 -0
- package/dist/tests/conformance/test262/manifest.d.ts +115 -0
- package/dist/tests/conformance/test262/manifest.js +257 -0
- package/dist/tests/conformance/test262/manifest.js.map +1 -0
- package/dist/tests/conformance/test262.test.d.ts +11 -0
- package/dist/tests/conformance/test262.test.js +74 -0
- package/dist/tests/conformance/test262.test.js.map +1 -0
- package/dist/tests/docs/structure.test.js +9 -11
- package/dist/tests/docs/structure.test.js.map +1 -1
- package/dist/tests/e2e/child-process.test.js +3 -2
- package/dist/tests/e2e/child-process.test.js.map +1 -1
- package/dist/tests/e2e/compile-builtins.test.js +45 -0
- package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
- package/dist/tests/e2e/compile-objects-classes.test.js +77 -0
- package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
- package/dist/tests/e2e/differential-syntax.test.d.ts +5 -0
- package/dist/tests/e2e/differential-syntax.test.js +95 -0
- package/dist/tests/e2e/differential-syntax.test.js.map +1 -0
- package/dist/tests/e2e/differential-values.test.js +15 -0
- package/dist/tests/e2e/differential-values.test.js.map +1 -1
- package/dist/tests/e2e/gui-browser.test.d.ts +13 -0
- package/dist/tests/e2e/gui-browser.test.js +163 -0
- package/dist/tests/e2e/gui-browser.test.js.map +1 -0
- package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
- package/dist/tests/e2e/gui-effects.test.js +262 -0
- package/dist/tests/e2e/gui-effects.test.js.map +1 -0
- package/dist/tests/e2e/gui-example-browser.test.js +2 -2
- package/dist/tests/e2e/gui-example-browser.test.js.map +1 -1
- package/dist/tests/e2e/gui-example-canvas.test.js +5 -4
- package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
- package/dist/tests/e2e/gui-example-svg.test.js +4 -3
- package/dist/tests/e2e/gui-example-svg.test.js.map +1 -1
- package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
- package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
- package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
- package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
- package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
- package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
- package/dist/tests/e2e/gui-example.test.js +4 -3
- package/dist/tests/e2e/gui-example.test.js.map +1 -1
- package/dist/tests/e2e/gui-helpers.js +4 -3
- package/dist/tests/e2e/gui-helpers.js.map +1 -1
- package/dist/tests/e2e/gui-layout.test.js +48 -0
- package/dist/tests/e2e/gui-layout.test.js.map +1 -1
- package/dist/tests/e2e/gui-media.test.js +10 -8
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
- package/dist/tests/e2e/gui-webgl.test.js +179 -0
- package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
- package/dist/tests/e2e/gui-webgl2.test.js +238 -0
- package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
- package/dist/tests/e2e/harness.d.ts +9 -0
- package/dist/tests/e2e/harness.js +14 -2
- package/dist/tests/e2e/harness.js.map +1 -1
- package/dist/tests/e2e/native-extensions.test.js +2 -1
- package/dist/tests/e2e/native-extensions.test.js.map +1 -1
- package/dist/tests/e2e/property-descriptors.test.js +20 -0
- package/dist/tests/e2e/property-descriptors.test.js.map +1 -1
- package/dist/tests/e2e/unicode-output.test.js +5 -3
- package/dist/tests/e2e/unicode-output.test.js.map +1 -1
- package/dist/tests/e2e/weak-collections.test.js +16 -2
- package/dist/tests/e2e/weak-collections.test.js.map +1 -1
- package/dist/tests/extensions/gui.test.js +41 -0
- package/dist/tests/extensions/gui.test.js.map +1 -1
- package/dist/tests/extensions/media.test.js +7 -3
- package/dist/tests/extensions/media.test.js.map +1 -1
- package/dist/tests/helpers.d.ts +1 -0
- package/dist/tests/helpers.js +1 -0
- package/dist/tests/helpers.js.map +1 -1
- package/dist/tests/parser/declarations.test.js +20 -0
- package/dist/tests/parser/declarations.test.js.map +1 -1
- package/dist/tests/parser/expressions.test.js +36 -0
- package/dist/tests/parser/expressions.test.js.map +1 -1
- package/dist/tests/platform.d.ts +32 -0
- package/dist/tests/platform.js +40 -0
- package/dist/tests/platform.js.map +1 -0
- package/dist/tests/platform.test.d.ts +12 -0
- package/dist/tests/platform.test.js +51 -0
- package/dist/tests/platform.test.js.map +1 -0
- package/dist/tests/version.test.js +4 -4
- package/dist/tests/version.test.js.map +1 -1
- package/doc/ai/README.md +10 -4
- package/doc/ai/build-recipe.md +1 -0
- package/doc/ai/cli.md +17 -5
- package/doc/ai/contributing.md +59 -2
- package/doc/ai/extensions.md +38 -7
- package/doc/ai/language-support.md +25 -16
- package/doc/ai/troubleshooting.md +12 -8
- package/doc/ai/zh-CN/README.md +9 -4
- package/doc/ai/zh-CN/build-recipe.md +1 -0
- package/doc/ai/zh-CN/cli.md +13 -3
- package/doc/ai/zh-CN/contributing.md +49 -3
- package/doc/ai/zh-CN/extensions.md +33 -6
- package/doc/ai/zh-CN/language-support.md +23 -14
- package/doc/ai/zh-CN/troubleshooting.md +10 -6
- package/doc/gui/api.md +47 -1
- package/doc/gui/build.md +72 -16
- package/doc/gui/canvas.md +11 -3
- package/doc/gui/dom.md +33 -18
- package/doc/gui/known-issues.md +58 -15
- package/doc/gui/layout.md +18 -0
- package/doc/gui/media.md +17 -13
- package/doc/gui/rendering.md +50 -3
- package/doc/gui/runtime.md +18 -0
- package/doc/gui/webgl.md +256 -0
- package/doc/gui-scripts.md +7 -0
- package/doc/gui.md +108 -17
- package/doc/implemented/binder.md +2 -0
- package/doc/implemented/checker.md +117 -0
- package/doc/implemented/cli.md +13 -1
- package/doc/implemented/codegen.md +3 -2
- package/doc/implemented/driver.md +2 -2
- package/doc/implemented/operators.md +2 -1
- package/doc/implemented/parser.md +3 -2
- package/doc/implemented/pipeline.md +8 -1
- package/doc/implemented/stdlib.md +2 -1
- package/doc/implemented/tests.md +3 -1
- package/doc/implemented.md +2 -0
- package/doc/npm-package.md +419 -0
- package/doc/requirements.md +22 -10
- package/doc/support-matrix.md +83 -0
- package/doc/unimplemented/classes.md +3 -0
- package/doc/unimplemented/deviations.md +3 -2
- package/doc/unimplemented/toolchain.md +1 -1
- package/doc/unimplemented/types.md +24 -8
- package/doc/unimplemented.md +1 -1
- package/doc/zh-CN/gui/api.md +43 -1
- package/doc/zh-CN/gui/build.md +64 -15
- package/doc/zh-CN/gui/canvas.md +9 -2
- package/doc/zh-CN/gui/dom.md +20 -7
- package/doc/zh-CN/gui/known-issues.md +46 -13
- package/doc/zh-CN/gui/layout.md +14 -0
- package/doc/zh-CN/gui/media.md +15 -11
- package/doc/zh-CN/gui/rendering.md +41 -4
- package/doc/zh-CN/gui/runtime.md +16 -0
- package/doc/zh-CN/gui/webgl.md +115 -0
- package/doc/zh-CN/gui-scripts.md +5 -0
- package/doc/zh-CN/gui.md +89 -14
- package/doc/zh-CN/implemented/binder.md +2 -0
- package/doc/zh-CN/implemented/checker.md +99 -0
- package/doc/zh-CN/implemented/cli.md +12 -1
- package/doc/zh-CN/implemented/codegen.md +3 -2
- package/doc/zh-CN/implemented/driver.md +2 -2
- package/doc/zh-CN/implemented/operators.md +1 -1
- package/doc/zh-CN/implemented/parser.md +3 -2
- package/doc/zh-CN/implemented/pipeline.md +3 -1
- package/doc/zh-CN/implemented/stdlib.md +2 -1
- package/doc/zh-CN/implemented/tests.md +3 -1
- package/doc/zh-CN/implemented.md +2 -0
- package/doc/zh-CN/npm-package.md +394 -0
- package/doc/zh-CN/post/announce.md +47 -47
- package/doc/zh-CN/requirements.md +16 -7
- package/doc/zh-CN/support-matrix.md +82 -0
- package/doc/zh-CN/unimplemented/classes.md +3 -0
- package/doc/zh-CN/unimplemented/deviations.md +3 -2
- package/doc/zh-CN/unimplemented/toolchain.md +1 -1
- package/doc/zh-CN/unimplemented/types.md +16 -6
- package/doc/zh-CN/unimplemented.md +1 -1
- package/llms.txt +6 -1
- package/package.json +2 -1
- package/runtime/ext_gui/audio.cpp +316 -0
- package/runtime/ext_gui/browser.cpp +573 -0
- package/runtime/ext_gui/browser_escape.cpp +85 -0
- package/runtime/ext_gui/browser_loop.cpp +83 -0
- package/runtime/ext_gui/canvas.cpp +12 -21
- package/runtime/ext_gui/canvas_internal.h +10 -0
- package/runtime/ext_gui/canvas_raster.cpp +79 -1
- package/runtime/ext_gui/clip_values.cpp +246 -0
- package/runtime/ext_gui/css.cpp +94 -0
- package/runtime/ext_gui/css.h +22 -1
- package/runtime/ext_gui/css_match.cpp +3 -0
- package/runtime/ext_gui/css_selector.cpp +9 -0
- package/runtime/ext_gui/css_sheet.cpp +89 -45
- package/runtime/ext_gui/document.cpp +4 -1
- package/runtime/ext_gui/document.h +2 -0
- package/runtime/ext_gui/dom.h +16 -0
- package/runtime/ext_gui/dom_api.cpp +37 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
- package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
- package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
- package/runtime/ext_gui/dom_api_document.cpp +96 -5
- package/runtime/ext_gui/dom_api_events.cpp +20 -0
- package/runtime/ext_gui/dom_api_internal.h +278 -0
- package/runtime/ext_gui/dom_api_proto.cpp +6 -0
- package/runtime/ext_gui/dom_api_webgl.cpp +376 -0
- package/runtime/ext_gui/dom_api_webgl2.cpp +434 -0
- package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
- package/runtime/ext_gui/dom_api_webgl_buffer.cpp +212 -0
- package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
- package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
- package/runtime/ext_gui/dom_api_webgl_state.cpp +444 -0
- package/runtime/ext_gui/dom_api_webgl_texture.cpp +445 -0
- package/runtime/ext_gui/effect_values.cpp +312 -0
- package/runtime/ext_gui/gradient_values.cpp +476 -0
- package/runtime/ext_gui/grid_values.cpp +230 -0
- package/runtime/ext_gui/gui.cpp +90 -23
- package/runtime/ext_gui/gui_canvas.cpp +50 -2
- package/runtime/ext_gui/gui_engine.h +71 -0
- package/runtime/ext_gui/gui_events.cpp +4 -1
- package/runtime/ext_gui/gui_media.cpp +1 -1
- package/runtime/ext_gui/gui_webgl.cpp +83 -0
- package/runtime/ext_gui/layout.cpp +21 -0
- package/runtime/ext_gui/layout_flow.cpp +81 -4
- package/runtime/ext_gui/layout_flow_internal.h +31 -0
- package/runtime/ext_gui/layout_grid.cpp +374 -0
- package/runtime/ext_gui/media.h +1 -1
- package/runtime/ext_gui/media_api.h +2 -2
- package/runtime/ext_gui/media_query.cpp +211 -0
- package/runtime/ext_gui/paint.cpp +111 -77
- package/runtime/ext_gui/paint.h +33 -3
- package/runtime/ext_gui/paint_background.cpp +229 -0
- package/runtime/ext_gui/paint_clip.cpp +268 -0
- package/runtime/ext_gui/paint_effects.cpp +324 -0
- package/runtime/ext_gui/paint_internal.h +85 -0
- package/runtime/ext_gui/renderer.cpp +8 -31
- package/runtime/ext_gui/renderer_clip.cpp +196 -0
- package/runtime/ext_gui/renderer_image.cpp +13 -8
- package/runtime/ext_gui/renderer_internal.h +15 -8
- package/runtime/ext_gui/renderer_text.cpp +6 -31
- package/runtime/ext_gui/style.cpp +343 -20
- package/runtime/ext_gui/style.h +144 -3
- package/runtime/ext_gui/style_print.cpp +134 -1
- package/runtime/ext_gui/style_values.cpp +152 -126
- package/runtime/ext_gui/style_values_internal.h +35 -0
- package/runtime/ext_gui/webgl.h +466 -0
- package/runtime/ext_gui/webgl2_constants.h +274 -0
- package/runtime/ext_gui/webgl_buffer.cpp +565 -0
- package/runtime/ext_gui/webgl_constants.h +317 -0
- package/runtime/ext_gui/webgl_context.cpp +466 -0
- package/runtime/ext_gui/webgl_draw.cpp +495 -0
- package/runtime/ext_gui/webgl_glsl.h +125 -0
- package/runtime/ext_gui/webgl_glsl_compile.cpp +431 -0
- package/runtime/ext_gui/webgl_glsl_rewrite.cpp +349 -0
- package/runtime/ext_gui/webgl_glsl_scan.cpp +581 -0
- package/runtime/ext_gui/webgl_msl.cpp +62 -0
- package/runtime/ext_gui/webgl_msl.h +33 -0
- package/runtime/ext_gui/webgl_pipeline.cpp +274 -0
- package/runtime/ext_gui/webgl_program_internal.h +18 -0
- package/runtime/ext_gui/webgl_shader.cpp +582 -0
- package/runtime/ext_gui/webgl_texture.cpp +293 -0
- package/runtime/ext_gui/webgl_uniform.cpp +167 -0
- package/runtime/ext_gui/webgl_webgl2.cpp +224 -0
- package/runtime/ext_gui/window.cpp +9 -0
- package/runtime/ext_media/media.cpp +1 -1
- package/runtime/ext_media/media_bridge.c +9 -3
- package/runtime/ext_node/path/path.c +7 -7
- package/runtime/ext_node/url/url.c +4 -2
- package/runtime/rt.h +15 -0
- package/runtime/rt_internal.h +1 -0
- package/runtime/xt_constructors.c +2 -1
- package/runtime/xt_containers/access.inc +8 -0
- package/runtime/xt_containers/objects.inc +22 -2
- package/runtime/xt_io/exception.inc +4 -2
- package/runtime/xt_regex/api.inc +2 -0
- package/runtime/xt_regex/matcher.inc +16 -3
- package/runtime/xt_regex/parser.inc +8 -2
- package/runtime/xt_regex/types.inc +3 -0
- package/runtime/xt_stdlib/math.inc +62 -0
- package/runtime/xt_stdlib2/date.inc +7 -1
- package/runtime/xt_stdlib2/objects.inc +14 -0
- package/runtime/xt_stdlib2/regexp-match.inc +60 -21
- package/runtime/xt_stdlib2/regexp.inc +1 -0
- package/runtime/xt_typed_array.c +1 -1
- package/scripts/build-gui.ts +90 -3
- package/scripts/build-media.ts +323 -58
- package/scripts/setup-vs-toolchain.ps1 +152 -0
- package/scripts/support-matrix.ts +167 -0
- package/src/ast/common.ts +2 -0
- package/src/ast/declarations.ts +12 -1
- package/src/ast/expressions.ts +6 -0
- package/src/ast/kinds.ts +2 -0
- package/src/binder/binder.ts +3 -0
- package/src/binder/declarations.ts +70 -0
- package/src/binder/references.ts +97 -4
- package/src/binder/types.ts +30 -0
- package/src/canonical.ts +37 -0
- package/src/checker/assignability.ts +134 -0
- package/src/checker/calls.ts +135 -0
- package/src/checker/checker.ts +47 -0
- package/src/checker/declarations.ts +26 -0
- package/src/checker/flow.ts +236 -0
- package/src/checker/globals.ts +40 -0
- package/src/checker/source.ts +53 -0
- package/src/checker/type-infer.ts +185 -0
- package/src/checker/type-model.ts +212 -0
- package/src/checker/type-system.ts +578 -0
- package/src/checker/typecheck-types.ts +112 -0
- package/src/checker/typecheck.ts +586 -0
- package/src/checker/undefined.ts +43 -0
- package/src/checker/walk.ts +16 -0
- package/src/cli/help.ts +65 -0
- package/src/cli/hints.ts +2 -1
- package/src/cli/main.ts +12 -49
- package/src/codegen/generator/calls/access.ts +8 -8
- package/src/codegen/generator/calls/invocation.ts +8 -5
- package/src/codegen/generator/calls/super.ts +67 -5
- package/src/codegen/generator/context.ts +31 -19
- package/src/codegen/generator/debug.ts +2 -1
- package/src/codegen/generator/expressions/primary.ts +84 -13
- package/src/codegen/generator/generator.ts +11 -1
- package/src/codegen/generator/module.ts +115 -24
- package/src/codegen/generator/state.ts +11 -1
- package/src/codegen/generator/statements/variables.ts +26 -6
- package/src/codegen/generator/tables.ts +5 -0
- package/src/driver/build-key.ts +3 -0
- package/src/driver/bundler/graph.ts +6 -2
- package/src/driver/bundler/merge.ts +14 -1
- package/src/driver/bundler/types.ts +13 -0
- package/src/driver/compiler.ts +4 -1
- package/src/driver/fingerprint.ts +2 -1
- package/src/driver/frontend.ts +13 -2
- package/src/driver/options.ts +6 -0
- package/src/driver/version.ts +1 -1
- package/src/extensions/gui/css.ts +113 -0
- package/src/extensions/gui/html.ts +31 -11
- package/src/extensions/gui/index.ts +81 -2
- package/src/extensions/gui/three.ts +25 -0
- package/src/extensions/media/index.ts +13 -16
- package/src/extensions/registry.ts +48 -0
- package/src/index.ts +1 -0
- package/src/parser/declarations/classes.ts +7 -0
- package/src/parser/expressions.ts +13 -1
- package/src/parser/literals.ts +6 -2
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import type { SourceFileNode } from "../../ast/nodes.js";
|
|
11
11
|
import type { DiagnosticBag } from "../../diagnostics/diagnostic.js";
|
|
12
|
+
import { bind } from "../../binder/binder.js";
|
|
13
|
+
import { checkProgram } from "../../checker/checker.js";
|
|
12
14
|
import { GeneratorContext } from "./context.js";
|
|
13
15
|
import { moduleMethods, type ModuleMethods } from "./module.js";
|
|
14
16
|
import { statementMethods, type StatementMethods } from "./statements.js";
|
|
@@ -45,6 +47,14 @@ export function generate(
|
|
|
45
47
|
diagnostics: DiagnosticBag,
|
|
46
48
|
options: CodegenOptions = {},
|
|
47
49
|
): CodegenResult {
|
|
48
|
-
|
|
50
|
+
// Bind once: the checker and the generator must see the same symbol table.
|
|
51
|
+
const binding = bind(sourceFile);
|
|
52
|
+
if (options.check !== false) {
|
|
53
|
+
checkProgram(sourceFile, binding, diagnostics, {
|
|
54
|
+
builtins: options.builtins ?? {},
|
|
55
|
+
globalValues: options.globalValues ?? {},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const generator = new Generator(sourceFile, diagnostics, options, binding);
|
|
49
59
|
return { ir: generator.run(), binding: generator.binding };
|
|
50
60
|
}
|
|
@@ -9,11 +9,13 @@ import {
|
|
|
9
9
|
type ArrowFunction,
|
|
10
10
|
type Block,
|
|
11
11
|
type Expression,
|
|
12
|
+
type FunctionDeclaration,
|
|
12
13
|
type Parameter,
|
|
13
14
|
} from "../../ast/nodes.js";
|
|
14
15
|
import type { ClassInfo, FunctionInfo, SymbolInfo } from "../../binder/binder.js";
|
|
15
16
|
import { SymbolKind } from "../../binder/binder.js";
|
|
16
17
|
import { i64, XT_UNDEFINED } from "../values.js";
|
|
18
|
+
import { ARTIFACT_LINE_ENDING, artifactPath } from "../../canonical.js";
|
|
17
19
|
import { RUNTIME_DECLARATIONS, type FunctionState } from "./state.js";
|
|
18
20
|
import { propertyNameText } from "./tables.js";
|
|
19
21
|
import type { Generator } from "./generator.js";
|
|
@@ -38,12 +40,15 @@ function symbolSuffix(name: string): string {
|
|
|
38
40
|
export interface ModuleMethods {
|
|
39
41
|
run(this: Generator): string;
|
|
40
42
|
emitFunction(this: Generator, fn: FunctionInfo): void;
|
|
43
|
+
emitHoistedFunctions(this: Generator, fn: FunctionInfo): void;
|
|
41
44
|
emitFunctionReturn(this: Generator, value: string): void;
|
|
42
45
|
emitMain(this: Generator): void;
|
|
43
46
|
functionName(this: Generator, fn: FunctionInfo): string;
|
|
44
47
|
classGlobal(this: Generator, classInfo: ClassInfo): string;
|
|
45
48
|
emitClassReference(this: Generator, classInfo: ClassInfo): string;
|
|
46
49
|
emitClassSetup(this: Generator, classInfo: ClassInfo): void;
|
|
50
|
+
memberKey(this: Generator, method: FunctionInfo): string;
|
|
51
|
+
emitMemberDefine(this: Generator, target: string, method: FunctionInfo, key: string, fnValue: string): void;
|
|
47
52
|
emitDefaultParameter(this: Generator, symbol: SymbolInfo, value: string, initializer: Expression): void;
|
|
48
53
|
}
|
|
49
54
|
|
|
@@ -75,7 +80,7 @@ export const moduleMethods: ModuleMethods = {
|
|
|
75
80
|
// the self-hosting fixpoint) is identical whether the compiler runs on
|
|
76
81
|
// Node (which uses `\` on Windows) or as a compiled binary (which always
|
|
77
82
|
// produces `/`).
|
|
78
|
-
const sourceName = this.sourceFile.fileName
|
|
83
|
+
const sourceName = artifactPath(this.sourceFile.fileName);
|
|
79
84
|
const header = [
|
|
80
85
|
"; ModuleID = 'xbintsc'",
|
|
81
86
|
"source_filename = \"" + sourceName + "\"",
|
|
@@ -93,7 +98,7 @@ export const moduleMethods: ModuleMethods = {
|
|
|
93
98
|
...this.functions,
|
|
94
99
|
"",
|
|
95
100
|
...this.debugMetadataLines(),
|
|
96
|
-
].join(
|
|
101
|
+
].join(ARTIFACT_LINE_ENDING);
|
|
97
102
|
},
|
|
98
103
|
|
|
99
104
|
// -- module level --------------------------------------------------------
|
|
@@ -149,7 +154,7 @@ export const moduleMethods: ModuleMethods = {
|
|
|
149
154
|
/* Normalise separators like `source_filename`: the compiler may run under
|
|
150
155
|
* Node (`\`) or as a self-hosted binary (`/`), and the IR must stay
|
|
151
156
|
* byte-identical across the two. */
|
|
152
|
-
const filePointer = this.internStatic(this.fileNameOf(fn.node)
|
|
157
|
+
const filePointer = this.internStatic(artifactPath(this.fileNameOf(fn.node)));
|
|
153
158
|
this.emit(
|
|
154
159
|
` call void @xt_stack_push(i8* ${namePointer}, i8* ${filePointer}, i32 ${this.lineOf(fn.node)})`,
|
|
155
160
|
);
|
|
@@ -189,6 +194,14 @@ export const moduleMethods: ModuleMethods = {
|
|
|
189
194
|
this.defineCaptureSlot(symbol, value);
|
|
190
195
|
}
|
|
191
196
|
|
|
197
|
+
// Hoisted function declarations: create their closure values in this
|
|
198
|
+
// frame (before the body runs) so a nested function that references one
|
|
199
|
+
// gets the closure built against the declaring frame, not against the
|
|
200
|
+
// caller's slots. Captured function symbols are boxed by the binder, so
|
|
201
|
+
// the second pass publishes the closures into those boxes and mutual
|
|
202
|
+
// recursion sees the same values.
|
|
203
|
+
this.emitHoistedFunctions(fn);
|
|
204
|
+
|
|
192
205
|
// Arrow functions inherit `this` lexically; it travels as an extra capture.
|
|
193
206
|
if (fn.isArrow && fn.capturesThis) {
|
|
194
207
|
const inherited = this.reg();
|
|
@@ -267,7 +280,7 @@ export const moduleMethods: ModuleMethods = {
|
|
|
267
280
|
? state.escapePointers.map((ptr) => ` call void asm sideeffect "", "r"(i64* ${ptr})`)
|
|
268
281
|
: [];
|
|
269
282
|
const lines = [...state.allocas.map((a) => ` ${a}`), ...escapes, ...state.buffer];
|
|
270
|
-
this.functions.push([header, ...lines, "}", ""].join(
|
|
283
|
+
this.functions.push([header, ...lines, "}", ""].join(ARTIFACT_LINE_ENDING));
|
|
271
284
|
},
|
|
272
285
|
|
|
273
286
|
emitMain(): void {
|
|
@@ -307,7 +320,7 @@ export const moduleMethods: ModuleMethods = {
|
|
|
307
320
|
" ret i32 0",
|
|
308
321
|
"}",
|
|
309
322
|
"",
|
|
310
|
-
].join(
|
|
323
|
+
].join(ARTIFACT_LINE_ENDING),
|
|
311
324
|
);
|
|
312
325
|
},
|
|
313
326
|
|
|
@@ -334,6 +347,46 @@ export const moduleMethods: ModuleMethods = {
|
|
|
334
347
|
return name;
|
|
335
348
|
},
|
|
336
349
|
|
|
350
|
+
emitHoistedFunctions(fn: FunctionInfo): void {
|
|
351
|
+
if (fn.isModule) return;
|
|
352
|
+
const body = (fn.node as { body?: Block }).body;
|
|
353
|
+
if (!body || body.kind !== SyntaxKind.Block) return;
|
|
354
|
+
const declarations: FunctionDeclaration[] = [];
|
|
355
|
+
for (const statement of body.statements) {
|
|
356
|
+
if (statement.kind === SyntaxKind.FunctionDeclaration) {
|
|
357
|
+
declarations.push(statement as FunctionDeclaration);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (declarations.length === 0) return;
|
|
361
|
+
/* Captured locals of this frame may be declared textually after the
|
|
362
|
+
* function that uses them. Function declarations are hoisted, so create
|
|
363
|
+
* their boxes now; the `let`/`const`/`var` statement fills the box when it
|
|
364
|
+
* runs (emitVariableStatement writes into an existing slot). */
|
|
365
|
+
for (const declaration of declarations) {
|
|
366
|
+
const child = this.binding.functionOfNode.get(declaration);
|
|
367
|
+
if (!child) continue;
|
|
368
|
+
for (const captured of child.captures) {
|
|
369
|
+
if (captured.fn !== fn) continue;
|
|
370
|
+
if (!this.current.slots.has(captured.id)) this.declareSlot(captured, i64(XT_UNDEFINED));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/* First pass: a slot (and a box, when captured) exists for every name
|
|
374
|
+
* before any closure is built, so sibling references cannot observe an
|
|
375
|
+
* uninitialised slot. */
|
|
376
|
+
const ready: Array<{ symbol: SymbolInfo; child: FunctionInfo }> = [];
|
|
377
|
+
for (const declaration of declarations) {
|
|
378
|
+
const symbol = this.binding.symbolOfDeclaration.get(declaration);
|
|
379
|
+
const child = this.binding.functionOfNode.get(declaration);
|
|
380
|
+
if (!symbol || !child) continue;
|
|
381
|
+
if (!this.current.slots.has(symbol.id)) this.declareSlot(symbol, i64(XT_UNDEFINED));
|
|
382
|
+
ready.push({ symbol, child });
|
|
383
|
+
}
|
|
384
|
+
/* Second pass: build and store the closures. */
|
|
385
|
+
for (const entry of ready) {
|
|
386
|
+
this.writeSlot(entry.symbol, this.emitClosureValue(entry.child));
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
|
|
337
390
|
emitClassReference(classInfo: ClassInfo): string {
|
|
338
391
|
const globalName = this.classGlobal(classInfo);
|
|
339
392
|
const value = this.reg();
|
|
@@ -346,18 +399,23 @@ export const moduleMethods: ModuleMethods = {
|
|
|
346
399
|
const globalName = this.classGlobal(classInfo);
|
|
347
400
|
const proto = this.reg();
|
|
348
401
|
this.emit(` ${proto} = call i64 @xt_object_new()`);
|
|
402
|
+
/* The parent constructor value, emitted once: it is used both for the
|
|
403
|
+
* instance prototype and for static inheritance (`Dog.kind` sees
|
|
404
|
+
* `Animal.kind`), and evaluating `extends mixin()` twice would run the
|
|
405
|
+
* expression twice. */
|
|
406
|
+
let parentValue: string | undefined;
|
|
349
407
|
if (classInfo.parentExpression) {
|
|
350
408
|
// `extends Error` / `extends TypeError` / other host builtins: chain the
|
|
351
409
|
// subclass prototype onto the builtin's prototype so `instanceof` works.
|
|
352
410
|
const parent = classInfo.parentExpression;
|
|
353
411
|
const errorName = this.errorFamilyName(parent);
|
|
412
|
+
parentValue = this.emitExpression(parent);
|
|
354
413
|
if (errorName) {
|
|
355
414
|
const nameValue = this.stringValue(errorName);
|
|
356
415
|
const parentProto = this.reg();
|
|
357
416
|
this.emit(` ${parentProto} = call i64 @xt_error_prototype(i64 ${nameValue})`);
|
|
358
417
|
this.emit(` call i64 @xt_object_set_prototype(i64 ${proto}, i64 ${parentProto})`);
|
|
359
418
|
} else {
|
|
360
|
-
const parentValue = this.emitExpression(parent);
|
|
361
419
|
const parentProto = this.reg();
|
|
362
420
|
this.emit(` ${parentProto} = call i64 @xt_function_get_prototype(i64 ${parentValue})`);
|
|
363
421
|
this.emit(` call i64 @xt_object_set_prototype(i64 ${proto}, i64 ${parentProto})`);
|
|
@@ -365,36 +423,69 @@ export const moduleMethods: ModuleMethods = {
|
|
|
365
423
|
}
|
|
366
424
|
for (const method of classInfo.methods) {
|
|
367
425
|
const fnValue = this.emitClosureValue(method);
|
|
368
|
-
const key = method
|
|
369
|
-
|
|
370
|
-
: this.stringValue(method.name);
|
|
371
|
-
const accessor = (method.node as { accessor?: "get" | "set" }).accessor;
|
|
372
|
-
if (accessor === "get") {
|
|
373
|
-
this.emit(` call i64 @xt_object_define_getter(i64 ${proto}, i64 ${key}, i64 ${fnValue})`);
|
|
374
|
-
} else if (accessor === "set") {
|
|
375
|
-
this.emit(` call i64 @xt_object_define_setter(i64 ${proto}, i64 ${key}, i64 ${fnValue})`);
|
|
376
|
-
} else {
|
|
377
|
-
this.emit(` call i64 @xt_set(i64 ${proto}, i64 ${key}, i64 ${fnValue})`);
|
|
378
|
-
}
|
|
426
|
+
const key = this.memberKey(method);
|
|
427
|
+
this.emitMemberDefine(proto, method, key, fnValue);
|
|
379
428
|
}
|
|
380
429
|
const ctor = this.emitClosureValue(classInfo.ctor!);
|
|
381
430
|
this.emit(` call i64 @xt_function_set_prototype(i64 ${ctor}, i64 ${proto})`);
|
|
431
|
+
/* Static members are inherited through the constructor's property bag. */
|
|
432
|
+
if (parentValue) {
|
|
433
|
+
this.emit(` call i64 @xt_object_set_prototype(i64 ${ctor}, i64 ${parentValue})`);
|
|
434
|
+
}
|
|
435
|
+
/* `A.prototype.constructor === A`: the standard property, and what
|
|
436
|
+
* `new this.constructor()` (Three.js `Matrix3.clone`, …) relies on. The
|
|
437
|
+
* hidden `__ctor` beside it is the internal hook `super(...)` and the
|
|
438
|
+
* implicit derived constructor read; keeping both means `constructor` can
|
|
439
|
+
* be overwritten by user code without breaking inheritance. */
|
|
382
440
|
const ctorKey = this.stringValue("__ctor");
|
|
383
441
|
this.emit(` call i64 @xt_set(i64 ${proto}, i64 ${ctorKey}, i64 ${ctor})`);
|
|
442
|
+
const constructorKey = this.stringValue("constructor");
|
|
443
|
+
this.emit(` call i64 @xt_set(i64 ${proto}, i64 ${constructorKey}, i64 ${ctor})`);
|
|
444
|
+
/* Publish the constructor before static fields and blocks run: they may
|
|
445
|
+
* refer to the class by name (`static { A.count = 1 }`), and by then the
|
|
446
|
+
* class binding is already initialised in JavaScript. */
|
|
447
|
+
this.emit(` store i64 ${ctor}, i64* ${globalName}`);
|
|
384
448
|
for (const method of classInfo.statics) {
|
|
385
449
|
const fnValue = this.emitClosureValue(method);
|
|
386
|
-
const key = method
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
this.
|
|
450
|
+
const key = this.memberKey(method);
|
|
451
|
+
/* `static get x()` / `static set x(v)` are accessors on the constructor
|
|
452
|
+
* value, not plain data properties. */
|
|
453
|
+
this.emitMemberDefine(ctor, method, key, fnValue);
|
|
390
454
|
}
|
|
391
|
-
for (const
|
|
392
|
-
if (
|
|
455
|
+
for (const entry of classInfo.staticInit) {
|
|
456
|
+
if (entry.kind === "block") {
|
|
457
|
+
/* `static { ... }` blocks run once, in order, with `this` bound to the
|
|
458
|
+
* class constructor. They are compiled as static methods and called
|
|
459
|
+
* immediately, which gives them their own scope and a normal `this`. */
|
|
460
|
+
const fnValue = this.emitClosureValue(entry.fn);
|
|
461
|
+
this.emit(` call i64 @xt_call_with_this(i64 ${fnValue}, i64 ${ctor}, i32 0, i64* null)`);
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
const field = entry.field;
|
|
393
465
|
const key = this.stringValue(field.name);
|
|
394
466
|
const value = field.initializer ? this.emitExpression(field.initializer) : i64(XT_UNDEFINED);
|
|
395
467
|
this.emit(` call i64 @xt_set(i64 ${ctor}, i64 ${key}, i64 ${value})`);
|
|
396
468
|
}
|
|
397
|
-
|
|
469
|
+
},
|
|
470
|
+
|
|
471
|
+
/** The property key of a class member: evaluated when computed. */
|
|
472
|
+
memberKey(method: FunctionInfo): string {
|
|
473
|
+
return method.computedKey
|
|
474
|
+
? this.emitExpression(method.computedKey)
|
|
475
|
+
: this.stringValue(method.name);
|
|
476
|
+
},
|
|
477
|
+
|
|
478
|
+
/** Install a class member as a data property, or as an accessor when it was
|
|
479
|
+
* declared with `get` / `set`. */
|
|
480
|
+
emitMemberDefine(target: string, method: FunctionInfo, key: string, fnValue: string): void {
|
|
481
|
+
const accessor = (method.node as { accessor?: "get" | "set" }).accessor;
|
|
482
|
+
if (accessor === "get") {
|
|
483
|
+
this.emit(` call i64 @xt_object_define_getter(i64 ${target}, i64 ${key}, i64 ${fnValue})`);
|
|
484
|
+
} else if (accessor === "set") {
|
|
485
|
+
this.emit(` call i64 @xt_object_define_setter(i64 ${target}, i64 ${key}, i64 ${fnValue})`);
|
|
486
|
+
} else {
|
|
487
|
+
this.emit(` call i64 @xt_set(i64 ${target}, i64 ${key}, i64 ${fnValue})`);
|
|
488
|
+
}
|
|
398
489
|
},
|
|
399
490
|
|
|
400
491
|
emitDefaultParameter(symbol: SymbolInfo, value: string, initializer: Expression): void {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import type { FunctionInfo } from "../../binder/binder.js";
|
|
6
6
|
import type { BindResult } from "../../binder/binder.js";
|
|
7
|
-
import type { BuiltinFunction, ExtensionModule } from "../../extensions/registry.js";
|
|
7
|
+
import type { BuiltinFunction, ExtensionModule, GlobalValue } from "../../extensions/registry.js";
|
|
8
8
|
import type { Block } from "../../ast/nodes.js";
|
|
9
9
|
|
|
10
10
|
export interface Slot {
|
|
@@ -70,6 +70,8 @@ export interface CodegenResult {
|
|
|
70
70
|
export interface CodegenOptions {
|
|
71
71
|
/** Global names supplied by registered extensions. */
|
|
72
72
|
readonly builtins?: Readonly<Record<string, BuiltinFunction>>;
|
|
73
|
+
/** Global *values* supplied by registered extensions (`window`, `document`). */
|
|
74
|
+
readonly globalValues?: Readonly<Record<string, GlobalValue>>;
|
|
73
75
|
/** Importable modules supplied by registered extensions. */
|
|
74
76
|
readonly modules?: Readonly<Record<string, ExtensionModule>>;
|
|
75
77
|
/**
|
|
@@ -91,6 +93,14 @@ export interface CodegenOptions {
|
|
|
91
93
|
* debugging; `xbintsc build --debug` turns it on.
|
|
92
94
|
*/
|
|
93
95
|
readonly debug?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Run the semantic checker before lowering (default **true**). It reports
|
|
98
|
+
* unresolved names, redeclarations and call-arity mismatches; `--no-check`
|
|
99
|
+
* (or `check: false` programmatically) restores the previous permissive
|
|
100
|
+
* behaviour. Code generation skips its own unresolved-name diagnostic while
|
|
101
|
+
* the checker is on, so the error is reported exactly once.
|
|
102
|
+
*/
|
|
103
|
+
readonly check?: boolean;
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
export const RUNTIME_DECLARATIONS: readonly string[] = [
|
|
@@ -33,9 +33,12 @@ export const variableStatementMethods: VariableStatementMethods = {
|
|
|
33
33
|
continue;
|
|
34
34
|
}
|
|
35
35
|
if (this.current.slots.has(symbol.id)) {
|
|
36
|
-
// Hoisted `var
|
|
37
|
-
//
|
|
38
|
-
|
|
36
|
+
// Hoisted `var`, or a box created early for a captured binding
|
|
37
|
+
// declared textually after a hoisted function: do not redeclare the
|
|
38
|
+
// slot, but assigning an initializer is still part of the statement.
|
|
39
|
+
if (declaration.initializer) {
|
|
40
|
+
this.writeSlot(symbol, this.emitExpression(declaration.initializer));
|
|
41
|
+
}
|
|
39
42
|
continue;
|
|
40
43
|
}
|
|
41
44
|
if (symbol.boxed) {
|
|
@@ -107,17 +110,34 @@ export const variableStatementMethods: VariableStatementMethods = {
|
|
|
107
110
|
}
|
|
108
111
|
},
|
|
109
112
|
|
|
110
|
-
/**
|
|
113
|
+
/**
|
|
114
|
+
* `x = fallback` in a binding pattern: only apply when `x` is `undefined`.
|
|
115
|
+
*
|
|
116
|
+
* The initializer is emitted inside its own block, so it is evaluated *only*
|
|
117
|
+
* when the property is missing — the specification's order. A `select` cannot
|
|
118
|
+
* do that: it would evaluate the fallback unconditionally, which runs side
|
|
119
|
+
* effects and throws for defaults like `canvas = createCanvasElement()` that
|
|
120
|
+
* assume they are only reached when the caller passed nothing.
|
|
121
|
+
*/
|
|
111
122
|
emitBindingDefault(value: string, initializer: Expression): string {
|
|
112
|
-
const
|
|
123
|
+
const slot = this.alloca();
|
|
124
|
+
this.emit(` store i64 ${value}, i64* ${slot}`);
|
|
113
125
|
const isUndefined = this.reg();
|
|
114
126
|
this.emit(` ${isUndefined} = call i64 @xt_seq(i64 ${value}, i64 ${i64(XT_UNDEFINED)})`);
|
|
115
127
|
const truthy = this.reg();
|
|
116
128
|
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${isUndefined})`);
|
|
117
129
|
const condition = this.reg();
|
|
118
130
|
this.emit(` ${condition} = icmp ne i32 ${truthy}, 0`);
|
|
131
|
+
const defaultLabel = this.label("bind.default");
|
|
132
|
+
const endLabel = this.label("bind.end");
|
|
133
|
+
this.terminate(`br i1 ${condition}, label %${defaultLabel}, label %${endLabel}`);
|
|
134
|
+
this.startBlock(defaultLabel);
|
|
135
|
+
const fallback = this.emitExpression(initializer);
|
|
136
|
+
this.emit(` store i64 ${fallback}, i64* ${slot}`);
|
|
137
|
+
this.terminate(`br label %${endLabel}`);
|
|
138
|
+
this.startBlock(endLabel);
|
|
119
139
|
const result = this.reg();
|
|
120
|
-
this.emit(` ${result} =
|
|
140
|
+
this.emit(` ${result} = load i64, i64* ${slot}`);
|
|
121
141
|
return result;
|
|
122
142
|
},
|
|
123
143
|
|
|
@@ -283,6 +283,11 @@ export const SYMBOL_WELL_KNOWN = new Set<string>([
|
|
|
283
283
|
"unscopables",
|
|
284
284
|
]);
|
|
285
285
|
|
|
286
|
+
/** Namespaces that also exist as a first-class object value (`Math.cos`). */
|
|
287
|
+
export const NAMESPACE_VALUES: Record<string, string> = {
|
|
288
|
+
Math: "xt_math_object",
|
|
289
|
+
};
|
|
290
|
+
|
|
286
291
|
/** Namespace identifiers whose property access maps to a runtime getter. */
|
|
287
292
|
export const NAMESPACE_PROPERTIES: Record<string, string> = {
|
|
288
293
|
process: "xt_process_get",
|
package/src/driver/build-key.ts
CHANGED
|
@@ -27,6 +27,8 @@ export interface CacheKeyInput {
|
|
|
27
27
|
readonly app: AppConfig;
|
|
28
28
|
readonly debug: boolean;
|
|
29
29
|
readonly lto: boolean;
|
|
30
|
+
/** Whether the semantic checker ran (default true). */
|
|
31
|
+
readonly check?: boolean;
|
|
30
32
|
readonly pgo?: PgoMode;
|
|
31
33
|
readonly pgoDir: string;
|
|
32
34
|
}
|
|
@@ -49,6 +51,7 @@ export function buildCacheKey(input: CacheKeyInput): string {
|
|
|
49
51
|
app.bundleId ?? "",
|
|
50
52
|
String(input.debug),
|
|
51
53
|
String(input.lto),
|
|
54
|
+
String(input.check !== false),
|
|
52
55
|
pgo ?? "",
|
|
53
56
|
pgo ? input.pgoDir : "",
|
|
54
57
|
]);
|
|
@@ -14,7 +14,7 @@ import { Parser } from "../../parser/parser.js";
|
|
|
14
14
|
import type { AssetLoader } from "../../extensions/registry.js";
|
|
15
15
|
import { classifyDependency } from "./resolve.js";
|
|
16
16
|
import { collectRequireSites, isNodeModulesPath, usesCommonJS } from "./commonjs.js";
|
|
17
|
-
import type { ModuleRecord } from "./types.js";
|
|
17
|
+
import type { ModuleRecord, OriginRange } from "./types.js";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* True when an import has no runtime binding, so it is not a module edge:
|
|
@@ -109,9 +109,12 @@ export function loadGraph(
|
|
|
109
109
|
* module before it is parsed. The core only sees the transformed text. */
|
|
110
110
|
const loader = assetLoaders[extname(path).toLowerCase()];
|
|
111
111
|
let text = raw;
|
|
112
|
+
let originRanges: readonly OriginRange[] | undefined;
|
|
112
113
|
if (loader) {
|
|
113
114
|
try {
|
|
114
|
-
|
|
115
|
+
const loaded = loader(path, raw);
|
|
116
|
+
text = loaded.moduleSource;
|
|
117
|
+
originRanges = loaded.sourceRanges;
|
|
115
118
|
} catch (error) {
|
|
116
119
|
diagnostics.error(
|
|
117
120
|
DiagnosticCode.CodegenError,
|
|
@@ -136,6 +139,7 @@ export function loadGraph(
|
|
|
136
139
|
originalNames: new Map(),
|
|
137
140
|
finalNames: new Map(),
|
|
138
141
|
commonjs: false,
|
|
142
|
+
originRanges,
|
|
139
143
|
};
|
|
140
144
|
// `require` / `module` / `exports` are only honoured inside `node_modules`,
|
|
141
145
|
// so user code keeps its ESM-only diagnostic.
|
|
@@ -176,9 +176,22 @@ export function bundleModules(
|
|
|
176
176
|
* diagnostic can name the right file and line instead of pointing into the
|
|
177
177
|
* entry module (whose text happens to start at the same offsets). */
|
|
178
178
|
const origins = new Map<object, string>();
|
|
179
|
+
/* A synthesized module (an extension asset loader such as the `gui` `.html`
|
|
180
|
+
* transform) may contain spans copied from another file — a `<script
|
|
181
|
+
* src="app.js">` body, say. Nodes inside such a span keep that file, so a
|
|
182
|
+
* diagnostic points at real source and a plain-`.js` script stays exempt
|
|
183
|
+
* from the type checker. */
|
|
184
|
+
const originOf = (record: ModuleRecord, node: Node): string => {
|
|
185
|
+
const ranges = record.originRanges;
|
|
186
|
+
if (ranges === undefined) return record.path;
|
|
187
|
+
for (const range of ranges) {
|
|
188
|
+
if (node.start >= range.start && node.end <= range.end) return range.file;
|
|
189
|
+
}
|
|
190
|
+
return record.path;
|
|
191
|
+
};
|
|
179
192
|
const trackOrigin = (record: ModuleRecord, root: Node): void => {
|
|
180
193
|
const visit = (node: Node): void => {
|
|
181
|
-
origins.set(node, record
|
|
194
|
+
origins.set(node, originOf(record, node));
|
|
182
195
|
const fields = node as unknown as Record<string, unknown>;
|
|
183
196
|
for (const key of Object.keys(fields)) {
|
|
184
197
|
if (key === "kind" || key === "start" || key === "end" || key === "text" || key === "value" || key === "raw") {
|
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
import type { SourceFileNode } from "../../ast/nodes.js";
|
|
6
6
|
import type { BindResult } from "../../binder/binder.js";
|
|
7
7
|
|
|
8
|
+
/** A `[start, end)` span of a synthesized module that came from `file`. */
|
|
9
|
+
export interface OriginRange {
|
|
10
|
+
readonly start: number;
|
|
11
|
+
readonly end: number;
|
|
12
|
+
readonly file: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
export interface ModuleRecord {
|
|
9
16
|
readonly path: string;
|
|
10
17
|
readonly text: string;
|
|
@@ -25,6 +32,12 @@ export interface ModuleRecord {
|
|
|
25
32
|
commonjs: boolean;
|
|
26
33
|
/** Synthetic `module` object for a CommonJS module (`<prefix>$cjs_module`). */
|
|
27
34
|
cjsModule?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Spans of a *synthesized* module text that were copied from another file
|
|
37
|
+
* (an extension asset loader's `sourceRanges`). Nodes inside one keep that
|
|
38
|
+
* file as their origin instead of `path`.
|
|
39
|
+
*/
|
|
40
|
+
originRanges?: readonly OriginRange[];
|
|
28
41
|
}
|
|
29
42
|
|
|
30
43
|
export interface BundleResult {
|
package/src/driver/compiler.ts
CHANGED
|
@@ -31,7 +31,7 @@ import { buildCacheKey } from "./build-key.js";
|
|
|
31
31
|
import type { BuildOptions, BuildResult, EmitKind, PhaseTiming } from "./options.js";
|
|
32
32
|
|
|
33
33
|
export { COMPILER_VERSION } from "./version.js";
|
|
34
|
-
export { compileString, compileEntry, parseEntry, type ParsedEntry } from "./frontend.js";
|
|
34
|
+
export { compileString, compileEntry, parseEntry, type FrontendOptions, type ParsedEntry } from "./frontend.js";
|
|
35
35
|
export { RUNTIME_SOURCES, type RuntimeObjects } from "./runtime-objects.js";
|
|
36
36
|
export type { BuildOptions, BuildResult, CompileStringResult, EmitKind, PhaseTiming } from "./options.js";
|
|
37
37
|
|
|
@@ -128,6 +128,7 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
|
|
|
128
128
|
app,
|
|
129
129
|
debug: options.debug === true,
|
|
130
130
|
lto,
|
|
131
|
+
check: options.check !== false,
|
|
131
132
|
pgo,
|
|
132
133
|
pgoDir,
|
|
133
134
|
});
|
|
@@ -149,9 +150,11 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
|
|
|
149
150
|
const codegenStarted = Date.now();
|
|
150
151
|
const { ir } = generate(parsed.sourceFile, diagnostics, {
|
|
151
152
|
builtins: registry.builtins(),
|
|
153
|
+
globalValues: registry.globalValues(),
|
|
152
154
|
modules: registry.modules(),
|
|
153
155
|
moduleHints: registry.moduleHints(),
|
|
154
156
|
debug: options.debug === true,
|
|
157
|
+
check: options.check !== false,
|
|
155
158
|
});
|
|
156
159
|
timings.push({ phase: "codegen", ms: Date.now() - codegenStarted });
|
|
157
160
|
|
|
@@ -11,6 +11,7 @@ import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
|
11
11
|
import { dirname, join, relative, resolve } from "node:path";
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
import type { ExtensionRegistry } from "../extensions/registry.js";
|
|
14
|
+
import { artifactPath } from "../canonical.js";
|
|
14
15
|
import { hashParts } from "./cache.js";
|
|
15
16
|
|
|
16
17
|
/** Runtime sources, headers and `#include`d `.inc` fragments, plus prebuilt archives. */
|
|
@@ -56,7 +57,7 @@ export function compilerFingerprint(): string {
|
|
|
56
57
|
if (entry.isDirectory()) {
|
|
57
58
|
walk(full);
|
|
58
59
|
} else if (entry.name.endsWith(".ts")) {
|
|
59
|
-
parts.push(relative(sourceRoot, full)
|
|
60
|
+
parts.push(artifactPath(relative(sourceRoot, full)), readFileSync(full, "utf8"));
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
};
|
package/src/driver/frontend.ts
CHANGED
|
@@ -32,6 +32,13 @@ function externalModuleSpecifiers(registry: ExtensionRegistry): Set<string> {
|
|
|
32
32
|
]);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/** Front-end switches shared by `compileString` and `compileEntry`. */
|
|
36
|
+
export interface FrontendOptions {
|
|
37
|
+
readonly debug?: boolean;
|
|
38
|
+
/** Run the semantic checker (default true; `--no-check` disables it). */
|
|
39
|
+
readonly check?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
35
42
|
/** A parsed (and, for module entries, already bundled) entry file. */
|
|
36
43
|
export interface ParsedEntry {
|
|
37
44
|
readonly absoluteEntry: string;
|
|
@@ -78,7 +85,7 @@ export function compileString(
|
|
|
78
85
|
source: string,
|
|
79
86
|
fileName = "input.ts",
|
|
80
87
|
extensions?: ExtensionRegistry,
|
|
81
|
-
options:
|
|
88
|
+
options: FrontendOptions = {},
|
|
82
89
|
): CompileStringResult {
|
|
83
90
|
const file = new SourceFile(fileName, source);
|
|
84
91
|
const diagnostics = new DiagnosticBag();
|
|
@@ -90,9 +97,11 @@ export function compileString(
|
|
|
90
97
|
if (diagnostics.hasErrors) return { ir: "", diagnostics: diagnostics.diagnostics };
|
|
91
98
|
const { ir } = generate(sourceFile, diagnostics, {
|
|
92
99
|
builtins: registry.builtins(),
|
|
100
|
+
globalValues: registry.globalValues(),
|
|
93
101
|
modules: registry.modules(),
|
|
94
102
|
moduleHints: registry.moduleHints(),
|
|
95
103
|
debug: options.debug === true,
|
|
104
|
+
check: options.check !== false,
|
|
96
105
|
});
|
|
97
106
|
return { ir, diagnostics: diagnostics.diagnostics };
|
|
98
107
|
}
|
|
@@ -104,7 +113,7 @@ export function compileString(
|
|
|
104
113
|
export function compileEntry(
|
|
105
114
|
entryPath: string,
|
|
106
115
|
extensions?: ExtensionRegistry,
|
|
107
|
-
options:
|
|
116
|
+
options: FrontendOptions = {},
|
|
108
117
|
): CompileStringResult {
|
|
109
118
|
const registry = extensions ?? createDefaultRegistry();
|
|
110
119
|
const diagnostics = new DiagnosticBag();
|
|
@@ -112,9 +121,11 @@ export function compileEntry(
|
|
|
112
121
|
if (diagnostics.hasErrors) return { ir: "", diagnostics: diagnostics.diagnostics };
|
|
113
122
|
const { ir } = generate(parsed.sourceFile, diagnostics, {
|
|
114
123
|
builtins: registry.builtins(),
|
|
124
|
+
globalValues: registry.globalValues(),
|
|
115
125
|
modules: registry.modules(),
|
|
116
126
|
moduleHints: registry.moduleHints(),
|
|
117
127
|
debug: options.debug === true,
|
|
128
|
+
check: options.check !== false,
|
|
118
129
|
});
|
|
119
130
|
return { ir, diagnostics: diagnostics.diagnostics };
|
|
120
131
|
}
|
package/src/driver/options.ts
CHANGED
|
@@ -35,6 +35,12 @@ export interface BuildOptions {
|
|
|
35
35
|
readonly app?: AppConfig;
|
|
36
36
|
/** Emit LLVM debug metadata so `-g` produces DWARF/CodeView (default false). */
|
|
37
37
|
readonly debug?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Run the semantic checker before lowering (default true). `--no-check`
|
|
40
|
+
* disables it; the incremental cache keys on this flag, so a checked and an
|
|
41
|
+
* unchecked build of the same source cannot reuse each other's artifacts.
|
|
42
|
+
*/
|
|
43
|
+
readonly check?: boolean;
|
|
38
44
|
/** Compile the program and runtime to LTO bitcode and link with lld. */
|
|
39
45
|
readonly lto?: boolean;
|
|
40
46
|
/**
|
package/src/driver/version.ts
CHANGED