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.
Files changed (481) hide show
  1. package/AGENTS.md +11 -2
  2. package/README.md +47 -16
  3. package/README.zh-CN.md +21 -2
  4. package/dist/scripts/support-matrix.d.ts +18 -0
  5. package/dist/scripts/support-matrix.js +141 -0
  6. package/dist/scripts/support-matrix.js.map +1 -0
  7. package/dist/src/ast/common.d.ts +2 -2
  8. package/dist/src/ast/declarations.d.ts +7 -1
  9. package/dist/src/ast/expressions.d.ts +5 -0
  10. package/dist/src/ast/kinds.d.ts +2 -0
  11. package/dist/src/ast/kinds.js +2 -0
  12. package/dist/src/ast/kinds.js.map +1 -1
  13. package/dist/src/binder/binder.d.ts +2 -1
  14. package/dist/src/binder/binder.js +2 -0
  15. package/dist/src/binder/binder.js.map +1 -1
  16. package/dist/src/binder/declarations.d.ts +9 -0
  17. package/dist/src/binder/declarations.js +64 -0
  18. package/dist/src/binder/declarations.js.map +1 -1
  19. package/dist/src/binder/references.js +99 -4
  20. package/dist/src/binder/references.js.map +1 -1
  21. package/dist/src/binder/types.d.ts +32 -0
  22. package/dist/src/binder/types.js.map +1 -1
  23. package/dist/src/canonical.d.ts +29 -0
  24. package/dist/src/canonical.js +35 -0
  25. package/dist/src/canonical.js.map +1 -0
  26. package/dist/src/checker/assignability.d.ts +13 -0
  27. package/dist/src/checker/assignability.js +146 -0
  28. package/dist/src/checker/assignability.js.map +1 -0
  29. package/dist/src/checker/calls.d.ts +13 -0
  30. package/dist/src/checker/calls.js +127 -0
  31. package/dist/src/checker/calls.js.map +1 -0
  32. package/dist/src/checker/checker.d.ts +26 -0
  33. package/dist/src/checker/checker.js +31 -0
  34. package/dist/src/checker/checker.js.map +1 -0
  35. package/dist/src/checker/declarations.d.ts +9 -0
  36. package/dist/src/checker/declarations.js +15 -0
  37. package/dist/src/checker/declarations.js.map +1 -0
  38. package/dist/src/checker/flow.d.ts +21 -0
  39. package/dist/src/checker/flow.js +241 -0
  40. package/dist/src/checker/flow.js.map +1 -0
  41. package/dist/src/checker/globals.d.ts +9 -0
  42. package/dist/src/checker/globals.js +29 -0
  43. package/dist/src/checker/globals.js.map +1 -0
  44. package/dist/src/checker/source.d.ts +38 -0
  45. package/dist/src/checker/source.js +48 -0
  46. package/dist/src/checker/source.js.map +1 -0
  47. package/dist/src/checker/type-infer.d.ts +18 -0
  48. package/dist/src/checker/type-infer.js +173 -0
  49. package/dist/src/checker/type-infer.js.map +1 -0
  50. package/dist/src/checker/type-model.d.ts +73 -0
  51. package/dist/src/checker/type-model.js +151 -0
  52. package/dist/src/checker/type-model.js.map +1 -0
  53. package/dist/src/checker/type-system.d.ts +58 -0
  54. package/dist/src/checker/type-system.js +569 -0
  55. package/dist/src/checker/type-system.js.map +1 -0
  56. package/dist/src/checker/typecheck-types.d.ts +22 -0
  57. package/dist/src/checker/typecheck-types.js +109 -0
  58. package/dist/src/checker/typecheck-types.js.map +1 -0
  59. package/dist/src/checker/typecheck.d.ts +62 -0
  60. package/dist/src/checker/typecheck.js +574 -0
  61. package/dist/src/checker/typecheck.js.map +1 -0
  62. package/dist/src/checker/undefined.d.ts +14 -0
  63. package/dist/src/checker/undefined.js +32 -0
  64. package/dist/src/checker/undefined.js.map +1 -0
  65. package/dist/src/checker/walk.d.ts +10 -0
  66. package/dist/src/checker/walk.js +15 -0
  67. package/dist/src/checker/walk.js.map +1 -0
  68. package/dist/src/cli/help.d.ts +7 -0
  69. package/dist/src/cli/help.js +64 -0
  70. package/dist/src/cli/help.js.map +1 -0
  71. package/dist/src/cli/hints.js +2 -1
  72. package/dist/src/cli/hints.js.map +1 -1
  73. package/dist/src/cli/main.js +12 -48
  74. package/dist/src/cli/main.js.map +1 -1
  75. package/dist/src/codegen/generator/calls/access.js +8 -8
  76. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  77. package/dist/src/codegen/generator/calls/invocation.js +9 -4
  78. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  79. package/dist/src/codegen/generator/calls/super.d.ts +9 -1
  80. package/dist/src/codegen/generator/calls/super.js +56 -5
  81. package/dist/src/codegen/generator/calls/super.js.map +1 -1
  82. package/dist/src/codegen/generator/context.d.ts +13 -2
  83. package/dist/src/codegen/generator/context.js +25 -19
  84. package/dist/src/codegen/generator/context.js.map +1 -1
  85. package/dist/src/codegen/generator/debug.js +2 -1
  86. package/dist/src/codegen/generator/debug.js.map +1 -1
  87. package/dist/src/codegen/generator/expressions/primary.d.ts +4 -1
  88. package/dist/src/codegen/generator/expressions/primary.js +68 -8
  89. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  90. package/dist/src/codegen/generator/generator.js +11 -1
  91. package/dist/src/codegen/generator/generator.js.map +1 -1
  92. package/dist/src/codegen/generator/module.d.ts +3 -0
  93. package/dist/src/codegen/generator/module.js +116 -26
  94. package/dist/src/codegen/generator/module.js.map +1 -1
  95. package/dist/src/codegen/generator/state.d.ts +11 -1
  96. package/dist/src/codegen/generator/state.js.map +1 -1
  97. package/dist/src/codegen/generator/statements/variables.js +26 -7
  98. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  99. package/dist/src/codegen/generator/tables.d.ts +2 -0
  100. package/dist/src/codegen/generator/tables.js +4 -0
  101. package/dist/src/codegen/generator/tables.js.map +1 -1
  102. package/dist/src/driver/build-key.d.ts +2 -0
  103. package/dist/src/driver/build-key.js +1 -0
  104. package/dist/src/driver/build-key.js.map +1 -1
  105. package/dist/src/driver/bundler/graph.js +5 -1
  106. package/dist/src/driver/bundler/graph.js.map +1 -1
  107. package/dist/src/driver/bundler/merge.js +16 -1
  108. package/dist/src/driver/bundler/merge.js.map +1 -1
  109. package/dist/src/driver/bundler/types.d.ts +12 -0
  110. package/dist/src/driver/compiler.d.ts +1 -1
  111. package/dist/src/driver/compiler.js +3 -0
  112. package/dist/src/driver/compiler.js.map +1 -1
  113. package/dist/src/driver/fingerprint.js +2 -1
  114. package/dist/src/driver/fingerprint.js.map +1 -1
  115. package/dist/src/driver/frontend.d.ts +8 -6
  116. package/dist/src/driver/frontend.js +4 -0
  117. package/dist/src/driver/frontend.js.map +1 -1
  118. package/dist/src/driver/options.d.ts +6 -0
  119. package/dist/src/driver/version.d.ts +1 -1
  120. package/dist/src/driver/version.js +1 -1
  121. package/dist/src/extensions/gui/css.d.ts +26 -0
  122. package/dist/src/extensions/gui/css.js +100 -0
  123. package/dist/src/extensions/gui/css.js.map +1 -0
  124. package/dist/src/extensions/gui/html.js +28 -7
  125. package/dist/src/extensions/gui/html.js.map +1 -1
  126. package/dist/src/extensions/gui/index.js +79 -2
  127. package/dist/src/extensions/gui/index.js.map +1 -1
  128. package/dist/src/extensions/gui/three.d.ts +16 -0
  129. package/dist/src/extensions/gui/three.js +22 -0
  130. package/dist/src/extensions/gui/three.js.map +1 -0
  131. package/dist/src/extensions/media/index.d.ts +6 -5
  132. package/dist/src/extensions/media/index.js +12 -14
  133. package/dist/src/extensions/media/index.js.map +1 -1
  134. package/dist/src/extensions/registry.d.ts +38 -0
  135. package/dist/src/extensions/registry.js +10 -0
  136. package/dist/src/extensions/registry.js.map +1 -1
  137. package/dist/src/index.d.ts +1 -0
  138. package/dist/src/index.js +1 -0
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/parser/declarations/classes.js +7 -0
  141. package/dist/src/parser/declarations/classes.js.map +1 -1
  142. package/dist/src/parser/expressions.js +14 -1
  143. package/dist/src/parser/expressions.js.map +1 -1
  144. package/dist/src/parser/literals.js +6 -2
  145. package/dist/src/parser/literals.js.map +1 -1
  146. package/dist/tests/binder/binder.test.js +29 -0
  147. package/dist/tests/binder/binder.test.js.map +1 -1
  148. package/dist/tests/canonical.test.d.ts +1 -0
  149. package/dist/tests/canonical.test.js +19 -0
  150. package/dist/tests/canonical.test.js.map +1 -0
  151. package/dist/tests/checker/checker.test.d.ts +1 -0
  152. package/dist/tests/checker/checker.test.js +245 -0
  153. package/dist/tests/checker/checker.test.js.map +1 -0
  154. package/dist/tests/cli/check.test.js +20 -0
  155. package/dist/tests/cli/check.test.js.map +1 -1
  156. package/dist/tests/conformance/matrix.test.d.ts +6 -0
  157. package/dist/tests/conformance/matrix.test.js +23 -0
  158. package/dist/tests/conformance/matrix.test.js.map +1 -0
  159. package/dist/tests/conformance/test262/manifest.d.ts +115 -0
  160. package/dist/tests/conformance/test262/manifest.js +257 -0
  161. package/dist/tests/conformance/test262/manifest.js.map +1 -0
  162. package/dist/tests/conformance/test262.test.d.ts +11 -0
  163. package/dist/tests/conformance/test262.test.js +74 -0
  164. package/dist/tests/conformance/test262.test.js.map +1 -0
  165. package/dist/tests/docs/structure.test.js +9 -11
  166. package/dist/tests/docs/structure.test.js.map +1 -1
  167. package/dist/tests/e2e/child-process.test.js +3 -2
  168. package/dist/tests/e2e/child-process.test.js.map +1 -1
  169. package/dist/tests/e2e/compile-builtins.test.js +45 -0
  170. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  171. package/dist/tests/e2e/compile-objects-classes.test.js +77 -0
  172. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  173. package/dist/tests/e2e/differential-syntax.test.d.ts +5 -0
  174. package/dist/tests/e2e/differential-syntax.test.js +95 -0
  175. package/dist/tests/e2e/differential-syntax.test.js.map +1 -0
  176. package/dist/tests/e2e/differential-values.test.js +15 -0
  177. package/dist/tests/e2e/differential-values.test.js.map +1 -1
  178. package/dist/tests/e2e/gui-browser.test.d.ts +13 -0
  179. package/dist/tests/e2e/gui-browser.test.js +163 -0
  180. package/dist/tests/e2e/gui-browser.test.js.map +1 -0
  181. package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
  182. package/dist/tests/e2e/gui-effects.test.js +262 -0
  183. package/dist/tests/e2e/gui-effects.test.js.map +1 -0
  184. package/dist/tests/e2e/gui-example-browser.test.js +2 -2
  185. package/dist/tests/e2e/gui-example-browser.test.js.map +1 -1
  186. package/dist/tests/e2e/gui-example-canvas.test.js +5 -4
  187. package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
  188. package/dist/tests/e2e/gui-example-svg.test.js +4 -3
  189. package/dist/tests/e2e/gui-example-svg.test.js.map +1 -1
  190. package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
  191. package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
  192. package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
  193. package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
  194. package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
  195. package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
  196. package/dist/tests/e2e/gui-example.test.js +4 -3
  197. package/dist/tests/e2e/gui-example.test.js.map +1 -1
  198. package/dist/tests/e2e/gui-helpers.js +4 -3
  199. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  200. package/dist/tests/e2e/gui-layout.test.js +48 -0
  201. package/dist/tests/e2e/gui-layout.test.js.map +1 -1
  202. package/dist/tests/e2e/gui-media.test.js +10 -8
  203. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  204. package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
  205. package/dist/tests/e2e/gui-webgl.test.js +179 -0
  206. package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
  207. package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
  208. package/dist/tests/e2e/gui-webgl2.test.js +238 -0
  209. package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
  210. package/dist/tests/e2e/harness.d.ts +9 -0
  211. package/dist/tests/e2e/harness.js +14 -2
  212. package/dist/tests/e2e/harness.js.map +1 -1
  213. package/dist/tests/e2e/native-extensions.test.js +2 -1
  214. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  215. package/dist/tests/e2e/property-descriptors.test.js +20 -0
  216. package/dist/tests/e2e/property-descriptors.test.js.map +1 -1
  217. package/dist/tests/e2e/unicode-output.test.js +5 -3
  218. package/dist/tests/e2e/unicode-output.test.js.map +1 -1
  219. package/dist/tests/e2e/weak-collections.test.js +16 -2
  220. package/dist/tests/e2e/weak-collections.test.js.map +1 -1
  221. package/dist/tests/extensions/gui.test.js +41 -0
  222. package/dist/tests/extensions/gui.test.js.map +1 -1
  223. package/dist/tests/extensions/media.test.js +7 -3
  224. package/dist/tests/extensions/media.test.js.map +1 -1
  225. package/dist/tests/helpers.d.ts +1 -0
  226. package/dist/tests/helpers.js +1 -0
  227. package/dist/tests/helpers.js.map +1 -1
  228. package/dist/tests/parser/declarations.test.js +20 -0
  229. package/dist/tests/parser/declarations.test.js.map +1 -1
  230. package/dist/tests/parser/expressions.test.js +36 -0
  231. package/dist/tests/parser/expressions.test.js.map +1 -1
  232. package/dist/tests/platform.d.ts +32 -0
  233. package/dist/tests/platform.js +40 -0
  234. package/dist/tests/platform.js.map +1 -0
  235. package/dist/tests/platform.test.d.ts +12 -0
  236. package/dist/tests/platform.test.js +51 -0
  237. package/dist/tests/platform.test.js.map +1 -0
  238. package/dist/tests/version.test.js +4 -4
  239. package/dist/tests/version.test.js.map +1 -1
  240. package/doc/ai/README.md +10 -4
  241. package/doc/ai/build-recipe.md +1 -0
  242. package/doc/ai/cli.md +17 -5
  243. package/doc/ai/contributing.md +59 -2
  244. package/doc/ai/extensions.md +38 -7
  245. package/doc/ai/language-support.md +25 -16
  246. package/doc/ai/troubleshooting.md +12 -8
  247. package/doc/ai/zh-CN/README.md +9 -4
  248. package/doc/ai/zh-CN/build-recipe.md +1 -0
  249. package/doc/ai/zh-CN/cli.md +13 -3
  250. package/doc/ai/zh-CN/contributing.md +49 -3
  251. package/doc/ai/zh-CN/extensions.md +33 -6
  252. package/doc/ai/zh-CN/language-support.md +23 -14
  253. package/doc/ai/zh-CN/troubleshooting.md +10 -6
  254. package/doc/gui/api.md +47 -1
  255. package/doc/gui/build.md +72 -16
  256. package/doc/gui/canvas.md +11 -3
  257. package/doc/gui/dom.md +33 -18
  258. package/doc/gui/known-issues.md +58 -15
  259. package/doc/gui/layout.md +18 -0
  260. package/doc/gui/media.md +17 -13
  261. package/doc/gui/rendering.md +50 -3
  262. package/doc/gui/runtime.md +18 -0
  263. package/doc/gui/webgl.md +256 -0
  264. package/doc/gui-scripts.md +7 -0
  265. package/doc/gui.md +108 -17
  266. package/doc/implemented/binder.md +2 -0
  267. package/doc/implemented/checker.md +117 -0
  268. package/doc/implemented/cli.md +13 -1
  269. package/doc/implemented/codegen.md +3 -2
  270. package/doc/implemented/driver.md +2 -2
  271. package/doc/implemented/operators.md +2 -1
  272. package/doc/implemented/parser.md +3 -2
  273. package/doc/implemented/pipeline.md +8 -1
  274. package/doc/implemented/stdlib.md +2 -1
  275. package/doc/implemented/tests.md +3 -1
  276. package/doc/implemented.md +2 -0
  277. package/doc/npm-package.md +419 -0
  278. package/doc/requirements.md +22 -10
  279. package/doc/support-matrix.md +83 -0
  280. package/doc/unimplemented/classes.md +3 -0
  281. package/doc/unimplemented/deviations.md +3 -2
  282. package/doc/unimplemented/toolchain.md +1 -1
  283. package/doc/unimplemented/types.md +24 -8
  284. package/doc/unimplemented.md +1 -1
  285. package/doc/zh-CN/gui/api.md +43 -1
  286. package/doc/zh-CN/gui/build.md +64 -15
  287. package/doc/zh-CN/gui/canvas.md +9 -2
  288. package/doc/zh-CN/gui/dom.md +20 -7
  289. package/doc/zh-CN/gui/known-issues.md +46 -13
  290. package/doc/zh-CN/gui/layout.md +14 -0
  291. package/doc/zh-CN/gui/media.md +15 -11
  292. package/doc/zh-CN/gui/rendering.md +41 -4
  293. package/doc/zh-CN/gui/runtime.md +16 -0
  294. package/doc/zh-CN/gui/webgl.md +115 -0
  295. package/doc/zh-CN/gui-scripts.md +5 -0
  296. package/doc/zh-CN/gui.md +89 -14
  297. package/doc/zh-CN/implemented/binder.md +2 -0
  298. package/doc/zh-CN/implemented/checker.md +99 -0
  299. package/doc/zh-CN/implemented/cli.md +12 -1
  300. package/doc/zh-CN/implemented/codegen.md +3 -2
  301. package/doc/zh-CN/implemented/driver.md +2 -2
  302. package/doc/zh-CN/implemented/operators.md +1 -1
  303. package/doc/zh-CN/implemented/parser.md +3 -2
  304. package/doc/zh-CN/implemented/pipeline.md +3 -1
  305. package/doc/zh-CN/implemented/stdlib.md +2 -1
  306. package/doc/zh-CN/implemented/tests.md +3 -1
  307. package/doc/zh-CN/implemented.md +2 -0
  308. package/doc/zh-CN/npm-package.md +394 -0
  309. package/doc/zh-CN/post/announce.md +47 -47
  310. package/doc/zh-CN/requirements.md +16 -7
  311. package/doc/zh-CN/support-matrix.md +82 -0
  312. package/doc/zh-CN/unimplemented/classes.md +3 -0
  313. package/doc/zh-CN/unimplemented/deviations.md +3 -2
  314. package/doc/zh-CN/unimplemented/toolchain.md +1 -1
  315. package/doc/zh-CN/unimplemented/types.md +16 -6
  316. package/doc/zh-CN/unimplemented.md +1 -1
  317. package/llms.txt +6 -1
  318. package/package.json +2 -1
  319. package/runtime/ext_gui/audio.cpp +316 -0
  320. package/runtime/ext_gui/browser.cpp +573 -0
  321. package/runtime/ext_gui/browser_escape.cpp +85 -0
  322. package/runtime/ext_gui/browser_loop.cpp +83 -0
  323. package/runtime/ext_gui/canvas.cpp +12 -21
  324. package/runtime/ext_gui/canvas_internal.h +10 -0
  325. package/runtime/ext_gui/canvas_raster.cpp +79 -1
  326. package/runtime/ext_gui/clip_values.cpp +246 -0
  327. package/runtime/ext_gui/css.cpp +94 -0
  328. package/runtime/ext_gui/css.h +22 -1
  329. package/runtime/ext_gui/css_match.cpp +3 -0
  330. package/runtime/ext_gui/css_selector.cpp +9 -0
  331. package/runtime/ext_gui/css_sheet.cpp +89 -45
  332. package/runtime/ext_gui/document.cpp +4 -1
  333. package/runtime/ext_gui/document.h +2 -0
  334. package/runtime/ext_gui/dom.h +16 -0
  335. package/runtime/ext_gui/dom_api.cpp +37 -0
  336. package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
  337. package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
  338. package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
  339. package/runtime/ext_gui/dom_api_document.cpp +96 -5
  340. package/runtime/ext_gui/dom_api_events.cpp +20 -0
  341. package/runtime/ext_gui/dom_api_internal.h +278 -0
  342. package/runtime/ext_gui/dom_api_proto.cpp +6 -0
  343. package/runtime/ext_gui/dom_api_webgl.cpp +376 -0
  344. package/runtime/ext_gui/dom_api_webgl2.cpp +434 -0
  345. package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
  346. package/runtime/ext_gui/dom_api_webgl_buffer.cpp +212 -0
  347. package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
  348. package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
  349. package/runtime/ext_gui/dom_api_webgl_state.cpp +444 -0
  350. package/runtime/ext_gui/dom_api_webgl_texture.cpp +445 -0
  351. package/runtime/ext_gui/effect_values.cpp +312 -0
  352. package/runtime/ext_gui/gradient_values.cpp +476 -0
  353. package/runtime/ext_gui/grid_values.cpp +230 -0
  354. package/runtime/ext_gui/gui.cpp +90 -23
  355. package/runtime/ext_gui/gui_canvas.cpp +50 -2
  356. package/runtime/ext_gui/gui_engine.h +71 -0
  357. package/runtime/ext_gui/gui_events.cpp +4 -1
  358. package/runtime/ext_gui/gui_media.cpp +1 -1
  359. package/runtime/ext_gui/gui_webgl.cpp +83 -0
  360. package/runtime/ext_gui/layout.cpp +21 -0
  361. package/runtime/ext_gui/layout_flow.cpp +81 -4
  362. package/runtime/ext_gui/layout_flow_internal.h +31 -0
  363. package/runtime/ext_gui/layout_grid.cpp +374 -0
  364. package/runtime/ext_gui/media.h +1 -1
  365. package/runtime/ext_gui/media_api.h +2 -2
  366. package/runtime/ext_gui/media_query.cpp +211 -0
  367. package/runtime/ext_gui/paint.cpp +111 -77
  368. package/runtime/ext_gui/paint.h +33 -3
  369. package/runtime/ext_gui/paint_background.cpp +229 -0
  370. package/runtime/ext_gui/paint_clip.cpp +268 -0
  371. package/runtime/ext_gui/paint_effects.cpp +324 -0
  372. package/runtime/ext_gui/paint_internal.h +85 -0
  373. package/runtime/ext_gui/renderer.cpp +8 -31
  374. package/runtime/ext_gui/renderer_clip.cpp +196 -0
  375. package/runtime/ext_gui/renderer_image.cpp +13 -8
  376. package/runtime/ext_gui/renderer_internal.h +15 -8
  377. package/runtime/ext_gui/renderer_text.cpp +6 -31
  378. package/runtime/ext_gui/style.cpp +343 -20
  379. package/runtime/ext_gui/style.h +144 -3
  380. package/runtime/ext_gui/style_print.cpp +134 -1
  381. package/runtime/ext_gui/style_values.cpp +152 -126
  382. package/runtime/ext_gui/style_values_internal.h +35 -0
  383. package/runtime/ext_gui/webgl.h +466 -0
  384. package/runtime/ext_gui/webgl2_constants.h +274 -0
  385. package/runtime/ext_gui/webgl_buffer.cpp +565 -0
  386. package/runtime/ext_gui/webgl_constants.h +317 -0
  387. package/runtime/ext_gui/webgl_context.cpp +466 -0
  388. package/runtime/ext_gui/webgl_draw.cpp +495 -0
  389. package/runtime/ext_gui/webgl_glsl.h +125 -0
  390. package/runtime/ext_gui/webgl_glsl_compile.cpp +431 -0
  391. package/runtime/ext_gui/webgl_glsl_rewrite.cpp +349 -0
  392. package/runtime/ext_gui/webgl_glsl_scan.cpp +581 -0
  393. package/runtime/ext_gui/webgl_msl.cpp +62 -0
  394. package/runtime/ext_gui/webgl_msl.h +33 -0
  395. package/runtime/ext_gui/webgl_pipeline.cpp +274 -0
  396. package/runtime/ext_gui/webgl_program_internal.h +18 -0
  397. package/runtime/ext_gui/webgl_shader.cpp +582 -0
  398. package/runtime/ext_gui/webgl_texture.cpp +293 -0
  399. package/runtime/ext_gui/webgl_uniform.cpp +167 -0
  400. package/runtime/ext_gui/webgl_webgl2.cpp +224 -0
  401. package/runtime/ext_gui/window.cpp +9 -0
  402. package/runtime/ext_media/media.cpp +1 -1
  403. package/runtime/ext_media/media_bridge.c +9 -3
  404. package/runtime/ext_node/path/path.c +7 -7
  405. package/runtime/ext_node/url/url.c +4 -2
  406. package/runtime/rt.h +15 -0
  407. package/runtime/rt_internal.h +1 -0
  408. package/runtime/xt_constructors.c +2 -1
  409. package/runtime/xt_containers/access.inc +8 -0
  410. package/runtime/xt_containers/objects.inc +22 -2
  411. package/runtime/xt_io/exception.inc +4 -2
  412. package/runtime/xt_regex/api.inc +2 -0
  413. package/runtime/xt_regex/matcher.inc +16 -3
  414. package/runtime/xt_regex/parser.inc +8 -2
  415. package/runtime/xt_regex/types.inc +3 -0
  416. package/runtime/xt_stdlib/math.inc +62 -0
  417. package/runtime/xt_stdlib2/date.inc +7 -1
  418. package/runtime/xt_stdlib2/objects.inc +14 -0
  419. package/runtime/xt_stdlib2/regexp-match.inc +60 -21
  420. package/runtime/xt_stdlib2/regexp.inc +1 -0
  421. package/runtime/xt_typed_array.c +1 -1
  422. package/scripts/build-gui.ts +90 -3
  423. package/scripts/build-media.ts +323 -58
  424. package/scripts/setup-vs-toolchain.ps1 +152 -0
  425. package/scripts/support-matrix.ts +167 -0
  426. package/src/ast/common.ts +2 -0
  427. package/src/ast/declarations.ts +12 -1
  428. package/src/ast/expressions.ts +6 -0
  429. package/src/ast/kinds.ts +2 -0
  430. package/src/binder/binder.ts +3 -0
  431. package/src/binder/declarations.ts +70 -0
  432. package/src/binder/references.ts +97 -4
  433. package/src/binder/types.ts +30 -0
  434. package/src/canonical.ts +37 -0
  435. package/src/checker/assignability.ts +134 -0
  436. package/src/checker/calls.ts +135 -0
  437. package/src/checker/checker.ts +47 -0
  438. package/src/checker/declarations.ts +26 -0
  439. package/src/checker/flow.ts +236 -0
  440. package/src/checker/globals.ts +40 -0
  441. package/src/checker/source.ts +53 -0
  442. package/src/checker/type-infer.ts +185 -0
  443. package/src/checker/type-model.ts +212 -0
  444. package/src/checker/type-system.ts +578 -0
  445. package/src/checker/typecheck-types.ts +112 -0
  446. package/src/checker/typecheck.ts +586 -0
  447. package/src/checker/undefined.ts +43 -0
  448. package/src/checker/walk.ts +16 -0
  449. package/src/cli/help.ts +65 -0
  450. package/src/cli/hints.ts +2 -1
  451. package/src/cli/main.ts +12 -49
  452. package/src/codegen/generator/calls/access.ts +8 -8
  453. package/src/codegen/generator/calls/invocation.ts +8 -5
  454. package/src/codegen/generator/calls/super.ts +67 -5
  455. package/src/codegen/generator/context.ts +31 -19
  456. package/src/codegen/generator/debug.ts +2 -1
  457. package/src/codegen/generator/expressions/primary.ts +84 -13
  458. package/src/codegen/generator/generator.ts +11 -1
  459. package/src/codegen/generator/module.ts +115 -24
  460. package/src/codegen/generator/state.ts +11 -1
  461. package/src/codegen/generator/statements/variables.ts +26 -6
  462. package/src/codegen/generator/tables.ts +5 -0
  463. package/src/driver/build-key.ts +3 -0
  464. package/src/driver/bundler/graph.ts +6 -2
  465. package/src/driver/bundler/merge.ts +14 -1
  466. package/src/driver/bundler/types.ts +13 -0
  467. package/src/driver/compiler.ts +4 -1
  468. package/src/driver/fingerprint.ts +2 -1
  469. package/src/driver/frontend.ts +13 -2
  470. package/src/driver/options.ts +6 -0
  471. package/src/driver/version.ts +1 -1
  472. package/src/extensions/gui/css.ts +113 -0
  473. package/src/extensions/gui/html.ts +31 -11
  474. package/src/extensions/gui/index.ts +81 -2
  475. package/src/extensions/gui/three.ts +25 -0
  476. package/src/extensions/media/index.ts +13 -16
  477. package/src/extensions/registry.ts +48 -0
  478. package/src/index.ts +1 -0
  479. package/src/parser/declarations/classes.ts +7 -0
  480. package/src/parser/expressions.ts +13 -1
  481. 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
- const generator = new Generator(sourceFile, diagnostics, options);
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.split("\\").join("/");
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("\n");
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).split("\\").join("/"));
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("\n"));
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("\n"),
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.computedKey
369
- ? this.emitExpression(method.computedKey)
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.computedKey
387
- ? this.emitExpression(method.computedKey)
388
- : this.stringValue(method.name);
389
- this.emit(` call i64 @xt_set(i64 ${ctor}, i64 ${key}, i64 ${fnValue})`);
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 field of classInfo.fields) {
392
- if (!field.isStatic) continue;
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
- this.emit(` store i64 ${ctor}, i64* ${globalName}`);
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` (or an already-declared slot): keep evaluating the
37
- // initializer for its side effects, but do not redeclare the slot.
38
- if (declaration.initializer) this.emitExpression(declaration.initializer);
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
- /** `x = fallback` in a binding pattern: only apply when `x` is `undefined`. */
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 fallback = this.emitExpression(initializer);
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} = select i1 ${condition}, i64 ${fallback}, i64 ${value}`);
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",
@@ -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
- text = loader(path, raw).moduleSource;
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.path);
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 {
@@ -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).replace(/\\/g, "/"), readFileSync(full, "utf8"));
60
+ parts.push(artifactPath(relative(sourceRoot, full)), readFileSync(full, "utf8"));
60
61
  }
61
62
  }
62
63
  };
@@ -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: { readonly debug?: boolean } = {},
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: { readonly debug?: boolean } = {},
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
  }
@@ -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
  /**
@@ -9,4 +9,4 @@
9
9
  * `main`/`master` only (see `.githooks/pre-commit`), so feature branches never
10
10
  * change this line and merging two of them cannot conflict here.
11
11
  */
12
- export const COMPILER_VERSION = "0.5.23";
12
+ export const COMPILER_VERSION = "0.5.32";