@elaraai/east 1.0.79 → 1.0.80

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 (276) hide show
  1. package/README.md +1 -1
  2. package/dist/src/comparison.d.ts.map +1 -1
  3. package/dist/src/comparison.js +4 -5
  4. package/dist/src/comparison.js.map +1 -1
  5. package/dist/src/compile/builtins/array.d.ts +59 -0
  6. package/dist/src/compile/builtins/array.d.ts.map +1 -0
  7. package/dist/src/compile/builtins/array.js +656 -0
  8. package/dist/src/compile/builtins/array.js.map +1 -0
  9. package/dist/src/compile/builtins/blob.d.ts +18 -0
  10. package/dist/src/compile/builtins/blob.d.ts.map +1 -0
  11. package/dist/src/compile/builtins/blob.js +150 -0
  12. package/dist/src/compile/builtins/blob.js.map +1 -0
  13. package/dist/src/compile/builtins/compare.d.ts +18 -0
  14. package/dist/src/compile/builtins/compare.d.ts.map +1 -0
  15. package/dist/src/compile/builtins/compare.js +52 -0
  16. package/dist/src/compile/builtins/compare.js.map +1 -0
  17. package/dist/src/compile/builtins/datetime.d.ts +21 -0
  18. package/dist/src/compile/builtins/datetime.d.ts.map +1 -0
  19. package/dist/src/compile/builtins/datetime.js +46 -0
  20. package/dist/src/compile/builtins/datetime.js.map +1 -0
  21. package/dist/src/compile/builtins/dict.d.ts +46 -0
  22. package/dist/src/compile/builtins/dict.d.ts.map +1 -0
  23. package/dist/src/compile/builtins/dict.js +551 -0
  24. package/dist/src/compile/builtins/dict.js.map +1 -0
  25. package/dist/src/compile/builtins/index.d.ts +9 -0
  26. package/dist/src/compile/builtins/index.d.ts.map +1 -0
  27. package/dist/src/compile/builtins/index.js +28 -0
  28. package/dist/src/compile/builtins/index.js.map +1 -0
  29. package/dist/src/compile/builtins/matrix.d.ts +31 -0
  30. package/dist/src/compile/builtins/matrix.d.ts.map +1 -0
  31. package/dist/src/compile/builtins/matrix.js +310 -0
  32. package/dist/src/compile/builtins/matrix.js.map +1 -0
  33. package/dist/src/compile/builtins/primitives.d.ts +36 -0
  34. package/dist/src/compile/builtins/primitives.d.ts.map +1 -0
  35. package/dist/src/compile/builtins/primitives.js +67 -0
  36. package/dist/src/compile/builtins/primitives.js.map +1 -0
  37. package/dist/src/compile/builtins/ref.d.ts +11 -0
  38. package/dist/src/compile/builtins/ref.d.ts.map +1 -0
  39. package/dist/src/compile/builtins/ref.js +30 -0
  40. package/dist/src/compile/builtins/ref.js.map +1 -0
  41. package/dist/src/compile/builtins/set.d.ts +41 -0
  42. package/dist/src/compile/builtins/set.d.ts.map +1 -0
  43. package/dist/src/compile/builtins/set.js +385 -0
  44. package/dist/src/compile/builtins/set.js.map +1 -0
  45. package/dist/src/compile/builtins/sparse.d.ts +19 -0
  46. package/dist/src/compile/builtins/sparse.d.ts.map +1 -0
  47. package/dist/src/compile/builtins/sparse.js +143 -0
  48. package/dist/src/compile/builtins/sparse.js.map +1 -0
  49. package/dist/src/compile/builtins/string.d.ts +34 -0
  50. package/dist/src/compile/builtins/string.d.ts.map +1 -0
  51. package/dist/src/compile/builtins/string.js +238 -0
  52. package/dist/src/compile/builtins/string.js.map +1 -0
  53. package/dist/src/compile/builtins/vector.d.ts +44 -0
  54. package/dist/src/compile/builtins/vector.d.ts.map +1 -0
  55. package/dist/src/compile/builtins/vector.js +463 -0
  56. package/dist/src/compile/builtins/vector.js.map +1 -0
  57. package/dist/src/compile/constructors.d.ts +13 -0
  58. package/dist/src/compile/constructors.d.ts.map +1 -0
  59. package/dist/src/compile/constructors.js +179 -0
  60. package/dist/src/compile/constructors.js.map +1 -0
  61. package/dist/src/compile/control.d.ts +13 -0
  62. package/dist/src/compile/control.d.ts.map +1 -0
  63. package/dist/src/compile/control.js +513 -0
  64. package/dist/src/compile/control.js.map +1 -0
  65. package/dist/src/compile/functions.d.ts +13 -0
  66. package/dist/src/compile/functions.d.ts.map +1 -0
  67. package/dist/src/compile/functions.js +492 -0
  68. package/dist/src/compile/functions.js.map +1 -0
  69. package/dist/src/compile/ir.d.ts +19 -0
  70. package/dist/src/compile/ir.d.ts.map +1 -0
  71. package/dist/src/compile/ir.js +193 -0
  72. package/dist/src/compile/ir.js.map +1 -0
  73. package/dist/src/compile/runtime.d.ts +78 -0
  74. package/dist/src/compile/runtime.d.ts.map +1 -0
  75. package/dist/src/compile/runtime.js +111 -0
  76. package/dist/src/compile/runtime.js.map +1 -0
  77. package/dist/src/compile/type_parameters.d.ts +4 -0
  78. package/dist/src/compile/type_parameters.d.ts.map +1 -0
  79. package/dist/src/compile/type_parameters.js +55 -0
  80. package/dist/src/compile/type_parameters.js.map +1 -0
  81. package/dist/src/compile/typed_arrays.d.ts +28 -0
  82. package/dist/src/compile/typed_arrays.d.ts.map +1 -0
  83. package/dist/src/compile/typed_arrays.js +77 -0
  84. package/dist/src/compile/typed_arrays.js.map +1 -0
  85. package/dist/src/compile.d.ts +6 -41
  86. package/dist/src/compile.d.ts.map +1 -1
  87. package/dist/src/compile.js +8 -4415
  88. package/dist/src/compile.js.map +1 -1
  89. package/dist/src/compile.open_beast.spec.js +5 -4
  90. package/dist/src/compile.open_beast.spec.js.map +1 -1
  91. package/dist/src/containers/sortedmap.d.ts +2 -1
  92. package/dist/src/containers/sortedmap.d.ts.map +1 -1
  93. package/dist/src/containers/sortedmap.js +4 -2
  94. package/dist/src/containers/sortedmap.js.map +1 -1
  95. package/dist/src/containers/sortedset.d.ts +2 -1
  96. package/dist/src/containers/sortedset.d.ts.map +1 -1
  97. package/dist/src/containers/sortedset.js +4 -2
  98. package/dist/src/containers/sortedset.js.map +1 -1
  99. package/dist/src/error.d.ts +15 -0
  100. package/dist/src/error.d.ts.map +1 -1
  101. package/dist/src/error.js +16 -0
  102. package/dist/src/error.js.map +1 -1
  103. package/dist/src/index.d.ts +1 -0
  104. package/dist/src/index.d.ts.map +1 -1
  105. package/dist/src/index.js +1 -0
  106. package/dist/src/index.js.map +1 -1
  107. package/dist/src/patch/index.d.ts +1 -1
  108. package/dist/src/patch/index.d.ts.map +1 -1
  109. package/dist/src/patch/index.js +1 -1
  110. package/dist/src/patch/index.js.map +1 -1
  111. package/dist/src/patch/type_of_patch.d.ts +25 -1
  112. package/dist/src/patch/type_of_patch.d.ts.map +1 -1
  113. package/dist/src/patch/type_of_patch.js +33 -10
  114. package/dist/src/patch/type_of_patch.js.map +1 -1
  115. package/dist/src/platform.spec.js +19 -1
  116. package/dist/src/platform.spec.js.map +1 -1
  117. package/dist/src/runner_protocol.d.ts +316 -0
  118. package/dist/src/runner_protocol.d.ts.map +1 -0
  119. package/dist/src/runner_protocol.js +135 -0
  120. package/dist/src/runner_protocol.js.map +1 -0
  121. package/dist/src/serialization/beast2/index.d.ts +21 -5
  122. package/dist/src/serialization/beast2/index.d.ts.map +1 -1
  123. package/dist/src/serialization/beast2/index.js +12 -2
  124. package/dist/src/serialization/beast2/index.js.map +1 -1
  125. package/dist/src/serialization/beast2/index.spec.js +84 -3
  126. package/dist/src/serialization/beast2/index.spec.js.map +1 -1
  127. package/dist/src/serialization/beast2/shared.d.ts +32 -3
  128. package/dist/src/serialization/beast2/shared.d.ts.map +1 -1
  129. package/dist/src/serialization/beast2/shared.js +135 -10
  130. package/dist/src/serialization/beast2/shared.js.map +1 -1
  131. package/dist/src/serialization/beast2/v4/container.d.ts.map +1 -1
  132. package/dist/src/serialization/beast2/v4/container.js +5 -3
  133. package/dist/src/serialization/beast2/v4/container.js.map +1 -1
  134. package/dist/src/serialization/beast2/v5/aliasing.spec.d.ts +6 -0
  135. package/dist/src/serialization/beast2/v5/aliasing.spec.d.ts.map +1 -0
  136. package/dist/src/serialization/beast2/v5/aliasing.spec.js +75 -0
  137. package/dist/src/serialization/beast2/v5/aliasing.spec.js.map +1 -0
  138. package/dist/src/serialization/beast2/v5/boundary.d.ts +176 -0
  139. package/dist/src/serialization/beast2/v5/boundary.d.ts.map +1 -0
  140. package/dist/src/serialization/beast2/v5/boundary.js +297 -0
  141. package/dist/src/serialization/beast2/v5/boundary.js.map +1 -0
  142. package/dist/src/serialization/beast2/v5/boundary.spec.d.ts +6 -0
  143. package/dist/src/serialization/beast2/v5/boundary.spec.d.ts.map +1 -0
  144. package/dist/src/serialization/beast2/v5/boundary.spec.js +479 -0
  145. package/dist/src/serialization/beast2/v5/boundary.spec.js.map +1 -0
  146. package/dist/src/serialization/beast2/v5/codec.d.ts +6 -5
  147. package/dist/src/serialization/beast2/v5/codec.d.ts.map +1 -1
  148. package/dist/src/serialization/beast2/v5/codec.js +18 -3
  149. package/dist/src/serialization/beast2/v5/codec.js.map +1 -1
  150. package/dist/src/serialization/beast2/v5/deflate.d.ts +24 -2
  151. package/dist/src/serialization/beast2/v5/deflate.d.ts.map +1 -1
  152. package/dist/src/serialization/beast2/v5/deflate.js +47 -12
  153. package/dist/src/serialization/beast2/v5/deflate.js.map +1 -1
  154. package/dist/src/serialization/beast2/v5/deflate.spec.js +15 -1
  155. package/dist/src/serialization/beast2/v5/deflate.spec.js.map +1 -1
  156. package/dist/src/serialization/beast2/v5/elements.d.ts +64 -0
  157. package/dist/src/serialization/beast2/v5/elements.d.ts.map +1 -0
  158. package/dist/src/serialization/beast2/v5/elements.js +320 -0
  159. package/dist/src/serialization/beast2/v5/elements.js.map +1 -0
  160. package/dist/src/serialization/beast2/v5/elements.spec.d.ts +6 -0
  161. package/dist/src/serialization/beast2/v5/elements.spec.d.ts.map +1 -0
  162. package/dist/src/serialization/beast2/v5/elements.spec.js +161 -0
  163. package/dist/src/serialization/beast2/v5/elements.spec.js.map +1 -0
  164. package/dist/src/serialization/beast2/v5/frame-pool.d.ts +62 -21
  165. package/dist/src/serialization/beast2/v5/frame-pool.d.ts.map +1 -1
  166. package/dist/src/serialization/beast2/v5/frame-pool.js +138 -27
  167. package/dist/src/serialization/beast2/v5/frame-pool.js.map +1 -1
  168. package/dist/src/serialization/beast2/v5/frame-pool.spec.js +198 -71
  169. package/dist/src/serialization/beast2/v5/frame-pool.spec.js.map +1 -1
  170. package/dist/src/serialization/beast2/v5/frame-worker.js +25 -15
  171. package/dist/src/serialization/beast2/v5/frame-worker.js.map +1 -1
  172. package/dist/src/serialization/beast2/v5/frames.d.ts +22 -12
  173. package/dist/src/serialization/beast2/v5/frames.d.ts.map +1 -1
  174. package/dist/src/serialization/beast2/v5/frames.js +52 -27
  175. package/dist/src/serialization/beast2/v5/frames.js.map +1 -1
  176. package/dist/src/serialization/beast2/v5/geometry.d.ts +38 -1
  177. package/dist/src/serialization/beast2/v5/geometry.d.ts.map +1 -1
  178. package/dist/src/serialization/beast2/v5/geometry.js +73 -1
  179. package/dist/src/serialization/beast2/v5/geometry.js.map +1 -1
  180. package/dist/src/serialization/beast2/v5/geometry.spec.js +34 -23
  181. package/dist/src/serialization/beast2/v5/geometry.spec.js.map +1 -1
  182. package/dist/src/serialization/beast2/v5/index.spec.js +32 -28
  183. package/dist/src/serialization/beast2/v5/index.spec.js.map +1 -1
  184. package/dist/src/serialization/beast2/v5/lazy.d.ts +42 -1
  185. package/dist/src/serialization/beast2/v5/lazy.d.ts.map +1 -1
  186. package/dist/src/serialization/beast2/v5/lazy.js +143 -28
  187. package/dist/src/serialization/beast2/v5/lazy.js.map +1 -1
  188. package/dist/src/serialization/beast2/v5/lazy.spec.js +102 -24
  189. package/dist/src/serialization/beast2/v5/lazy.spec.js.map +1 -1
  190. package/dist/src/serialization/beast2/v5/manifest-writer.d.ts +110 -0
  191. package/dist/src/serialization/beast2/v5/manifest-writer.d.ts.map +1 -0
  192. package/dist/src/serialization/beast2/v5/manifest-writer.js +118 -0
  193. package/dist/src/serialization/beast2/v5/manifest-writer.js.map +1 -0
  194. package/dist/src/serialization/beast2/v5/manifest-writer.spec.d.ts +6 -0
  195. package/dist/src/serialization/beast2/v5/manifest-writer.spec.d.ts.map +1 -0
  196. package/dist/src/serialization/beast2/v5/manifest-writer.spec.js +207 -0
  197. package/dist/src/serialization/beast2/v5/manifest-writer.spec.js.map +1 -0
  198. package/dist/src/serialization/beast2/v5/manifest.d.ts +241 -0
  199. package/dist/src/serialization/beast2/v5/manifest.d.ts.map +1 -0
  200. package/dist/src/serialization/beast2/v5/manifest.js +233 -0
  201. package/dist/src/serialization/beast2/v5/manifest.js.map +1 -0
  202. package/dist/src/serialization/beast2/v5/merge.d.ts +93 -0
  203. package/dist/src/serialization/beast2/v5/merge.d.ts.map +1 -0
  204. package/dist/src/serialization/beast2/v5/merge.js +202 -0
  205. package/dist/src/serialization/beast2/v5/merge.js.map +1 -0
  206. package/dist/src/serialization/beast2/v5/merge.spec.d.ts +6 -0
  207. package/dist/src/serialization/beast2/v5/merge.spec.d.ts.map +1 -0
  208. package/dist/src/serialization/beast2/v5/merge.spec.js +118 -0
  209. package/dist/src/serialization/beast2/v5/merge.spec.js.map +1 -0
  210. package/dist/src/serialization/beast2/v5/recut.d.ts +143 -0
  211. package/dist/src/serialization/beast2/v5/recut.d.ts.map +1 -0
  212. package/dist/src/serialization/beast2/v5/recut.js +365 -0
  213. package/dist/src/serialization/beast2/v5/recut.js.map +1 -0
  214. package/dist/src/serialization/beast2/v5/recut.spec.d.ts +6 -0
  215. package/dist/src/serialization/beast2/v5/recut.spec.d.ts.map +1 -0
  216. package/dist/src/serialization/beast2/v5/recut.spec.js +215 -0
  217. package/dist/src/serialization/beast2/v5/recut.spec.js.map +1 -0
  218. package/dist/src/serialization/beast2/v5/runs.d.ts +148 -0
  219. package/dist/src/serialization/beast2/v5/runs.d.ts.map +1 -0
  220. package/dist/src/serialization/beast2/v5/runs.js +260 -0
  221. package/dist/src/serialization/beast2/v5/runs.js.map +1 -0
  222. package/dist/src/serialization/beast2/v5/runs.spec.d.ts +6 -0
  223. package/dist/src/serialization/beast2/v5/runs.spec.d.ts.map +1 -0
  224. package/dist/src/serialization/beast2/v5/runs.spec.js +182 -0
  225. package/dist/src/serialization/beast2/v5/runs.spec.js.map +1 -0
  226. package/dist/src/serialization/beast2/v5/sha256.d.ts +19 -0
  227. package/dist/src/serialization/beast2/v5/sha256.d.ts.map +1 -0
  228. package/dist/src/serialization/beast2/v5/sha256.js +103 -0
  229. package/dist/src/serialization/beast2/v5/sha256.js.map +1 -0
  230. package/dist/src/serialization/beast2/v5/sha256.spec.d.ts +6 -0
  231. package/dist/src/serialization/beast2/v5/sha256.spec.d.ts.map +1 -0
  232. package/dist/src/serialization/beast2/v5/sha256.spec.js +42 -0
  233. package/dist/src/serialization/beast2/v5/sha256.spec.js.map +1 -0
  234. package/dist/src/serialization/beast2/v5/stream.d.ts +273 -86
  235. package/dist/src/serialization/beast2/v5/stream.d.ts.map +1 -1
  236. package/dist/src/serialization/beast2/v5/stream.js +576 -244
  237. package/dist/src/serialization/beast2/v5/stream.js.map +1 -1
  238. package/dist/src/serialization/beast2/v5/sync-reader.spec.js +24 -10
  239. package/dist/src/serialization/beast2/v5/sync-reader.spec.js.map +1 -1
  240. package/dist/src/serialization/index.d.ts +1 -1
  241. package/dist/src/serialization/index.d.ts.map +1 -1
  242. package/dist/src/serialization/index.js +1 -1
  243. package/dist/src/serialization/index.js.map +1 -1
  244. package/dist/src/serialization/json.d.ts +28 -0
  245. package/dist/src/serialization/json.d.ts.map +1 -1
  246. package/dist/src/serialization/json.js +141 -30
  247. package/dist/src/serialization/json.js.map +1 -1
  248. package/dist/src/serialization/json.spec.js +47 -2
  249. package/dist/src/serialization/json.spec.js.map +1 -1
  250. package/dist/src/serialization/json_schema.d.ts +15 -11
  251. package/dist/src/serialization/json_schema.d.ts.map +1 -1
  252. package/dist/src/serialization/json_schema.js +21 -36
  253. package/dist/src/serialization/json_schema.js.map +1 -1
  254. package/dist/src/serialization/json_schema.spec.js +26 -32
  255. package/dist/src/serialization/json_schema.spec.js.map +1 -1
  256. package/dist/src/serialization/json_schema_to_type.d.ts +10 -5
  257. package/dist/src/serialization/json_schema_to_type.d.ts.map +1 -1
  258. package/dist/src/serialization/json_schema_to_type.js +13 -6
  259. package/dist/src/serialization/json_schema_to_type.js.map +1 -1
  260. package/dist/src/serialization/json_schema_to_type.spec.js +19 -0
  261. package/dist/src/serialization/json_schema_to_type.spec.js.map +1 -1
  262. package/dist/src/string_order.d.ts +36 -0
  263. package/dist/src/string_order.d.ts.map +1 -0
  264. package/dist/src/string_order.js +64 -0
  265. package/dist/src/string_order.js.map +1 -0
  266. package/dist/src/string_order.spec.d.ts +6 -0
  267. package/dist/src/string_order.spec.d.ts.map +1 -0
  268. package/dist/src/string_order.spec.js +79 -0
  269. package/dist/src/string_order.spec.js.map +1 -0
  270. package/dist/src/type_of_type.d.ts +17 -0
  271. package/dist/src/type_of_type.d.ts.map +1 -1
  272. package/dist/src/type_of_type.js +66 -0
  273. package/dist/src/type_of_type.js.map +1 -1
  274. package/dist/src/type_of_type.to_etv.spec.js +69 -1
  275. package/dist/src/type_of_type.to_etv.spec.js.map +1 -1
  276. package/package.json +1 -1
@@ -2,4419 +2,12 @@
2
2
  * Copyright (c) 2025 Elara AI Pty Ltd
3
3
  * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
4
  */
5
- import {} from "./builtins.js";
6
- import {} from "./ir.js";
7
- import { compareFor, equalFor, greaterEqualFor, greaterFor, isFor, lessEqualFor, lessFor, notEqualFor } from "./comparison.js";
8
- import { diffFor } from "./patch/diff.js";
9
- import { applyFor } from "./patch/apply.js";
10
- import { composeFor } from "./patch/compose.js";
11
- import { invertFor } from "./patch/invert.js";
12
- import { ConflictError } from "./patch/index.js";
13
- import { printFor, parseFor } from "./serialization/east.js";
14
- import { variant } from "./containers/variant.js";
15
- import { isFrozenValue } from "./frozen.js";
16
- import { EastError, InternalError } from "./error.js";
17
- import { get_current_source_map } from "./location.js";
18
- import { SortedSet } from "./containers/sortedset.js";
19
- import { SortedMap } from "./containers/sortedmap.js";
20
- import { BufferWriter } from "./serialization/binary-utils.js";
21
- import { decodeBeast2For, decodeBeastFor, encodeBeast2For, encodeBeastFor, fromJSONFor, toJSONFor, decodeCsvFor, encodeCsvFor, openBeast2LazyFor, isBeast2LazySafe, readBeast2Extents, readBeast2Type } from "./serialization/index.js";
22
- import { formatDateTime } from "./datetime_format/print.js";
23
- import { parseDateTimeFormatted } from "./datetime_format/parse.js";
24
- import { EastTypeValueType, isTypeValueEqual, expandTypeValue } from "./type_of_type.js";
25
- import { ref } from "./containers/ref.js";
26
- import { matrix } from "./containers/matrix.js";
27
- export { isTypeValueEqual };
28
- export const printTypeValue = printFor(EastTypeValueType);
29
- /**
30
- * Symbol used to attach source IR to compiled functions.
31
- * This enables serialization of free functions (functions with no captures).
32
- */
33
- export const EAST_IR_SYMBOL = Symbol.for("east.ir");
34
- /**
35
- * Symbol used to attach capture values to compiled functions.
36
- * This enables serialization of closures (functions with captures).
37
- */
38
- export const EAST_CAPTURES_SYMBOL = Symbol.for("east.captures");
39
- /**
40
- * Symbol used to attach source map to compiled functions.
41
- * Enables encoding location stacks into beast2 source_map_section.
42
- */
43
- export const EAST_SOURCE_MAP_SYMBOL = Symbol.for("east.source_map");
44
- /** Determines if a variable requires boxing (mutable + captured) */
45
- export function requiresBoxing(variable) {
46
- return variable.mutable && variable.captured;
47
- }
48
- /** Get a context value, throwing InternalError if missing */
49
- function getContextValue(ctx, name) {
50
- const value = ctx[name];
51
- if (value === undefined) {
52
- throw new InternalError(`Variable '${name}' not found in runtime context`);
53
- }
54
- return value;
55
- }
56
- // =============================================================================
57
- /** @internal The frozen-mutation error message — identical across the TS, C
58
- * and Python runtimes (compliance-tested), so a body that mutates a frozen
59
- * task input fails the same way everywhere. */
60
- const FROZEN_MESSAGE = "cannot mutate a frozen value (task inputs are immutable) — copy first";
61
- /** @internal Track iteration locks to prevent concurrent modification */
62
- const iterationLocks = new WeakMap();
63
- /** @internal Lock a collection for iteration (prevents size/keyset modifications) */
64
- const lockForIteration = (obj) => {
65
- iterationLocks.set(obj, (iterationLocks.get(obj) || 0) + 1);
66
- };
67
- /** @internal Unlock a collection after iteration */
68
- const unlockForIteration = (obj) => {
69
- const count = iterationLocks.get(obj) || 0;
70
- if (count > 1) {
71
- iterationLocks.set(obj, count - 1);
72
- }
73
- else {
74
- iterationLocks.delete(obj);
75
- }
76
- };
77
- /** @internal An exception throw for the purpose of early function return */
78
- export class ReturnException {
79
- value;
80
- constructor(value) {
81
- this.value = value;
82
- }
83
- }
84
- /** @internal An exception throw for the purpose of early loop continue */
85
- class ContinueException {
86
- label;
87
- constructor(label) {
88
- this.label = label;
89
- }
90
- }
91
- /** @internal An exception throw for the purpose of early loop break */
92
- class BreakException {
93
- label;
94
- constructor(label) {
95
- this.label = label;
96
- }
97
- }
98
- /** Compile `IR` into a JavaScript function using a closure-compiler technique.
99
- * This should execute faster than a simple tree-walking interpreter, but slower than hand-written Javascript.
100
- *
101
- * A "context" of the current variables in scope is given. For toplevel function IR, provide `{}`.
102
- * A "platform" is provided with JavaScript functions to perform effects, like logging. If no effects are needed, simply provide `{}`.
103
- *
104
- * @internal
105
- */
106
- // Captured once per top-level compile; all closures share the same SourceMap.
107
- let _compile_source_map = null;
108
- export function compile_internal(ir, ctx, platform, asyncPlatformFns, platformDef, fresh_ctx = true, compilingNodes = new Set()) {
109
- // Capture source map from the active scope on first call
110
- if (fresh_ctx)
111
- _compile_source_map = get_current_source_map();
112
- const source_map = _compile_source_map;
113
- // The IR is checked prior to compilation, so we can assume it's valid here.
114
- // The compiler needs to take care that Promises are properly awaited, so most IR nodes need both sync and async implementations.
115
- // We assume unnecessary `async` functions degrade performance but unnecessary `await`s are not too bad, so while we could be more "specific" in our awaits we do not bother
116
- if (ir.type === "Value") {
117
- const v = ir.value.value.value;
118
- return (_ctx) => v;
119
- }
120
- else if (ir.type === "Error") {
121
- const message_compiled = compile_internal(ir.value.message, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
122
- if (ir.value.isAsync) {
123
- const err_location = source_map?.resolve(ir.value.loc_id) ?? [];
124
- return async (ctx) => { throw new EastError(await message_compiled(ctx), { location: err_location }); };
125
- }
126
- else {
127
- const err_location = source_map?.resolve(ir.value.loc_id) ?? [];
128
- return (ctx) => { throw new EastError(message_compiled(ctx), { location: err_location }); };
129
- }
130
- }
131
- else if (ir.type === "TryCatch") {
132
- const try_body = compile_internal(ir.value.try_body, Object.create(ctx), platform, asyncPlatformFns, platformDef, true, compilingNodes);
133
- const new_ctx = Object.create(ctx);
134
- const message_name = ir.value.message.value.name;
135
- const stack_name = ir.value.stack.value.name;
136
- new_ctx[message_name] = ir.value.message.value.type;
137
- new_ctx[stack_name] = ir.value.stack.value.type;
138
- const catch_body = compile_internal(ir.value.catch_body, new_ctx, platform, asyncPlatformFns, platformDef, true, compilingNodes);
139
- // Don't include finally unless necessary (Value nodes are effect free)
140
- const finally_body = ir.value.finally_body.type === "Value" ? undefined : compile_internal(ir.value.finally_body, Object.create(ctx), platform, asyncPlatformFns, platformDef, true, compilingNodes);
141
- if (ir.value.isAsync) {
142
- if (finally_body === undefined) {
143
- return async (ctx) => {
144
- try {
145
- return await try_body(Object.create(ctx));
146
- }
147
- catch (e) {
148
- if (e instanceof EastError) {
149
- const new_ctx = Object.create(ctx);
150
- new_ctx[message_name] = variant("value", e.message);
151
- new_ctx[stack_name] = variant("value", e.location.map(l => ({ filename: l.filename, line: l.line, column: l.column })));
152
- return await catch_body(new_ctx);
153
- }
154
- else {
155
- throw (e);
156
- }
157
- }
158
- };
159
- }
160
- else {
161
- return async (ctx) => {
162
- try {
163
- return await try_body(Object.create(ctx));
164
- }
165
- catch (e) {
166
- if (e instanceof EastError) {
167
- const new_ctx = Object.create(ctx);
168
- new_ctx[message_name] = variant("value", e.message);
169
- new_ctx[stack_name] = variant("value", e.location.map(l => ({ filename: l.filename, line: l.line, column: l.column })));
170
- return await catch_body(new_ctx);
171
- }
172
- else {
173
- throw (e);
174
- }
175
- }
176
- finally {
177
- await finally_body(Object.create(ctx));
178
- }
179
- };
180
- }
181
- }
182
- else {
183
- if (finally_body === undefined) {
184
- return (ctx) => {
185
- try {
186
- return try_body(Object.create(ctx));
187
- }
188
- catch (e) {
189
- if (e instanceof EastError) {
190
- const new_ctx = Object.create(ctx);
191
- new_ctx[message_name] = variant("value", e.message);
192
- new_ctx[stack_name] = variant("value", e.location.map(l => ({ filename: l.filename, line: l.line, column: l.column })));
193
- return catch_body(new_ctx);
194
- }
195
- else {
196
- throw (e);
197
- }
198
- }
199
- };
200
- }
201
- else {
202
- return (ctx) => {
203
- try {
204
- return try_body(Object.create(ctx));
205
- }
206
- catch (e) {
207
- if (e instanceof EastError) {
208
- const new_ctx = Object.create(ctx);
209
- new_ctx[message_name] = variant("value", e.message);
210
- new_ctx[stack_name] = variant("value", e.location.map(l => ({ filename: l.filename, line: l.line, column: l.column })));
211
- return catch_body(new_ctx);
212
- }
213
- else {
214
- throw (e);
215
- }
216
- }
217
- finally {
218
- finally_body(Object.create(ctx));
219
- }
220
- };
221
- }
222
- }
223
- }
224
- else if (ir.type === "Variable") {
225
- const name = ir.value.name;
226
- // All context values are variants - read via .value
227
- return (ctx) => getContextValue(ctx, name).value;
228
- }
229
- else if (ir.type === "Let") {
230
- const compiled_statement = compile_internal(ir.value.value, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
231
- const name = ir.value.variable.value.name;
232
- ctx[name] = ir.value.variable.value.type;
233
- const boxed = requiresBoxing(ir.value.variable.value);
234
- if (ir.value.isAsync) {
235
- return async (ctx) => {
236
- ctx[name] = boxed
237
- ? variant("boxed", await compiled_statement(ctx))
238
- : variant("value", await compiled_statement(ctx));
239
- return null;
240
- };
241
- }
242
- else {
243
- return (ctx) => {
244
- ctx[name] = boxed
245
- ? variant("boxed", compiled_statement(ctx))
246
- : variant("value", compiled_statement(ctx));
247
- return null;
248
- };
249
- }
250
- }
251
- else if (ir.type === "Assign") {
252
- const name = ir.value.variable.value.name;
253
- const compiled_statement = compile_internal(ir.value.value, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
254
- if (requiresBoxing(ir.value.variable.value)) {
255
- // Boxed variables: mutate in place via .value
256
- if (ir.value.isAsync) {
257
- return async (ctx) => {
258
- getContextValue(ctx, name).value = await compiled_statement(ctx);
259
- return null;
260
- };
261
- }
262
- else {
263
- return (ctx) => {
264
- getContextValue(ctx, name).value = compiled_statement(ctx);
265
- return null;
266
- };
267
- }
268
- }
269
- else {
270
- // Non-boxed variables: replace the variant
271
- if (ir.value.isAsync) {
272
- return async (ctx) => {
273
- const value = await compiled_statement(ctx);
274
- // We need to check in which prototype the variable lives
275
- while (!Object.hasOwn(ctx, name))
276
- ctx = Object.getPrototypeOf(ctx);
277
- ctx[name] = variant("value", value);
278
- return null;
279
- };
280
- }
281
- else {
282
- return (ctx) => {
283
- const value = compiled_statement(ctx);
284
- // We need to check in which prototype the variable lives
285
- while (!Object.hasOwn(ctx, name))
286
- ctx = Object.getPrototypeOf(ctx);
287
- ctx[name] = variant("value", value);
288
- return null;
289
- };
290
- }
291
- }
292
- }
293
- else if (ir.type === "As") {
294
- // in dynamically typed runtimes like Javascript, this is a no-op
295
- // (for statically typed runtimes this assists in unifying types in branches)
296
- return compile_internal(ir.value.value, ctx, platform, asyncPlatformFns, platformDef, fresh_ctx, compilingNodes);
297
- }
298
- else if (ir.type === "UnwrapRecursive") {
299
- // in dynamically typed runtimes like Javascript, this is a no-op
300
- // (for statically typed runtimes this assists in e.g. typing a reference or pointer)
301
- return compile_internal(ir.value.value, ctx, platform, asyncPlatformFns, platformDef, fresh_ctx, compilingNodes);
302
- }
303
- else if (ir.type === "WrapRecursive") {
304
- // in dynamically typed runtimes like Javascript, this is a no-op
305
- // (for statically typed runtimes this assists in e.g. typing a heap allocation)
306
- return compile_internal(ir.value.value, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
307
- }
308
- else if (ir.type === "Function") {
309
- // Compile-time type context for body compilation
310
- const typeCtx = {};
311
- for (const variable of ir.value.captures) {
312
- typeCtx[variable.value.name] = variable.value.type;
313
- }
314
- for (const parameter of ir.value.parameters) {
315
- typeCtx[parameter.value.name] = parameter.value.type;
316
- }
317
- const compiled_body = compile_internal(ir.value.body, typeCtx, platform, asyncPlatformFns, platformDef, true, compilingNodes);
318
- const capture_names = ir.value.captures.map(v => v.value.name);
319
- const parameter_names = ir.value.parameters.map(v => v.value.name);
320
- // Store original IR for potential serialization
321
- const originalIR = ir;
322
- return (ctx) => {
323
- // Runtime context for captured values
324
- const captureCtx = {};
325
- for (const name of capture_names) {
326
- captureCtx[name] = getContextValue(ctx, name);
327
- }
328
- const fn = (...args) => {
329
- const fnCtx = { ...captureCtx };
330
- parameter_names.forEach((name, i) => fnCtx[name] = variant("value", args[i]));
331
- return compiled_body(fnCtx);
332
- };
333
- // Attach IR to function for serialization support
334
- Object.defineProperty(fn, EAST_IR_SYMBOL, {
335
- value: originalIR,
336
- writable: false,
337
- enumerable: false,
338
- configurable: false
339
- });
340
- // Attach capture values for serialization support
341
- Object.defineProperty(fn, EAST_CAPTURES_SYMBOL, {
342
- value: captureCtx,
343
- writable: false,
344
- enumerable: false,
345
- configurable: false
346
- });
347
- // Propagate source map from enclosing compilation scope
348
- if (source_map) {
349
- Object.defineProperty(fn, EAST_SOURCE_MAP_SYMBOL, {
350
- value: source_map,
351
- writable: false,
352
- enumerable: false,
353
- configurable: false
354
- });
355
- }
356
- return fn;
357
- };
358
- }
359
- else if (ir.type === "AsyncFunction") {
360
- // Compile-time type context for body compilation
361
- const typeCtx = {};
362
- for (const variable of ir.value.captures) {
363
- typeCtx[variable.value.name] = variable.value.type;
364
- }
365
- for (const parameter of ir.value.parameters) {
366
- typeCtx[parameter.value.name] = parameter.value.type;
367
- }
368
- const compiled_body = compile_internal(ir.value.body, typeCtx, platform, asyncPlatformFns, platformDef, true, compilingNodes);
369
- const capture_names = ir.value.captures.map(v => v.value.name);
370
- const parameter_names = ir.value.parameters.map(v => v.value.name);
371
- // Store original IR for potential serialization
372
- const originalIR = ir;
373
- return (ctx) => {
374
- // Runtime context for captured values
375
- const captureCtx = {};
376
- for (const name of capture_names) {
377
- captureCtx[name] = getContextValue(ctx, name);
378
- }
379
- const fn = (...args) => {
380
- const fnCtx = { ...captureCtx };
381
- parameter_names.forEach((name, i) => fnCtx[name] = variant("value", args[i]));
382
- return compiled_body(fnCtx); // Promise can pass through in tail position
383
- };
384
- // Attach IR to function for serialization support
385
- Object.defineProperty(fn, EAST_IR_SYMBOL, {
386
- value: originalIR,
387
- writable: false,
388
- enumerable: false,
389
- configurable: false
390
- });
391
- // Attach capture values for serialization support
392
- Object.defineProperty(fn, EAST_CAPTURES_SYMBOL, {
393
- value: captureCtx,
394
- writable: false,
395
- enumerable: false,
396
- configurable: false
397
- });
398
- // Propagate source map from enclosing compilation scope
399
- if (source_map) {
400
- Object.defineProperty(fn, EAST_SOURCE_MAP_SYMBOL, {
401
- value: source_map,
402
- writable: false,
403
- enumerable: false,
404
- configurable: false
405
- });
406
- }
407
- return fn;
408
- };
409
- }
410
- else if (ir.type === "Call") {
411
- const compiled_f = compile_internal(ir.value.function, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
412
- const compiled_args = ir.value.arguments.map(argument => compile_internal(argument, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes));
413
- const loc_id = ir.value.loc_id;
414
- if (ir.value.isAsync) {
415
- // need to await the arguments
416
- return async (ctx) => {
417
- try {
418
- const args = [];
419
- for (const compiled_arg of compiled_args) {
420
- args.push(await compiled_arg(ctx));
421
- }
422
- return compiled_f(ctx)(...args);
423
- }
424
- catch (e) {
425
- if (e instanceof ReturnException) {
426
- return e.value;
427
- }
428
- else if (e instanceof EastError) {
429
- // TODO: push loc_id to EastError once SourceMap resolution is wired up
430
- throw (e);
431
- }
432
- else if (e instanceof ContinueException) {
433
- throw new Error(`continue failed to find label ${e.label} at loc_id ${loc_id}`);
434
- }
435
- else if (e instanceof BreakException) {
436
- throw new Error(`break failed to find label ${e.label} at loc_id ${loc_id}`);
437
- }
438
- else {
439
- throw (e);
440
- }
441
- }
442
- };
443
- }
444
- else {
445
- return (ctx) => {
446
- try {
447
- return compiled_f(ctx)(...compiled_args.map(arg => arg(ctx)));
448
- }
449
- catch (e) {
450
- if (e instanceof ReturnException) {
451
- return e.value;
452
- }
453
- else if (e instanceof EastError) {
454
- // TODO: push loc_id to EastError once SourceMap resolution is wired up
455
- throw (e);
456
- }
457
- else if (e instanceof ContinueException) {
458
- throw new Error(`continue failed to find label ${e.label} at loc_id ${loc_id}`);
459
- }
460
- else if (e instanceof BreakException) {
461
- throw new Error(`break failed to find label ${e.label} at loc_id ${loc_id}`);
462
- }
463
- else {
464
- throw (e);
465
- }
466
- }
467
- };
468
- }
469
- }
470
- else if (ir.type === "CallAsync") {
471
- const compiled_f = compile_internal(ir.value.function, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
472
- const compiled_args = ir.value.arguments.map(argument => compile_internal(argument, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes));
473
- const loc_id = ir.value.loc_id;
474
- return async (ctx) => {
475
- try {
476
- const args = [];
477
- for (const compiled_arg of compiled_args) {
478
- args.push(await compiled_arg(ctx));
479
- }
480
- return await compiled_f(ctx)(...args);
481
- }
482
- catch (e) {
483
- if (e instanceof ReturnException) {
484
- return e.value;
485
- }
486
- else if (e instanceof EastError) {
487
- // TODO: push loc_id to EastError once SourceMap resolution is wired up
488
- throw (e);
489
- }
490
- else if (e instanceof ContinueException) {
491
- throw new Error(`continue failed to find label ${e.label} at loc_id ${loc_id}`);
492
- }
493
- else if (e instanceof BreakException) {
494
- throw new Error(`break failed to find label ${e.label} at loc_id ${loc_id}`);
495
- }
496
- else {
497
- throw (e);
498
- }
499
- }
500
- };
501
- }
502
- else if (ir.type === "IfElse") {
503
- const ifs = [];
504
- let asyncPredicate = false;
505
- for (const { predicate, body } of ir.value.ifs) {
506
- if (predicate.value.isAsync) {
507
- asyncPredicate = true;
508
- }
509
- ifs.push({
510
- predicate: compile_internal(predicate, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes),
511
- body: compile_internal(body, Object.create(ctx), platform, asyncPlatformFns, platformDef, true, compilingNodes),
512
- });
513
- }
514
- const else_body = compile_internal(ir.value.else_body, Object.create(ctx), platform, asyncPlatformFns, platformDef, true, compilingNodes);
515
- if (ir.value.isAsync) {
516
- if (asyncPredicate) {
517
- return async (ctx) => {
518
- for (const { predicate, body } of ifs) {
519
- if (await predicate(ctx)) {
520
- return await body(Object.create(ctx));
521
- }
522
- }
523
- return await else_body(Object.create(ctx));
524
- };
525
- }
526
- else {
527
- return async (ctx) => {
528
- for (const { predicate, body } of ifs) {
529
- if (predicate(ctx)) {
530
- return await body(Object.create(ctx));
531
- }
532
- }
533
- return await else_body(Object.create(ctx));
534
- };
535
- }
536
- }
537
- else {
538
- return (ctx) => {
539
- for (const { predicate, body } of ifs) {
540
- if (predicate(ctx)) {
541
- return body(Object.create(ctx));
542
- }
543
- }
544
- return else_body(Object.create(ctx));
545
- };
546
- }
547
- }
548
- else if (ir.type === "Match") {
549
- const compiled_variant = compile_internal(ir.value.variant, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
550
- const compiled_cases = {};
551
- const data_names = {};
552
- for (const { case: k, variable, body } of ir.value.cases) {
553
- const ctx2 = Object.create(ctx);
554
- const data_name = variable.value.name;
555
- data_names[k] = data_name;
556
- ctx2[data_name] = variable.value.type;
557
- compiled_cases[k] = compile_internal(body, ctx2, platform, asyncPlatformFns, platformDef, true, compilingNodes);
558
- }
559
- if (ir.value.isAsync) {
560
- if (ir.value.variant.value.isAsync) {
561
- return async (ctx) => {
562
- const v = await compiled_variant(ctx);
563
- const ctx2 = Object.create(ctx);
564
- ctx2[data_names[v.type]] = variant("value", v.value);
565
- return await compiled_cases[v.type](ctx2);
566
- };
567
- }
568
- else {
569
- return async (ctx) => {
570
- const v = compiled_variant(ctx);
571
- const ctx2 = Object.create(ctx);
572
- ctx2[data_names[v.type]] = variant("value", v.value);
573
- return await compiled_cases[v.type](ctx2);
574
- };
575
- }
576
- }
577
- else {
578
- return (ctx) => {
579
- const v = compiled_variant(ctx);
580
- const ctx2 = Object.create(ctx);
581
- ctx2[data_names[v.type]] = variant("value", v.value);
582
- return compiled_cases[v.type](ctx2);
583
- };
584
- }
585
- }
586
- else if (ir.type === "While") {
587
- const compiled_predicate = compile_internal(ir.value.predicate, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
588
- const ctx2 = Object.create(ctx);
589
- const compiled_body = compile_internal(ir.value.body, ctx2, platform, asyncPlatformFns, platformDef, true, compilingNodes);
590
- const label = ir.value.label.name;
591
- if (ir.value.isAsync) {
592
- return async (ctx) => {
593
- while (await compiled_predicate(ctx)) {
594
- try {
595
- const ctx2 = Object.create(ctx);
596
- await compiled_body(ctx2);
597
- }
598
- catch (e) {
599
- if (e instanceof ContinueException && e.label === label) {
600
- continue;
601
- }
602
- else if (e instanceof BreakException && e.label === label) {
603
- break;
604
- }
605
- else {
606
- throw e;
607
- }
608
- }
609
- }
610
- return null;
611
- };
612
- }
613
- else {
614
- return (ctx) => {
615
- while (compiled_predicate(ctx)) {
616
- try {
617
- const ctx2 = Object.create(ctx);
618
- compiled_body(ctx2);
619
- }
620
- catch (e) {
621
- if (e instanceof ContinueException && e.label === label) {
622
- continue;
623
- }
624
- else if (e instanceof BreakException && e.label === label) {
625
- break;
626
- }
627
- else {
628
- throw e;
629
- }
630
- }
631
- }
632
- return null;
633
- };
634
- }
635
- }
636
- else if (ir.type === "ForArray") {
637
- const value_type = expandTypeValue(ir.value.array.value.type).value;
638
- const compiled_array = compile_internal(ir.value.array, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
639
- const ctx2 = Object.create(ctx);
640
- const key_name = ir.value.key.value.name;
641
- const value_name = ir.value.value.value.name;
642
- ctx2[key_name] = variant("Integer", null);
643
- ctx2[value_name] = value_type;
644
- const compiled_body = compile_internal(ir.value.body, ctx2, platform, asyncPlatformFns, platformDef, true, compilingNodes);
645
- const label = ir.value.label.name;
646
- if (ir.value.isAsync) {
647
- return async (ctx) => {
648
- const array = await compiled_array(ctx);
649
- lockForIteration(array);
650
- try {
651
- for (const [key, value] of array.entries()) {
652
- const ctx2 = Object.create(ctx);
653
- ctx2[key_name] = variant("value", BigInt(key));
654
- ctx2[value_name] = variant("value", value);
655
- try {
656
- await compiled_body(ctx2);
657
- }
658
- catch (e) {
659
- if (e instanceof ContinueException && e.label === label) {
660
- continue;
661
- }
662
- else if (e instanceof BreakException && e.label === label) {
663
- break;
664
- }
665
- else {
666
- throw e;
667
- }
668
- }
669
- }
670
- return null;
671
- }
672
- finally {
673
- unlockForIteration(array);
674
- }
675
- };
676
- }
677
- else {
678
- return (ctx) => {
679
- const array = compiled_array(ctx);
680
- lockForIteration(array);
681
- try {
682
- for (const [key, value] of array.entries()) {
683
- const ctx2 = Object.create(ctx);
684
- ctx2[key_name] = variant("value", BigInt(key));
685
- ctx2[value_name] = variant("value", value);
686
- try {
687
- compiled_body(ctx2);
688
- }
689
- catch (e) {
690
- if (e instanceof ContinueException && e.label === label) {
691
- continue;
692
- }
693
- else if (e instanceof BreakException && e.label === label) {
694
- break;
695
- }
696
- else {
697
- throw e;
698
- }
699
- }
700
- }
701
- return null;
702
- }
703
- finally {
704
- unlockForIteration(array);
705
- }
706
- };
707
- }
708
- }
709
- else if (ir.type === "ForSet") {
710
- const key_type = expandTypeValue(ir.value.set.value.type).value;
711
- const compiled_set = compile_internal(ir.value.set, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
712
- const ctx2 = Object.create(ctx);
713
- const key_name = ir.value.key.value.name;
714
- ctx2[key_name] = key_type;
715
- const compiled_body = compile_internal(ir.value.body, ctx2, platform, asyncPlatformFns, platformDef, true, compilingNodes);
716
- const label = ir.value.label.name;
717
- if (ir.value.isAsync) {
718
- return async (ctx) => {
719
- const set = await compiled_set(ctx);
720
- lockForIteration(set);
721
- try {
722
- for (const key of set) {
723
- const ctx2 = Object.create(ctx);
724
- ctx2[key_name] = variant("value", key);
725
- try {
726
- await compiled_body(ctx2);
727
- }
728
- catch (e) {
729
- if (e instanceof ContinueException && e.label === label) {
730
- continue;
731
- }
732
- else if (e instanceof BreakException && e.label === label) {
733
- break;
734
- }
735
- else {
736
- throw e;
737
- }
738
- }
739
- }
740
- return null;
741
- }
742
- finally {
743
- unlockForIteration(set);
744
- }
745
- };
746
- }
747
- else {
748
- return (ctx) => {
749
- const set = compiled_set(ctx);
750
- lockForIteration(set);
751
- try {
752
- for (const key of set) {
753
- const ctx2 = Object.create(ctx);
754
- ctx2[key_name] = variant("value", key);
755
- try {
756
- compiled_body(ctx2);
757
- }
758
- catch (e) {
759
- if (e instanceof ContinueException && e.label === label) {
760
- continue;
761
- }
762
- else if (e instanceof BreakException && e.label === label) {
763
- break;
764
- }
765
- else {
766
- throw e;
767
- }
768
- }
769
- }
770
- return null;
771
- }
772
- finally {
773
- unlockForIteration(set);
774
- }
775
- };
776
- }
777
- }
778
- else if (ir.type === "ForDict") {
779
- const key_type = expandTypeValue(ir.value.dict.value.type).value.key;
780
- const value_type = expandTypeValue(ir.value.dict.value.type).value.value;
781
- const compiled_dict = compile_internal(ir.value.dict, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
782
- const ctx2 = Object.create(ctx);
783
- const key_name = ir.value.key.value.name;
784
- const value_name = ir.value.value.value.name;
785
- ctx2[key_name] = key_type;
786
- ctx2[value_name] = value_type;
787
- const compiled_body = compile_internal(ir.value.body, ctx2, platform, asyncPlatformFns, platformDef, true, compilingNodes);
788
- const label = ir.value.label.name;
789
- if (ir.value.isAsync) {
790
- return async (ctx) => {
791
- const dict = await compiled_dict(ctx);
792
- lockForIteration(dict);
793
- try {
794
- for (const [key, value] of dict) {
795
- const ctx2 = Object.create(ctx);
796
- ctx2[key_name] = variant("value", key);
797
- ctx2[value_name] = variant("value", value);
798
- try {
799
- await compiled_body(ctx2);
800
- }
801
- catch (e) {
802
- if (e instanceof ContinueException && e.label === label) {
803
- continue;
804
- }
805
- else if (e instanceof BreakException && e.label === label) {
806
- break;
807
- }
808
- else {
809
- throw e;
810
- }
811
- }
812
- }
813
- return null;
814
- }
815
- finally {
816
- unlockForIteration(dict);
817
- }
818
- };
819
- }
820
- else {
821
- return (ctx) => {
822
- const dict = compiled_dict(ctx);
823
- lockForIteration(dict);
824
- try {
825
- for (const [key, value] of dict) {
826
- const ctx2 = Object.create(ctx);
827
- ctx2[key_name] = variant("value", key);
828
- ctx2[value_name] = variant("value", value);
829
- try {
830
- compiled_body(ctx2);
831
- }
832
- catch (e) {
833
- if (e instanceof ContinueException && e.label === label) {
834
- continue;
835
- }
836
- else if (e instanceof BreakException && e.label === label) {
837
- break;
838
- }
839
- else {
840
- throw e;
841
- }
842
- }
843
- }
844
- return null;
845
- }
846
- finally {
847
- unlockForIteration(dict);
848
- }
849
- };
850
- }
851
- }
852
- else if (ir.type === "Block") {
853
- // The pattern of creating a new context (e.g. a function) and then immediately invoking a block (e.g. as the function body) is very common.
854
- // Here we avoid creating a second context when possible, as an optimization.
855
- if (fresh_ctx) {
856
- const compiled_statements = [];
857
- for (const statement of ir.value.statements) {
858
- const compiled_statement = compile_internal(statement, ctx, platform, asyncPlatformFns, platformDef, true, compilingNodes);
859
- compiled_statements.push(compiled_statement);
860
- }
861
- if (ir.value.isAsync) {
862
- return async (ctx) => {
863
- let ret = null;
864
- for (const statement of compiled_statements) {
865
- ret = await statement(ctx);
866
- }
867
- return ret;
868
- };
869
- }
870
- else {
871
- return (ctx) => {
872
- let ret = null;
873
- for (const statement of compiled_statements) {
874
- ret = statement(ctx);
875
- }
876
- return ret;
877
- };
878
- }
879
- }
880
- else {
881
- const ctx2 = Object.create(ctx);
882
- const compiled_statements = [];
883
- for (const statement of ir.value.statements) {
884
- const compiled_statement = compile_internal(statement, ctx2, platform, asyncPlatformFns, platformDef, true, compilingNodes);
885
- compiled_statements.push(compiled_statement);
886
- }
887
- if (ir.value.isAsync) {
888
- return async (ctx) => {
889
- const ctx2 = Object.create(ctx);
890
- let ret = null;
891
- for (const statement of compiled_statements) {
892
- ret = await statement(ctx2);
893
- }
894
- return ret;
895
- };
896
- }
897
- else {
898
- return (ctx) => {
899
- const ctx2 = Object.create(ctx);
900
- let ret = null;
901
- for (const statement of compiled_statements) {
902
- ret = statement(ctx2);
903
- }
904
- return ret;
905
- };
906
- }
907
- }
908
- }
909
- else if (ir.type === "GetField") {
910
- const struct = compile_internal(ir.value.struct, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
911
- const field = ir.value.field;
912
- if (ir.value.isAsync) {
913
- return async (ctx) => (await struct(ctx))[field];
914
- }
915
- else {
916
- return (ctx) => struct(ctx)[field];
917
- }
918
- }
919
- else if (ir.type === "Struct") {
920
- const fields = ir.value.fields.map(f => {
921
- return compile_internal(f.value, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
922
- });
923
- const keys = ir.value.fields.map(f => f.name);
924
- if (ir.value.isAsync) {
925
- return async (ctx) => {
926
- const fs = [];
927
- for (const [i, a] of fields.entries()) {
928
- fs.push([keys[i], await a(ctx)]);
929
- }
930
- return Object.fromEntries(fs);
931
- };
932
- }
933
- else {
934
- return (ctx) => Object.fromEntries(fields.map((a, i) => [keys[i], a(ctx)]));
935
- }
936
- }
937
- else if (ir.type === "Variant") {
938
- const k = ir.value.case;
939
- const v = compile_internal(ir.value.value, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
940
- if (ir.value.isAsync) {
941
- return async (ctx) => variant(k, await v(ctx));
942
- }
943
- else {
944
- return (ctx) => variant(k, v(ctx));
945
- }
946
- }
947
- else if (ir.type === "NewRef") {
948
- const value = compile_internal(ir.value.value, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
949
- if (ir.value.isAsync) {
950
- return async (ctx) => ref(await value(ctx));
951
- }
952
- else {
953
- return (ctx) => ref(value(ctx));
954
- }
955
- }
956
- else if (ir.type === "NewArray") {
957
- const values = ir.value.values.map(a => {
958
- return compile_internal(a, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
959
- });
960
- if (ir.value.isAsync) {
961
- return async (ctx) => {
962
- let vals = [];
963
- for (const a of values) {
964
- vals.push(await a(ctx));
965
- }
966
- return vals;
967
- };
968
- }
969
- else {
970
- return (ctx) => values.map(a => a(ctx));
971
- }
972
- }
973
- else if (ir.type === "NewSet") {
974
- const values = ir.value.values.map(a => {
975
- return compile_internal(a, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
976
- });
977
- const keyComparer = compareFor(ir.value.type.value);
978
- if (ir.value.isAsync) {
979
- return (ctx) => {
980
- const keys = [];
981
- for (const a of values) {
982
- keys.push(a(ctx));
983
- }
984
- return new SortedSet(keys, keyComparer);
985
- };
986
- }
987
- else {
988
- return (ctx) => new SortedSet(values.map(a => a(ctx)), keyComparer);
989
- }
990
- }
991
- else if (ir.type === "NewDict") {
992
- const values = ir.value.values.map(({ key, value }) => {
993
- return [compile_internal(key, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes), compile_internal(value, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes)];
994
- });
995
- const keyComparer = compareFor(ir.value.type.value.key);
996
- if (ir.value.isAsync) {
997
- return async (ctx) => {
998
- const entries = [];
999
- for (const [k, v] of values) {
1000
- entries.push([await k(ctx), await v(ctx)]);
1001
- }
1002
- return new SortedMap(entries, keyComparer);
1003
- };
1004
- }
1005
- else {
1006
- return (ctx) => new SortedMap(values.map(([k, v]) => [k(ctx), v(ctx)]), keyComparer);
1007
- }
1008
- }
1009
- else if (ir.type === "NewVector") {
1010
- const elementType = ir.value.type.value; // element EastTypeValue
1011
- const values = ir.value.values.map(a => {
1012
- return compile_internal(a, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
1013
- });
1014
- if (ir.value.isAsync) {
1015
- return async (ctx) => {
1016
- const vals = [];
1017
- for (const a of values) {
1018
- vals.push(await a(ctx));
1019
- }
1020
- return createTypedArray(elementType, vals);
1021
- };
1022
- }
1023
- else {
1024
- return (ctx) => {
1025
- const vals = values.map(a => a(ctx));
1026
- return createTypedArray(elementType, vals);
1027
- };
1028
- }
1029
- }
1030
- else if (ir.type === "NewMatrix") {
1031
- const elementType = ir.value.type.value;
1032
- const rows = Number(ir.value.rows);
1033
- const cols = Number(ir.value.cols);
1034
- const values = ir.value.values.map(a => {
1035
- return compile_internal(a, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
1036
- });
1037
- if (ir.value.isAsync) {
1038
- return async (ctx) => {
1039
- const vals = [];
1040
- for (const a of values) {
1041
- vals.push(await a(ctx));
1042
- }
1043
- return matrix(createTypedArray(elementType, vals), rows, cols);
1044
- };
1045
- }
1046
- else {
1047
- return (ctx) => {
1048
- const vals = values.map(a => a(ctx));
1049
- return matrix(createTypedArray(elementType, vals), rows, cols);
1050
- };
1051
- }
1052
- }
1053
- else if (ir.type === "Return") {
1054
- const compiled_value = compile_internal(ir.value.value, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
1055
- if (ir.value.isAsync) {
1056
- return async (ctx) => {
1057
- throw new ReturnException(await compiled_value(ctx));
1058
- };
1059
- }
1060
- else {
1061
- return (ctx) => {
1062
- throw new ReturnException(compiled_value(ctx));
1063
- };
1064
- }
1065
- }
1066
- else if (ir.type === "Continue") {
1067
- const label = ir.value.label;
1068
- return (_ctx) => {
1069
- throw new ContinueException(label.name);
1070
- };
1071
- }
1072
- else if (ir.type === "Break") {
1073
- const label = ir.value.label;
1074
- return (_ctx) => {
1075
- throw new BreakException(label.name);
1076
- };
1077
- }
1078
- else if (ir.type === "Builtin") {
1079
- let argsAsync = false;
1080
- const args = ir.value.arguments.map((a, _i) => {
1081
- if (a.value.isAsync) {
1082
- argsAsync = true;
1083
- }
1084
- return compile_internal(a, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
1085
- });
1086
- // Special optimization for regex builtins with literal pattern/flags
1087
- const loc_id = ir.value.loc_id;
1088
- if ((ir.value.builtin === "RegexContains" || ir.value.builtin === "RegexIndexOf" || ir.value.builtin === "RegexReplace") &&
1089
- ir.value.arguments[1]?.type === "Value" &&
1090
- ir.value.arguments[2]?.type === "Value") {
1091
- if (ir.value.arguments[1].value.value.type !== "String") {
1092
- throw new Error(`Regex builtin pattern argument must be String literal at loc_id ${ir.value.arguments[1].value.loc_id}`);
1093
- }
1094
- if (ir.value.arguments[2].value.value.type !== "String") {
1095
- throw new Error(`Regex builtin flags argument must be String literal at loc_id ${ir.value.arguments[2].value.loc_id}`);
1096
- }
1097
- // Compile regex once at closure compilation time
1098
- const pattern = ir.value.arguments[1].value.value.value;
1099
- const flags = ir.value.arguments[2].value.value.value;
1100
- const textArg = args[0]; // Already compiled text argument
1101
- if (ir.value.builtin === "RegexContains") {
1102
- const compiledRegex = new RegExp(pattern, flags);
1103
- return (ctx) => compiledRegex.test(textArg(ctx));
1104
- }
1105
- else if (ir.value.builtin === "RegexIndexOf") {
1106
- const compiledRegex = new RegExp(pattern, flags);
1107
- return (ctx) => {
1108
- const text = textArg(ctx);
1109
- const codeUnitIndex = text.search(compiledRegex);
1110
- if (codeUnitIndex === -1)
1111
- return -1n;
1112
- // Convert code unit index to codepoint index
1113
- let codepointIndex = 0;
1114
- let codeUnitPos = 0;
1115
- for (const char of text) {
1116
- if (codeUnitPos === codeUnitIndex) {
1117
- return BigInt(codepointIndex);
1118
- }
1119
- codeUnitPos += char.length;
1120
- codepointIndex++;
1121
- }
1122
- return -1n;
1123
- };
1124
- }
1125
- else { // RegexReplace
1126
- // Precompile regex with global flag for replaceAll semantics
1127
- const globalFlags = flags.includes('g') ? flags : flags + 'g';
1128
- const compiledRegex = new RegExp(pattern, globalFlags);
1129
- // Check if replacement is also constant for full optimization
1130
- if (ir.value.arguments[3]?.type === "Value") {
1131
- if (ir.value.arguments[3].value.value.type !== "String") {
1132
- throw new Error(`RegexReplace builtin replacement argument must be String literal at loc_id ${ir.value.arguments[3].value.loc_id}`);
1133
- }
1134
- // FULL OPTIMIZATION: Pattern, flags, and replacement are all constant
1135
- const replacement = ir.value.arguments[3].value.value.value;
1136
- // Validate replacement string: only allow $$, $1-$9, and $<
1137
- // This is stricter than JavaScript's native behavior but provides clear, consistent semantics
1138
- // and avoids backend-specific features like $&, $`, $'
1139
- let i = 0;
1140
- while (i < replacement.length) {
1141
- const char = replacement[i];
1142
- if (char === '$') {
1143
- i += char.length;
1144
- let char2 = replacement[i];
1145
- if (char2 === undefined) {
1146
- return (_ctx) => { throw new EastError(`invalid regex replacement string: unescaped $ at end of string`, { location: (source_map?.resolve(loc_id) ?? []) }); };
1147
- }
1148
- else if (char2 === '$') {
1149
- i += 1;
1150
- }
1151
- else if (char2 >= '1' && char2 <= '9') {
1152
- i += 1;
1153
- char2 = replacement[i];
1154
- while (char2 !== undefined && char2 >= '0' && char2 <= '9') {
1155
- i += 1;
1156
- char2 = replacement[i];
1157
- }
1158
- }
1159
- else if (char2 === '<') {
1160
- // Scan until closing >
1161
- i += 1;
1162
- const init_i = i;
1163
- char2 = replacement[i];
1164
- while (true) {
1165
- if (char2 === undefined) {
1166
- return (_ctx) => { throw new EastError(`invalid regex replacement string: unterminated group name in $<...>`, { location: (source_map?.resolve(loc_id) ?? []) }); };
1167
- }
1168
- if (char2 === '>') {
1169
- break;
1170
- }
1171
- if (!((char2 >= '0' && char2 <= '9') || (char2 >= 'a' && char2 <= 'z') || (char2 >= 'A' && char2 <= 'Z') || char2 === '_')) {
1172
- return (_ctx) => { throw new EastError(`invalid regex replacement string: invalid character ${JSON.stringify(char2)} in group name in $<...>`, { location: (source_map?.resolve(loc_id) ?? []) }); };
1173
- }
1174
- i += 1;
1175
- char2 = replacement[i];
1176
- }
1177
- if (i === init_i) {
1178
- return (_ctx) => { throw new EastError(`invalid regex replacement string: empty group name in $<>`, { location: (source_map?.resolve(loc_id) ?? []) }); };
1179
- }
1180
- i += 1; // for closing >
1181
- }
1182
- else {
1183
- return (_ctx) => { throw new EastError(`invalid regex replacement string: unescaped $ at $${char2}`, { location: (source_map?.resolve(loc_id) ?? []) }); };
1184
- }
1185
- }
1186
- else {
1187
- i += char.length;
1188
- }
1189
- }
1190
- return (ctx) => {
1191
- const text = textArg(ctx);
1192
- return text.replaceAll(compiledRegex, replacement);
1193
- };
1194
- }
1195
- else {
1196
- // PARTIAL OPTIMIZATION: Pattern and flags constant, replacement dynamic
1197
- const replacementArg = args[3];
1198
- return (ctx) => {
1199
- const text = textArg(ctx);
1200
- const replacement = replacementArg(ctx);
1201
- // Validate replacement string: only allow $$, $1-$9, and $<
1202
- // This is stricter than JavaScript's native behavior but provides clear, consistent semantics
1203
- // and avoids backend-specific features like $&, $`, $'
1204
- let i = 0;
1205
- while (i < replacement.length) {
1206
- const char = replacement[i];
1207
- if (char === '$') {
1208
- i += char.length;
1209
- let char2 = replacement[i];
1210
- if (char2 === undefined) {
1211
- throw new EastError(`invalid regex replacement string: unescaped $ at end of string`, { location: (source_map?.resolve(loc_id) ?? []) });
1212
- }
1213
- else if (char2 === '$') {
1214
- i += 1;
1215
- }
1216
- else if (char2 >= '1' && char2 <= '9') {
1217
- i += 1;
1218
- char2 = replacement[i];
1219
- while (char2 !== undefined && char2 >= '0' && char2 <= '9') {
1220
- i += 1;
1221
- char2 = replacement[i];
1222
- }
1223
- }
1224
- else if (char2 === '<') {
1225
- // Scan until closing >
1226
- i += 1;
1227
- const init_i = i;
1228
- char2 = replacement[i];
1229
- while (true) {
1230
- if (char2 === undefined) {
1231
- throw new EastError(`invalid regex replacement string: unterminated group name in $<...>`, { location: (source_map?.resolve(loc_id) ?? []) });
1232
- }
1233
- if (char2 === '>') {
1234
- break;
1235
- }
1236
- if (!((char2 >= '0' && char2 <= '9') || (char2 >= 'a' && char2 <= 'z') || (char2 >= 'A' && char2 <= 'Z') || char2 === '_')) {
1237
- throw new EastError(`invalid regex replacement string: invalid character ${JSON.stringify(char2)} in group name in $<...>`, { location: (source_map?.resolve(loc_id) ?? []) });
1238
- }
1239
- i += 1;
1240
- char2 = replacement[i];
1241
- }
1242
- if (i === init_i) {
1243
- throw new EastError(`invalid regex replacement string: empty group name in $<>`, { location: (source_map?.resolve(loc_id) ?? []) });
1244
- }
1245
- i += 1; // for closing >
1246
- }
1247
- else {
1248
- throw new EastError(`invalid regex replacement string: unescaped $ at $${char2}`, { location: (source_map?.resolve(loc_id) ?? []) });
1249
- }
1250
- }
1251
- else {
1252
- i += char.length;
1253
- }
1254
- }
1255
- return text.replaceAll(compiledRegex, replacement);
1256
- };
1257
- }
1258
- }
1259
- }
1260
- const evaluator = builtin_evaluators[ir.value.builtin](ir.value.loc_id, source_map, platformDef, ...ir.value.type_parameters);
1261
- if (argsAsync) {
1262
- return async (ctx) => {
1263
- const args_resolved = [];
1264
- for (const a of args) {
1265
- args_resolved.push(await a(ctx));
1266
- }
1267
- return evaluator(...args_resolved);
1268
- };
1269
- }
1270
- else {
1271
- return (ctx) => evaluator(...args.map(a => a(ctx)));
1272
- }
1273
- }
1274
- else if (ir.type === "Platform") {
1275
- const loc_id = ir.value.loc_id;
1276
- let argsAsync = false;
1277
- const args = ir.value.arguments.map(a => {
1278
- if (a.value.isAsync) {
1279
- argsAsync = true;
1280
- }
1281
- return compile_internal(a, ctx, platform, asyncPlatformFns, platformDef, false, compilingNodes);
1282
- });
1283
- // Look up platform function definition to check if generic
1284
- const platformFn = platformDef.find(p => p.name === ir.value.name);
1285
- const typeParams = ir.value.type_parameters ?? [];
1286
- // Get evaluator - for generic functions, call factory with type params
1287
- let evaluator;
1288
- if (typeParams.length > 0 && platformFn?.type_parameters && platformFn.type_parameters.length > 0) {
1289
- // Generic platform function - fn is a factory that takes type params
1290
- if (!platformFn.fn) {
1291
- // Missing generic platform function - create stub that throws at runtime
1292
- const name = ir.value.name;
1293
- evaluator = () => {
1294
- throw new EastError(`Platform function '${name}' is not available`, { location: (source_map?.resolve(loc_id) ?? []) });
1295
- };
1296
- }
1297
- else {
1298
- evaluator = platformFn.fn(...typeParams);
1299
- }
1300
- }
1301
- else {
1302
- // Non-generic - use platform map for backwards compatibility
1303
- const platformEvaluator = platform[ir.value.name];
1304
- if (platformEvaluator === undefined) {
1305
- // Missing platform function - create stub that throws at runtime
1306
- const name = ir.value.name;
1307
- evaluator = () => {
1308
- throw new EastError(`Platform function '${name}' is not available`, { location: (source_map?.resolve(loc_id) ?? []) });
1309
- };
1310
- }
1311
- else {
1312
- evaluator = platformEvaluator;
1313
- }
1314
- }
1315
- if (argsAsync) {
1316
- return async (ctx) => {
1317
- const args_resolved = [];
1318
- for (const a of args) {
1319
- args_resolved.push(await a(ctx));
1320
- }
1321
- return evaluator(...args_resolved); // evaluator can return Promise unconditionally in tail position if the platform function is async
1322
- };
1323
- }
1324
- else {
1325
- return (ctx) => evaluator(...args.map(a => a(ctx))); // evaluator can return Promise unconditionally in tail position if the platform function is async
1326
- }
1327
- }
1328
- else {
1329
- throw new Error(`Unhandled IR type ${ir.type} at loc_id ${ir.value.loc_id}`); // The `satisfies never` here ensures that this branch is unreachable if all IR types are handled
1330
- }
1331
- }
1332
- /** Used to call a compiled function with the given arguments and handle errors within builtin functions */
1333
- function call_function(loc_id, source_map, compiled_f, ...args) {
1334
- try {
1335
- return compiled_f(...args);
1336
- }
1337
- catch (e) {
1338
- if (e instanceof ReturnException) {
1339
- return e.value;
1340
- }
1341
- else if (e instanceof EastError) {
1342
- // TODO: push loc_id to EastError once SourceMap resolution is wired up
1343
- throw (e);
1344
- }
1345
- else if (e instanceof ContinueException) {
1346
- throw new Error(`continue failed to find label ${e.label} at loc_id ${loc_id}`);
1347
- }
1348
- else if (e instanceof BreakException) {
1349
- throw new Error(`break failed to find label ${e.label} at loc_id ${loc_id}`);
1350
- }
1351
- else {
1352
- throw (e);
1353
- }
1354
- }
1355
- }
1356
- /** Allocates an empty TypedArray of the given length for a given element type */
1357
- function allocateTypedArray(elementType, length) {
1358
- if (elementType.type === "Float")
1359
- return new Float64Array(length);
1360
- if (elementType.type === "Integer")
1361
- return new BigInt64Array(length);
1362
- if (elementType.type === "Boolean")
1363
- return new Uint8ClampedArray(length);
1364
- throw new Error(`Unsupported vector element type: ${elementType.type}`);
1365
- }
1366
- /** Wraps to East's 64-bit Integer semantics */
1367
- function wrapI64(x) {
1368
- return BigInt.asIntN(64, x);
1369
- }
1370
- /** Throws unless the vector/matrix element type parameter is Float or Integer */
1371
- function requireNumericElem(builtin, T, loc_id, source_map) {
1372
- if (T.type !== "Float" && T.type !== "Integer") {
1373
- throw new EastError(`${builtin} requires Float or Integer elements`, { location: (source_map?.resolve(loc_id) ?? []) });
1374
- }
1375
- return T.type;
1376
- }
1377
- /** Throws the shared length-mismatch error for elementwise vector operands */
1378
- function requireSameLength(a, b, loc_id, source_map) {
1379
- if (a.length !== b.length) {
1380
- throw new EastError(`Vector length mismatch (${a.length} vs ${b.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
1381
- }
1382
- }
1383
- /** Throws the shared dimension-mismatch error for elementwise matrix operands */
1384
- function requireSameDims(a, b, loc_id, source_map) {
1385
- if (a.rows !== b.rows || a.cols !== b.cols) {
1386
- throw new EastError(`Matrix dimension mismatch (${a.rows}x${a.cols} vs ${b.rows}x${b.cols})`, { location: (source_map?.resolve(loc_id) ?? []) });
1387
- }
1388
- }
1389
- /** Validates the sparse-accumulator invariant: parallel lengths and strictly ascending indices */
1390
- function requireSparse(ix, v, loc_id, source_map) {
1391
- if (ix.length !== v.length) {
1392
- throw new EastError(`Sparse index and value lengths differ (${ix.length} vs ${v.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
1393
- }
1394
- for (let i = 1; i < ix.length; i++) {
1395
- if (ix[i] <= ix[i - 1]) {
1396
- throw new EastError(`Sparse index vector must be strictly ascending`, { location: (source_map?.resolve(loc_id) ?? []) });
1397
- }
1398
- }
1399
- }
1400
- /** Creates the appropriate TypedArray for a given element type */
1401
- function createTypedArray(elementType, values) {
1402
- if (elementType.type === "Float") {
1403
- const arr = new Float64Array(values.length);
1404
- for (let i = 0; i < values.length; i++)
1405
- arr[i] = values[i];
1406
- return arr;
1407
- }
1408
- else if (elementType.type === "Integer") {
1409
- const arr = new BigInt64Array(values.length);
1410
- for (let i = 0; i < values.length; i++)
1411
- arr[i] = values[i];
1412
- return arr;
1413
- }
1414
- else if (elementType.type === "Boolean") {
1415
- const arr = new Uint8ClampedArray(values.length);
1416
- for (let i = 0; i < values.length; i++)
1417
- arr[i] = values[i] ? 1 : 0;
1418
- return arr;
1419
- }
1420
- else {
1421
- throw new Error(`Unsupported vector element type: ${elementType.type}`);
1422
- }
1423
- }
1424
- /** @internal */
1425
- const builtin_evaluators = {
1426
- Is: (loc_id, source_map, _platformDef, T) => isFor(T),
1427
- Equal: (loc_id, source_map, _platformDef, T) => equalFor(T),
1428
- NotEqual: (loc_id, source_map, _platformDef, T) => notEqualFor(T),
1429
- Less: (loc_id, source_map, _platformDef, T) => lessFor(T),
1430
- LessEqual: (loc_id, source_map, _platformDef, T) => lessEqualFor(T),
1431
- Greater: (loc_id, source_map, _platformDef, T) => greaterFor(T),
1432
- GreaterEqual: (loc_id, source_map, _platformDef, T) => greaterEqualFor(T),
1433
- Diff: (loc_id, source_map, _platformDef, T) => diffFor(T),
1434
- ApplyPatch: (loc_id, source_map, _platformDef, T) => {
1435
- const apply = applyFor(T);
1436
- return (base, patch) => {
1437
- try {
1438
- return apply(base, patch);
1439
- }
1440
- catch (e) {
1441
- if (e instanceof ConflictError) {
1442
- throw new EastError(e.message, { location: (source_map?.resolve(loc_id) ?? []) });
1443
- }
1444
- throw e;
1445
- }
1446
- };
1447
- },
1448
- ComposePatch: (loc_id, source_map, _platformDef, T) => {
1449
- const compose = composeFor(T);
1450
- return (first, second) => {
1451
- try {
1452
- return compose(first, second);
1453
- }
1454
- catch (e) {
1455
- if (e instanceof ConflictError) {
1456
- throw new EastError(e.message, { location: (source_map?.resolve(loc_id) ?? []) });
1457
- }
1458
- throw e;
1459
- }
1460
- };
1461
- },
1462
- InvertPatch: (loc_id, source_map, _platformDef, T) => invertFor(T),
1463
- BooleanNot: (_loc_id, _source_map) => (x) => !x,
1464
- BooleanOr: (_loc_id, _source_map) => (x, y) => x || y,
1465
- BooleanAnd: (_loc_id, _source_map) => (x, y) => x && y,
1466
- BooleanXor: (_loc_id, _source_map) => (x, y) => x !== y,
1467
- IntegerToFloat: (_loc_id, _source_map) => (x) => Number(x),
1468
- IntegerNegate: (_loc_id, _source_map) => (x) => BigInt.asIntN(64, -x),
1469
- IntegerAdd: (_loc_id, _source_map) => (x, y) => BigInt.asIntN(64, x + y),
1470
- IntegerSubtract: (_loc_id, _source_map) => (x, y) => BigInt.asIntN(64, x - y),
1471
- IntegerMultiply: (_loc_id, _source_map) => (x, y) => BigInt.asIntN(64, x * y),
1472
- IntegerDivide: (loc_id, source_map) => (x, y) => {
1473
- if (y === 0n)
1474
- throw new EastError("Division by zero", { location: (source_map?.resolve(loc_id) ?? []) });
1475
- return BigInt.asIntN(64, x / y);
1476
- },
1477
- IntegerRemainder: (loc_id, source_map) => (x, y) => {
1478
- if (y === 0n)
1479
- throw new EastError("Division by zero", { location: (source_map?.resolve(loc_id) ?? []) });
1480
- return x % y;
1481
- },
1482
- IntegerPow: (_loc_id, _source_map) => (x, y) => y >= 0n ? BigInt.asIntN(64, x ** y) : 0n,
1483
- IntegerAbs: (_loc_id, _source_map) => (x) => BigInt.asIntN(64, x < 0n ? -x : x),
1484
- IntegerSign: (_loc_id, _source_map) => (x) => x > 0n ? 1n : x < 0n ? -1n : 0n,
1485
- IntegerLog: (_loc_id, _source_map) => (value, base) => {
1486
- if (value === 0n)
1487
- return 0n;
1488
- if (base <= 1n)
1489
- return 0n; // Invalid base
1490
- let abs_value = value < 0n ? -value : value;
1491
- let result = 0n;
1492
- while (abs_value >= base) {
1493
- abs_value = abs_value / base;
1494
- result = result + 1n;
1495
- }
1496
- return result;
1497
- },
1498
- FloatToInteger: (loc_id, source_map) => (x) => {
1499
- if (Number.isNaN(x))
1500
- throw new EastError("Cannot convert NaN to integer", { location: (source_map?.resolve(loc_id) ?? []) });
1501
- if (x >= 9223372036854775808)
1502
- throw new EastError("Float too high to convert to integer", { location: (source_map?.resolve(loc_id) ?? []) });
1503
- if (x < -9223372036854775808)
1504
- throw new EastError("Float too low to convert to integer", { location: (source_map?.resolve(loc_id) ?? []) });
1505
- if (!Number.isInteger(x)) {
1506
- throw new EastError("Cannot convert non-integer float to integer", { location: (source_map?.resolve(loc_id) ?? []) });
1507
- }
1508
- return BigInt(x);
1509
- },
1510
- FloatNegate: (_loc_id, _source_map) => (x) => -x,
1511
- FloatAdd: (_loc_id, _source_map) => (x, y) => x + y,
1512
- FloatSubtract: (_loc_id, _source_map) => (x, y) => x - y,
1513
- FloatMultiply: (_loc_id, _source_map) => (x, y) => x * y,
1514
- FloatDivide: (_loc_id, _source_map) => (x, y) => x / y,
1515
- FloatRemainder: (_loc_id, _source_map) => (x, y) => x % y,
1516
- FloatPow: (_loc_id, _source_map) => (x, y) => x ** y,
1517
- FloatAbs: (_loc_id, _source_map) => (x) => x < 0 ? -x : x,
1518
- FloatSign: (_loc_id, _source_map) => (x) => x > 0 ? 1 : x < 0 ? -1 : 0, // What sign is NaN?
1519
- FloatSqrt: (_loc_id, _source_map) => (value) => Math.sqrt(value),
1520
- FloatLog: (_loc_id, _source_map) => (value) => Math.log(value),
1521
- FloatExp: (_loc_id, _source_map) => (value) => Math.exp(value),
1522
- FloatSin: (_loc_id, _source_map) => (value) => Math.sin(value),
1523
- FloatCos: (_loc_id, _source_map) => (value) => Math.cos(value),
1524
- FloatTan: (_loc_id, _source_map) => (value) => Math.tan(value),
1525
- Print: (loc_id, source_map, _platformDef, T) => {
1526
- return printFor(T);
1527
- },
1528
- Parse: (loc_id, source_map, _platformDef, T) => {
1529
- const p = parseFor(T);
1530
- return (x) => {
1531
- const result = p(x);
1532
- if (result.success) {
1533
- return result.value;
1534
- }
1535
- else {
1536
- throw new EastError(`Failed to parse ${printTypeValue(T)} at ${result.position}: ${result.error}`, { location: (source_map?.resolve(loc_id) ?? []) });
1537
- }
1538
- };
1539
- },
1540
- StringConcat: (_loc_id, _source_map) => (x, y) => x + y,
1541
- StringRepeat: (_loc_id, _source_map) => (x, y) => y > 0n ? x.repeat(Number(y)) : "",
1542
- StringLength: (_loc_id, _source_map) => (x) => {
1543
- let len = 0;
1544
- for (const _ of x)
1545
- len++;
1546
- return BigInt(len);
1547
- },
1548
- StringSubstring: (_loc_id, _source_map) => (x, from, to) => {
1549
- // Convert bigint indices to numbers, handle forgiving semantics like JavaScript
1550
- let fromNum = Number(from);
1551
- let toNum = Number(to);
1552
- // Handle negative indices and lengths (forgiving semantics)
1553
- if (fromNum < 0)
1554
- fromNum = 0;
1555
- if (toNum < 0)
1556
- toNum = 0;
1557
- if (fromNum > toNum) {
1558
- toNum = fromNum;
1559
- }
1560
- // Convert codepoint indices to code unit indices
1561
- let codeUnitFrom = 0;
1562
- let codeUnitTo = 0;
1563
- let codepointIndex = 0;
1564
- for (const char of x) {
1565
- if (codepointIndex === fromNum) {
1566
- codeUnitFrom = codeUnitTo;
1567
- }
1568
- if (codepointIndex === toNum) {
1569
- break;
1570
- }
1571
- codeUnitTo += char.length;
1572
- codepointIndex++;
1573
- }
1574
- // If 'from' is beyond string length, return empty string
1575
- if (fromNum >= codepointIndex)
1576
- return "";
1577
- // If 'to' is beyond string length, use string end
1578
- if (toNum > codepointIndex) {
1579
- codeUnitTo = x.length;
1580
- }
1581
- return x.substring(codeUnitFrom, codeUnitTo);
1582
- },
1583
- StringUpperCase: (_loc_id, _source_map) => (x) => x.toUpperCase(),
1584
- StringLowerCase: (_loc_id, _source_map) => (x) => x.toLowerCase(),
1585
- StringSplit: (_loc_id, _source_map) => (x, delimiter) => {
1586
- if (delimiter === "") {
1587
- if (x === "") {
1588
- // Split always returns at least one element
1589
- return [""];
1590
- }
1591
- else {
1592
- // Split into individual codepoints
1593
- return [...x];
1594
- }
1595
- }
1596
- return x.split(delimiter);
1597
- },
1598
- StringTrim: (_loc_id, _source_map) => (x) => x.trim(),
1599
- StringTrimStart: (_loc_id, _source_map) => (x) => x.trimStart(),
1600
- StringTrimEnd: (_loc_id, _source_map) => (x) => x.trimEnd(),
1601
- StringStartsWith: (_loc_id, _source_map) => (x, prefix) => x.startsWith(prefix),
1602
- StringEndsWith: (_loc_id, _source_map) => (x, suffix) => x.endsWith(suffix),
1603
- StringContains: (_loc_id, _source_map) => (x, substring) => x.includes(substring),
1604
- StringIndexOf: (_loc_id, _source_map) => (x, substring) => {
1605
- const codeUnitIndex = x.indexOf(substring);
1606
- if (codeUnitIndex === -1)
1607
- return -1n;
1608
- // Special case for empty substring - it's always found at position 0
1609
- if (substring === "")
1610
- return BigInt(codeUnitIndex);
1611
- // Convert code unit index to codepoint index
1612
- let codepointIndex = 0;
1613
- let codeUnitPos = 0;
1614
- for (const char of x) {
1615
- if (codeUnitPos === codeUnitIndex) {
1616
- return BigInt(codepointIndex);
1617
- }
1618
- codeUnitPos += char.length;
1619
- codepointIndex++;
1620
- }
1621
- return -1n;
1622
- },
1623
- StringReplace: (_loc_id, _source_map) => (x, searchValue, replaceValue) => {
1624
- // Replace all occurrences (like JavaScript's string.replaceAll with string)
1625
- return x.replaceAll(searchValue, replaceValue);
1626
- },
1627
- RegexContains: (_loc_id, _source_map) => (text, pattern, flags) => {
1628
- const regex = new RegExp(pattern, flags);
1629
- return regex.test(text);
1630
- },
1631
- RegexIndexOf: (_loc_id, _source_map) => (text, pattern, flags) => {
1632
- const regex = new RegExp(pattern, flags);
1633
- const codeUnitIndex = text.search(regex);
1634
- if (codeUnitIndex === -1)
1635
- return -1n;
1636
- // Convert code unit index to codepoint index
1637
- let codepointIndex = 0;
1638
- let codeUnitPos = 0;
1639
- for (const char of text) {
1640
- if (codeUnitPos === codeUnitIndex) {
1641
- return BigInt(codepointIndex);
1642
- }
1643
- codeUnitPos += char.length;
1644
- codepointIndex++;
1645
- }
1646
- return -1n;
1647
- },
1648
- RegexReplace: (loc_id, source_map) => (text, pattern, flags, replacement) => {
1649
- // Ensure global flag is set for replaceAll semantics
1650
- const globalFlags = flags.includes('g') ? flags : flags + 'g';
1651
- const regex = new RegExp(pattern, globalFlags);
1652
- // Validate replacement string: only allow $$, $1-$9, and $<
1653
- // This is stricter than JavaScript's native behavior but provides clear, consistent semantics
1654
- // and avoids backend-specific features like $&, $`, $'
1655
- let i = 0;
1656
- while (i < replacement.length) {
1657
- const char = replacement[i];
1658
- if (char === '$') {
1659
- i += char.length;
1660
- let char2 = replacement[i];
1661
- if (char2 === undefined) {
1662
- throw new EastError(`invalid regex replacement string: unescaped $ at end of string`, { location: (source_map?.resolve(loc_id) ?? []) });
1663
- }
1664
- else if (char2 === '$') {
1665
- i += 1;
1666
- }
1667
- else if (char2 >= '1' && char2 <= '9') {
1668
- i += 1;
1669
- char2 = replacement[i];
1670
- while (char2 !== undefined && char2 >= '0' && char2 <= '9') {
1671
- i += 1;
1672
- char2 = replacement[i];
1673
- }
1674
- }
1675
- else if (char2 === '<') {
1676
- // Scan until closing >
1677
- i += 1;
1678
- const init_i = i;
1679
- char2 = replacement[i];
1680
- while (true) {
1681
- if (char2 === undefined) {
1682
- throw new EastError(`invalid regex replacement string: unterminated group name in $<...>`, { location: (source_map?.resolve(loc_id) ?? []) });
1683
- }
1684
- if (char2 === '>') {
1685
- break;
1686
- }
1687
- if (!((char2 >= '0' && char2 <= '9') || (char2 >= 'a' && char2 <= 'z') || (char2 >= 'A' && char2 <= 'Z') || char2 === '_')) {
1688
- throw new EastError(`invalid regex replacement string: invalid character ${JSON.stringify(char2)} in group name in $<...>`, { location: (source_map?.resolve(loc_id) ?? []) });
1689
- }
1690
- i += 1;
1691
- char2 = replacement[i];
1692
- }
1693
- if (i === init_i) {
1694
- throw new EastError(`invalid regex replacement string: empty group name in $<>`, { location: (source_map?.resolve(loc_id) ?? []) });
1695
- }
1696
- i += 1; // for closing >
1697
- }
1698
- else {
1699
- throw new EastError(`invalid regex replacement string: unescaped $ at $${char2}`, { location: (source_map?.resolve(loc_id) ?? []) });
1700
- }
1701
- }
1702
- else {
1703
- i += char.length;
1704
- }
1705
- }
1706
- return text.replaceAll(regex, replacement);
1707
- },
1708
- StringEncodeUtf8: (_loc_id, _source_map) => {
1709
- // do not add BOM for UTF-8
1710
- const encoder = new TextEncoder();
1711
- return (x) => {
1712
- return encoder.encode(x);
1713
- };
1714
- },
1715
- StringEncodeUtf16: (_loc_id, _source_map) => {
1716
- // always use little-endian with BOM (most common in practice)
1717
- return (x) => {
1718
- const buffer = new BufferWriter();
1719
- buffer.writeUint8(0xFF);
1720
- buffer.writeUint8(0xFE);
1721
- for (let i = 0; i < x.length; i++) {
1722
- const codeUnit = x.charCodeAt(i);
1723
- buffer.writeUint16LE(codeUnit);
1724
- }
1725
- return buffer.toUint8Array();
1726
- };
1727
- },
1728
- StringParseJSON: (loc_id, source_map, _platformDef, type) => {
1729
- const fromJSON = fromJSONFor(type);
1730
- return (x) => {
1731
- let parsed;
1732
- try {
1733
- parsed = JSON.parse(x);
1734
- }
1735
- catch (e) {
1736
- throw new EastError(`Failed to parse JSON: ${e.message}`, { location: (source_map?.resolve(loc_id) ?? []) });
1737
- }
1738
- try {
1739
- return fromJSON(parsed);
1740
- }
1741
- catch (e) {
1742
- throw new EastError(`Failed to convert JSON to ${printTypeValue(type)}: ${e.message}`, { location: (source_map?.resolve(loc_id) ?? []) });
1743
- }
1744
- };
1745
- },
1746
- StringPrintJSON: (loc_id, source_map, _platformDef, type) => {
1747
- const toJSON = toJSONFor(type);
1748
- return (x) => JSON.stringify(toJSON(x));
1749
- },
1750
- DateTimeGetYear: (_loc_id, _source_map) => (date) => BigInt(date.getUTCFullYear()),
1751
- DateTimeGetMonth: (_loc_id, _source_map) => (date) => BigInt(date.getUTCMonth() + 1), // JavaScript months are 0-based, East uses 1-based
1752
- DateTimeGetDayOfMonth: (_loc_id, _source_map) => (date) => BigInt(date.getUTCDate()),
1753
- DateTimeGetHour: (_loc_id, _source_map) => (date) => BigInt(date.getUTCHours()),
1754
- DateTimeGetMinute: (_loc_id, _source_map) => (date) => BigInt(date.getUTCMinutes()),
1755
- DateTimeGetSecond: (_loc_id, _source_map) => (date) => BigInt(date.getUTCSeconds()),
1756
- DateTimeGetDayOfWeek: (_loc_id, _source_map) => (date) => {
1757
- const jsDay = date.getUTCDay(); // JavaScript: 0=Sunday, 1=Monday, ..., 6=Saturday
1758
- return BigInt(jsDay === 0 ? 7 : jsDay); // ISO 8601: 1=Monday, 2=Tuesday, ..., 7=Sunday
1759
- },
1760
- DateTimeGetMillisecond: (_loc_id, _source_map) => (date) => BigInt(date.getUTCMilliseconds()),
1761
- DateTimeAddMilliseconds: (_loc_id, _source_map) => (date, milliseconds) => new Date(date.getTime() + Number(milliseconds)),
1762
- DateTimeDurationMilliseconds: (_loc_id, _source_map) => (date1, date2) => BigInt(date1.getTime() - date2.getTime()),
1763
- DateTimeToEpochMilliseconds: (_loc_id, _source_map) => (date) => BigInt(date.getTime()),
1764
- DateTimeFromEpochMilliseconds: (_loc_id, _source_map) => (milliseconds) => new Date(Number(milliseconds)),
1765
- DateTimeFromComponents: (_loc_id, _source_map) => (year, month, day, hour, minute, second, millisecond) => {
1766
- const y = Number(year);
1767
- const date = new Date(Date.UTC(y, Number(month) - 1, Number(day), Number(hour), Number(minute), Number(second), Number(millisecond)));
1768
- // `Date.UTC` applies JavaScript's legacy two-digit-year rule, remapping a
1769
- // year of 0-99 to 1900-1999. East years mean what they say (east-c sets
1770
- // `tm_year = year - 1900` and does no remapping), so undo it — on the
1771
- // ROLLED year, since an out-of-range month or day may have carried into
1772
- // it and the normalisation is part of the contract.
1773
- if (y >= 0 && y <= 99)
1774
- date.setUTCFullYear(date.getUTCFullYear() - 1900);
1775
- return date;
1776
- },
1777
- DateTimePrintFormat: (_loc_id, _source_map) => (date, tokens) => {
1778
- return formatDateTime(date, tokens);
1779
- },
1780
- DateTimeParseFormat: (loc_id, source_map) => (str, tokens) => {
1781
- const result = parseDateTimeFormatted(str, tokens);
1782
- if (result.success) {
1783
- return result.value;
1784
- }
1785
- else {
1786
- throw new EastError(`Failed to parse datetime at position ${result.position}: ${result.error}`, { location: (source_map?.resolve(loc_id) ?? []) });
1787
- }
1788
- },
1789
- BlobSize: (_loc_id, _source_map) => (data) => BigInt(data.length),
1790
- BlobGetUint8: (loc_id, source_map) => (data, index) => {
1791
- const i = Number(index);
1792
- if (i < 0 || i >= data.length) {
1793
- throw new EastError(`Blob index ${index} out of bounds`, { location: (source_map?.resolve(loc_id) ?? []) });
1794
- }
1795
- else {
1796
- return BigInt(data[i]);
1797
- }
1798
- },
1799
- BlobDecodeUtf8: (loc_id, source_map) => {
1800
- const decoder = new TextDecoder('utf-8', { fatal: true });
1801
- return (data) => {
1802
- try {
1803
- return decoder.decode(data);
1804
- }
1805
- catch {
1806
- throw new EastError("Blob is not valid UTF-8", { location: (source_map?.resolve(loc_id) ?? []) });
1807
- }
1808
- };
1809
- },
1810
- BlobDecodeUtf16: (loc_id, source_map) => {
1811
- const decoder_be = new TextDecoder('utf-16be', { fatal: true });
1812
- const decoder_le = new TextDecoder('utf-16le', { fatal: true });
1813
- return (data) => {
1814
- try {
1815
- if (data.length >= 2) {
1816
- // Check for BOM
1817
- if (data[0] === 0xFE && data[1] === 0xFF) {
1818
- // Big-endian BOM
1819
- return decoder_be.decode(data.subarray(2));
1820
- }
1821
- else if (data[0] === 0xFF && data[1] === 0xFE) {
1822
- // Little-endian BOM
1823
- return decoder_le.decode(data.subarray(2));
1824
- }
1825
- }
1826
- // No BOM, default to little-endian (not unicode spec compliant, but more common in practice)
1827
- return decoder_le.decode(data);
1828
- }
1829
- catch {
1830
- throw new EastError("Blob is not valid UTF-16", { location: (source_map?.resolve(loc_id) ?? []) });
1831
- }
1832
- };
1833
- },
1834
- BlobEncodeBeast: (loc_id, source_map, _platformDef, type) => {
1835
- const encodeBeast = encodeBeastFor(type);
1836
- return (value) => {
1837
- return encodeBeast(value);
1838
- };
1839
- },
1840
- BlobDecodeBeast: (loc_id, source_map, _platformDef, type) => {
1841
- const decodeBeast = decodeBeastFor(type);
1842
- return (data) => {
1843
- try {
1844
- return decodeBeast(data);
1845
- }
1846
- catch (e) {
1847
- throw new EastError(`Failed to decode Beast data: ${e.message}`, { location: (source_map?.resolve(loc_id) ?? []) });
1848
- }
1849
- };
1850
- },
1851
- BlobEncodeBeast2: (loc_id, source_map, _platformDef, type) => {
1852
- const encodeBeast2 = encodeBeast2For(type);
1853
- return (value) => {
1854
- return encodeBeast2(value);
1855
- };
1856
- },
1857
- BlobDecodeBeast2: (loc_id, source_map, platformDef, type) => {
1858
- const decodeBeast2 = decodeBeast2For(type, { platform: platformDef });
1859
- return (data) => {
1860
- try {
1861
- return decodeBeast2(data);
1862
- }
1863
- catch (e) {
1864
- throw new EastError(`Failed to decode Beast2 data: ${e.message}`, { location: (source_map?.resolve(loc_id) ?? []) });
1865
- }
1866
- };
1867
- },
1868
- BlobOpenBeast2: (loc_id, source_map, platformDef, type) => {
1869
- // The frozen lazy open a runner gives a task input, at the expression
1870
- // level. The header names the wire type (both container versions), and
1871
- // paging or decoding by any other type would read garbage, so a mismatch
1872
- // is an error rather than a decode by the declared type. Whatever cannot
1873
- // page — a v4 container, an index-less blob, cross-segment aliasing, a
1874
- // gated element shape — decodes whole, frozen, with the same semantics.
1875
- // The whole decoder is built on first use: a paged blob never needs it.
1876
- let whole = null;
1877
- const open = openBeast2LazyFor(type, { platform: platformDef, frozen: true });
1878
- const lazySafe = isBeast2LazySafe(type, { frozen: true });
1879
- return (data) => {
1880
- try {
1881
- // One geometry read answers everything the open needs: the wire
1882
- // type, whether an index exists (it throws otherwise) and whether
1883
- // the segments are self-contained.
1884
- let extents = null;
1885
- try {
1886
- extents = readBeast2Extents(data);
1887
- }
1888
- catch {
1889
- extents = null;
1890
- }
1891
- const wire = extents !== null ? extents.typeValue : readBeast2Type(data);
1892
- if (!isTypeValueEqual(wire, type)) {
1893
- throw new Error(`beast2: cannot open a blob of type ${printTypeValue(wire)} as ${printTypeValue(type)}`);
1894
- }
1895
- if (lazySafe && extents !== null && extents.selfContained)
1896
- return open(data);
1897
- whole ??= decodeBeast2For(type, { platform: platformDef, frozen: true });
1898
- return whole(data);
1899
- }
1900
- catch (e) {
1901
- throw new EastError(`Failed to open Beast2 data: ${e.message}`, { location: (source_map?.resolve(loc_id) ?? []) });
1902
- }
1903
- };
1904
- },
1905
- BlobDecodeCsv: (loc_id, source_map, _platformDef, structType, _configType) => {
1906
- return (data, config) => {
1907
- try {
1908
- const decoder = decodeCsvFor(structType, config);
1909
- return decoder(data);
1910
- }
1911
- catch (e) {
1912
- throw new EastError(`Failed to decode CSV data: ${e.message}`, { location: (source_map?.resolve(loc_id) ?? []) });
1913
- }
1914
- };
1915
- },
1916
- ArrayEncodeCsv: (loc_id, source_map, _platformDef, structType, _configType) => {
1917
- return (data, config) => {
1918
- try {
1919
- const encoder = encodeCsvFor(structType, config);
1920
- return encoder(data);
1921
- }
1922
- catch (e) {
1923
- throw new EastError(`Failed to encode CSV data: ${e.message}`, { location: (source_map?.resolve(loc_id) ?? []) });
1924
- }
1925
- };
1926
- },
1927
- RefGet: (_loc_id, _source_map, _platformDef, _T) => (ref) => {
1928
- return ref.value;
1929
- },
1930
- RefUpdate: (loc_id, source_map, _platformDef, _T) => (ref, value) => {
1931
- if (isFrozenValue(ref)) {
1932
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
1933
- }
1934
- ref.value = value;
1935
- return null;
1936
- },
1937
- RefMerge: (loc_id, source_map, _platformDef, _T) => (ref, value, merger) => {
1938
- if (isFrozenValue(ref)) {
1939
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
1940
- }
1941
- const new_value = call_function(loc_id, source_map, merger, ref.value, value);
1942
- ref.value = new_value;
1943
- return null;
1944
- },
1945
- ArrayGenerate: (loc_id, source_map, _platformDef, _T) => (size, f) => {
1946
- const result = [];
1947
- for (let i = 0n; i < size; i += 1n) {
1948
- const v = call_function(loc_id, source_map, f, i);
1949
- result.push(v);
1950
- }
1951
- return result;
1952
- },
1953
- ArrayRange: (_loc_id, _source_map) => (start, end, step) => {
1954
- const result = [];
1955
- if (step === 0n) {
1956
- return result; // empty array
1957
- }
1958
- else if (step > 0n) {
1959
- for (let i = start; i < end; i += step) {
1960
- result.push(i);
1961
- }
1962
- }
1963
- else { // step < 0
1964
- for (let i = start; i > end; i += step) {
1965
- result.push(i);
1966
- }
1967
- }
1968
- return result;
1969
- },
1970
- ArrayLinspace: (_loc_id, _source_map) => (start, end, size) => {
1971
- const result = [];
1972
- if (size <= 0n) {
1973
- return result; // empty array
1974
- }
1975
- else if (size === 1n) {
1976
- return [start];
1977
- }
1978
- else {
1979
- const step = (end - start) / Number(size - 1n);
1980
- for (let i = 0n; i < size; i += 1n) {
1981
- result.push(start + Number(i) * step);
1982
- }
1983
- }
1984
- return result;
1985
- },
1986
- ArraySize: (_loc_id, _source_map, _platformDef, _T) => (array) => BigInt(array.length),
1987
- ArrayHas: (_loc_id, _source_map, _platformDef, _T) => (array, key) => {
1988
- const i = Number(key);
1989
- return i >= 0 && i < array.length;
1990
- },
1991
- ArrayGet: (loc_id, source_map, _platformDef, _T) => (array, key) => {
1992
- const i = Number(key);
1993
- if (i < 0 || i >= array.length) {
1994
- throw new EastError(`Array index ${key} out of bounds`, { location: (source_map?.resolve(loc_id) ?? []) });
1995
- }
1996
- else {
1997
- return array[i];
1998
- }
1999
- },
2000
- ArrayGetOrDefault: (loc_id, source_map, _platformDef, _T) => (array, key, defaultFn) => {
2001
- const i = Number(key);
2002
- if (i < 0 || i >= array.length) {
2003
- return call_function(loc_id, source_map, defaultFn, key);
2004
- }
2005
- else {
2006
- return array[i];
2007
- }
2008
- },
2009
- ArrayTryGet: (_loc_id, _source_map, _platformDef, _T) => (array, key) => {
2010
- const i = Number(key);
2011
- if (i < 0 || i >= array.length) {
2012
- return variant("none", null);
2013
- }
2014
- else {
2015
- return variant("some", array[i]);
2016
- }
2017
- },
2018
- ArrayUpdate: (loc_id, source_map, _platformDef, _T) => (array, key, value) => {
2019
- if (isFrozenValue(array)) {
2020
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2021
- }
2022
- const i = Number(key);
2023
- if (i < 0 || i >= array.length) {
2024
- throw new EastError(`Array index ${key} out of bounds`, { location: (source_map?.resolve(loc_id) ?? []) });
2025
- }
2026
- else {
2027
- array[i] = value;
2028
- return null;
2029
- }
2030
- },
2031
- ArrayMerge: (loc_id, source_map, _platformDef, _T) => (array, key, value, merger) => {
2032
- if (isFrozenValue(array)) {
2033
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2034
- }
2035
- const i = Number(key);
2036
- if (i < 0 || i >= array.length) {
2037
- throw new EastError(`Array index ${key} out of bounds`, { location: (source_map?.resolve(loc_id) ?? []) });
2038
- }
2039
- else {
2040
- const new_value = call_function(loc_id, source_map, merger, array[i], value, key);
2041
- array[i] = new_value;
2042
- return null;
2043
- }
2044
- },
2045
- ArrayPushLast: (loc_id, source_map, _platformDef, _T) => (array, value) => {
2046
- if (isFrozenValue(array)) {
2047
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2048
- }
2049
- if ((iterationLocks.get(array) || 0) > 0) {
2050
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2051
- }
2052
- array.push(value);
2053
- return null;
2054
- },
2055
- ArrayPopLast: (loc_id, source_map, _platformDef, _T) => (array) => {
2056
- if (isFrozenValue(array)) {
2057
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2058
- }
2059
- if ((iterationLocks.get(array) || 0) > 0) {
2060
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2061
- }
2062
- if (array.length === 0) {
2063
- throw new EastError("Cannot pop from empty Array", { location: (source_map?.resolve(loc_id) ?? []) });
2064
- }
2065
- else {
2066
- return array.pop();
2067
- }
2068
- },
2069
- ArrayPushFirst: (loc_id, source_map, _platformDef, _T) => (array, value) => {
2070
- if (isFrozenValue(array)) {
2071
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2072
- }
2073
- if ((iterationLocks.get(array) || 0) > 0) {
2074
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2075
- }
2076
- array.unshift(value);
2077
- return null;
2078
- },
2079
- ArrayPopFirst: (loc_id, source_map, _platformDef, _T) => (array) => {
2080
- if (isFrozenValue(array)) {
2081
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2082
- }
2083
- if ((iterationLocks.get(array) || 0) > 0) {
2084
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2085
- }
2086
- if (array.length === 0) {
2087
- throw new EastError("Cannot pop from empty Array", { location: (source_map?.resolve(loc_id) ?? []) });
2088
- }
2089
- else {
2090
- return array.shift();
2091
- }
2092
- },
2093
- ArrayAppend: (loc_id, source_map, _platformDef, _T) => (array, other) => {
2094
- if (isFrozenValue(array)) {
2095
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2096
- }
2097
- if ((iterationLocks.get(array) || 0) > 0) {
2098
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2099
- }
2100
- array.push(...other);
2101
- return null;
2102
- },
2103
- ArrayPrepend: (loc_id, source_map, _platformDef, _T) => (array, other) => {
2104
- if (isFrozenValue(array)) {
2105
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2106
- }
2107
- if ((iterationLocks.get(array) || 0) > 0) {
2108
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2109
- }
2110
- array.unshift(...other);
2111
- return null;
2112
- },
2113
- ArrayMergeAll: (loc_id, source_map, _platformDef, _T, _T2) => (array, other, merger) => {
2114
- if (isFrozenValue(array)) {
2115
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2116
- }
2117
- lockForIteration(array);
2118
- lockForIteration(other);
2119
- try {
2120
- for (let i = 0; i < other.length; i++) {
2121
- const key = BigInt(i);
2122
- if (i < array.length) {
2123
- const new_value = call_function(loc_id, source_map, merger, array[i], other[i], key);
2124
- array[i] = new_value;
2125
- }
2126
- else {
2127
- throw new EastError(`Array index ${key} out of bounds`, { location: (source_map?.resolve(loc_id) ?? []) });
2128
- }
2129
- }
2130
- }
2131
- finally {
2132
- unlockForIteration(other);
2133
- unlockForIteration(array);
2134
- }
2135
- return null;
2136
- },
2137
- ArrayClear: (loc_id, source_map, _platformDef, _T) => (array) => {
2138
- if (isFrozenValue(array)) {
2139
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2140
- }
2141
- if ((iterationLocks.get(array) || 0) > 0) {
2142
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2143
- }
2144
- array.length = 0;
2145
- return null;
2146
- },
2147
- ArraySortInPlace: (loc_id, source_map, _platformDef, T, T2) => (array, by) => {
2148
- if (isFrozenValue(array)) {
2149
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2150
- }
2151
- if ((iterationLocks.get(array) || 0) > 0) {
2152
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2153
- }
2154
- lockForIteration(array);
2155
- try {
2156
- const cmp = compareFor(T2);
2157
- array.sort((a, b) => {
2158
- const projectedA = call_function(loc_id, source_map, by, a);
2159
- const projectedB = call_function(loc_id, source_map, by, b);
2160
- return cmp(projectedA, projectedB);
2161
- });
2162
- }
2163
- finally {
2164
- unlockForIteration(array);
2165
- }
2166
- return null;
2167
- },
2168
- ArrayReverseInPlace: (loc_id, source_map, _platformDef, _T) => (array) => {
2169
- if (isFrozenValue(array)) {
2170
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2171
- }
2172
- if ((iterationLocks.get(array) || 0) > 0) {
2173
- throw new EastError("Cannot modify Array during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2174
- }
2175
- array.reverse();
2176
- return null;
2177
- },
2178
- ArraySort: (loc_id, source_map, _platformDef, T, T2) => (array, by) => {
2179
- const cmp = compareFor(T2);
2180
- const newArray = [...array];
2181
- newArray.sort((a, b) => {
2182
- const projectedA = call_function(loc_id, source_map, by, a);
2183
- const projectedB = call_function(loc_id, source_map, by, b);
2184
- return cmp(projectedA, projectedB);
2185
- });
2186
- return newArray;
2187
- },
2188
- ArrayReverse: (_loc_id, _source_map, _platformDef, _T) => (array) => {
2189
- const newArray = [...array];
2190
- newArray.reverse();
2191
- return newArray;
2192
- },
2193
- ArrayIsSorted: (loc_id, source_map, _platformDef, T, T2) => {
2194
- const cmp = compareFor(T2);
2195
- return (array, by) => {
2196
- if (array.length < 2)
2197
- return true;
2198
- lockForIteration(array);
2199
- try {
2200
- let projectedPrev = call_function(loc_id, source_map, by, array[0]);
2201
- for (let i = 1; i < array.length; i++) {
2202
- const projectedCurr = call_function(loc_id, source_map, by, array[i]);
2203
- if (cmp(projectedPrev, projectedCurr) > 0) {
2204
- return false;
2205
- }
2206
- projectedPrev = projectedCurr;
2207
- }
2208
- }
2209
- finally {
2210
- unlockForIteration(array);
2211
- }
2212
- return true;
2213
- };
2214
- },
2215
- ArrayFindSortedFirst: (loc_id, source_map, _platformDef, T, T2) => {
2216
- const cmp = compareFor(T2);
2217
- return (array, key, by) => {
2218
- let low = 0;
2219
- let high = array.length;
2220
- lockForIteration(array);
2221
- try {
2222
- while (low < high) {
2223
- const mid = Math.floor((low + high) / 2);
2224
- const projectedMid = call_function(loc_id, source_map, by, array[mid]);
2225
- if (cmp(projectedMid, key) < 0) {
2226
- low = mid + 1;
2227
- }
2228
- else {
2229
- high = mid;
2230
- }
2231
- }
2232
- }
2233
- finally {
2234
- unlockForIteration(array);
2235
- }
2236
- return BigInt(low);
2237
- };
2238
- },
2239
- ArrayFindSortedLast: (loc_id, source_map, _platformDef, T, T2) => {
2240
- const cmp = compareFor(T2);
2241
- return (array, key, by) => {
2242
- let low = 0;
2243
- let high = array.length;
2244
- lockForIteration(array);
2245
- try {
2246
- while (low < high) {
2247
- const mid = Math.floor((low + high) / 2);
2248
- const projectedMid = call_function(loc_id, source_map, by, array[mid]);
2249
- if (cmp(projectedMid, key) <= 0) {
2250
- low = mid + 1;
2251
- }
2252
- else {
2253
- high = mid;
2254
- }
2255
- }
2256
- }
2257
- finally {
2258
- unlockForIteration(array);
2259
- }
2260
- return BigInt(low);
2261
- };
2262
- },
2263
- ArrayFindSortedRange: (loc_id, source_map, _platformDef, T, T2) => {
2264
- const cmp = compareFor(T2);
2265
- return (array, key, by) => {
2266
- let lo = -1;
2267
- let hi = array.length;
2268
- lockForIteration(array);
2269
- try {
2270
- // Main search loop - find any equal element or determine the range doesn't exist
2271
- while (lo < hi - 1) {
2272
- const mid = Math.floor((lo + hi) / 2);
2273
- const projectedMid = call_function(loc_id, source_map, by, array[mid]);
2274
- const cmpResult = cmp(projectedMid, key);
2275
- if (cmpResult < 0) {
2276
- lo = mid;
2277
- }
2278
- else if (cmpResult > 0) {
2279
- hi = mid;
2280
- }
2281
- else {
2282
- // Found an equal element! Now find the first and last positions
2283
- // within the constrained range
2284
- // Find first position in range [max(lo, -1), mid]
2285
- let firstLo = Math.max(lo, -1);
2286
- let firstHi = mid + 1;
2287
- while (firstLo < firstHi - 1) {
2288
- const firstMid = Math.floor((firstLo + firstHi) / 2);
2289
- const projectedFirst = call_function(loc_id, source_map, by, array[firstMid]);
2290
- if (cmp(projectedFirst, key) < 0) {
2291
- firstLo = firstMid;
2292
- }
2293
- else {
2294
- firstHi = firstMid;
2295
- }
2296
- }
2297
- // Find last position in range [mid, min(hi, array.length)]
2298
- let lastLo = mid - 1;
2299
- let lastHi = Math.min(hi, array.length);
2300
- while (lastLo < lastHi - 1) {
2301
- const lastMid = Math.floor((lastLo + lastHi) / 2);
2302
- const projectedLast = call_function(loc_id, source_map, by, array[lastMid]);
2303
- if (cmp(projectedLast, key) <= 0) {
2304
- lastLo = lastMid;
2305
- }
2306
- else {
2307
- lastHi = lastMid;
2308
- }
2309
- }
2310
- return { start: BigInt(firstLo + 1), end: BigInt(lastLo + 1) };
2311
- }
2312
- }
2313
- }
2314
- finally {
2315
- unlockForIteration(array);
2316
- }
2317
- // No equal element found - return empty range
2318
- return { start: BigInt(lo + 1), end: BigInt(lo + 1) };
2319
- };
2320
- },
2321
- ArrayFindFirst: (loc_id, source_map, _platformDef, T, T2) => {
2322
- const cmp = compareFor(T2);
2323
- return (array, value, by) => {
2324
- lockForIteration(array);
2325
- try {
2326
- for (let i = 0; i < array.length; i++) {
2327
- const projected = call_function(loc_id, source_map, by, array[i]);
2328
- if (cmp(projected, value) === 0) {
2329
- return variant("some", BigInt(i));
2330
- }
2331
- }
2332
- return variant("none", null);
2333
- }
2334
- finally {
2335
- unlockForIteration(array);
2336
- }
2337
- };
2338
- },
2339
- ArrayConcat: (_loc_id, _source_map, _platformDef, _T) => (a1, a2) => {
2340
- return [...a1, ...a2];
2341
- },
2342
- ArraySlice: (_loc_id, _source_map, _platformDef, _T) => (array, start, end) => {
2343
- const startNum = Number(start);
2344
- const endNum = Number(end);
2345
- return array.slice(startNum, endNum);
2346
- },
2347
- ArrayGetKeys: (loc_id, source_map, _platformDef, _T) => (array, keys, onMissing) => {
2348
- return keys.map(k => {
2349
- const i = Number(k);
2350
- if (i < 0 || i >= array.length) {
2351
- return call_function(loc_id, source_map, onMissing, k);
2352
- }
2353
- else {
2354
- return array[i];
2355
- }
2356
- });
2357
- },
2358
- ArrayForEach: (loc_id, source_map, _platformDef, _T, _T2) => (array, f) => {
2359
- lockForIteration(array);
2360
- try {
2361
- array.forEach((x, i) => {
2362
- return call_function(loc_id, source_map, f, x, BigInt(i));
2363
- });
2364
- return null;
2365
- }
2366
- finally {
2367
- unlockForIteration(array);
2368
- }
2369
- },
2370
- ArrayCopy: (_loc_id, _source_map, _platformDef, _T) => (array) => {
2371
- return [...array];
2372
- },
2373
- ArrayMap: (loc_id, source_map, _platformDef, _T, _T2) => (array, f) => {
2374
- lockForIteration(array);
2375
- try {
2376
- return array.map((x, i) => {
2377
- return call_function(loc_id, source_map, f, x, BigInt(i));
2378
- });
2379
- }
2380
- finally {
2381
- unlockForIteration(array);
2382
- }
2383
- },
2384
- ArrayFilter: (loc_id, source_map, _platformDef, _T, _T2) => (array, f) => {
2385
- lockForIteration(array);
2386
- try {
2387
- return array.filter((x, i) => {
2388
- return call_function(loc_id, source_map, f, x, BigInt(i));
2389
- });
2390
- }
2391
- finally {
2392
- unlockForIteration(array);
2393
- }
2394
- },
2395
- ArrayFilterMap: (loc_id, source_map, _platformDef, _T, _T2) => (array, f) => {
2396
- lockForIteration(array);
2397
- try {
2398
- const result = [];
2399
- for (let i = 0; i < array.length; i++) {
2400
- const v = call_function(loc_id, source_map, f, array[i], BigInt(i));
2401
- if (v.type === "some") {
2402
- result.push(v.value);
2403
- }
2404
- }
2405
- return result;
2406
- }
2407
- finally {
2408
- unlockForIteration(array);
2409
- }
2410
- },
2411
- ArrayFirstMap: (loc_id, source_map, _platformDef, _T, _T2) => (array, f) => {
2412
- lockForIteration(array);
2413
- try {
2414
- for (let i = 0; i < array.length; i++) {
2415
- const v = call_function(loc_id, source_map, f, array[i], BigInt(i));
2416
- if (v.type === "some") {
2417
- return v;
2418
- }
2419
- }
2420
- return variant("none", null);
2421
- }
2422
- finally {
2423
- unlockForIteration(array);
2424
- }
2425
- },
2426
- ArrayFold: (loc_id, source_map, _platformDef, _T, _T2) => (array, init, f) => {
2427
- lockForIteration(array);
2428
- try {
2429
- return array.reduce((acc, x, i) => {
2430
- return call_function(loc_id, source_map, f, acc, x, BigInt(i));
2431
- }, init);
2432
- }
2433
- finally {
2434
- unlockForIteration(array);
2435
- }
2436
- },
2437
- ArrayScan: (loc_id, source_map, _platformDef, _T, _T2) => (array, init, f) => {
2438
- lockForIteration(array);
2439
- try {
2440
- const result = [];
2441
- let acc = init;
2442
- for (let i = 0; i < array.length; i++) {
2443
- acc = call_function(loc_id, source_map, f, acc, array[i], BigInt(i));
2444
- result.push(acc);
2445
- }
2446
- return result;
2447
- }
2448
- finally {
2449
- unlockForIteration(array);
2450
- }
2451
- },
2452
- ArrayMapReduce: (loc_id, source_map, _platformDef, _T, _T2) => (array, mapFn, reduceFn) => {
2453
- if (array.length === 0) {
2454
- throw new EastError("Cannot reduce empty array with no initial value", { location: (source_map?.resolve(loc_id) ?? []) });
2455
- }
2456
- lockForIteration(array);
2457
- try {
2458
- let acc = call_function(loc_id, source_map, mapFn, array[0], 0n);
2459
- for (let i = 1; i < array.length; i++) {
2460
- const mapped = call_function(loc_id, source_map, mapFn, array[i], BigInt(i));
2461
- acc = call_function(loc_id, source_map, reduceFn, acc, mapped);
2462
- }
2463
- return acc;
2464
- }
2465
- finally {
2466
- unlockForIteration(array);
2467
- }
2468
- },
2469
- ArrayStringJoin: (_loc_id, _source_map, _platformDef) => (x, y) => x.join(y),
2470
- ArrayToSet: (loc_id, source_map, _platformDef, _T, T2) => {
2471
- const compare = compareFor(T2);
2472
- return (array, f) => {
2473
- lockForIteration(array);
2474
- try {
2475
- const result = new SortedSet([], compare);
2476
- for (let i = 0; i < array.length; i++) {
2477
- const v = call_function(loc_id, source_map, f, array[i], BigInt(i));
2478
- result.add(v);
2479
- }
2480
- return result;
2481
- }
2482
- finally {
2483
- unlockForIteration(array);
2484
- }
2485
- };
2486
- },
2487
- ArrayToDict: (loc_id, source_map, _platformDef, _T, K2, _T2) => {
2488
- const compare = compareFor(K2);
2489
- return (array, keyFn, valueFn, onConflict) => {
2490
- const result = new SortedMap([], compare);
2491
- lockForIteration(array);
2492
- try {
2493
- for (let i = 0; i < array.length; i++) {
2494
- const v = array[i];
2495
- const k = call_function(loc_id, source_map, keyFn, v, BigInt(i));
2496
- let val = call_function(loc_id, source_map, valueFn, v, BigInt(i));
2497
- const existing = result.get(k);
2498
- if (existing === undefined) {
2499
- result.set(k, val);
2500
- }
2501
- else {
2502
- val = call_function(loc_id, source_map, onConflict, existing, val, k);
2503
- result.set(k, val);
2504
- }
2505
- }
2506
- return result;
2507
- }
2508
- finally {
2509
- unlockForIteration(array);
2510
- }
2511
- };
2512
- },
2513
- ArrayFlattenToArray: (loc_id, source_map, _platformDef, _T) => (array, fn) => {
2514
- return array.flatMap(v => {
2515
- return call_function(loc_id, source_map, fn, v);
2516
- });
2517
- },
2518
- ArrayFlattenToSet: (loc_id, source_map, _platformDef, _T, K2) => {
2519
- const compare = compareFor(K2);
2520
- return (array, fn) => {
2521
- const result = new SortedSet([], compare);
2522
- lockForIteration(array);
2523
- try {
2524
- for (const v of array) {
2525
- const subset = call_function(loc_id, source_map, fn, v);
2526
- for (const k of subset) {
2527
- result.add(k);
2528
- }
2529
- }
2530
- return result;
2531
- }
2532
- finally {
2533
- unlockForIteration(array);
2534
- }
2535
- };
2536
- },
2537
- ArrayFlattenToDict: (loc_id, source_map, _platformDef, _T, K2, _T2) => {
2538
- const compare = compareFor(K2);
2539
- return (array, fn, onConflict) => {
2540
- const result = new SortedMap([], compare);
2541
- lockForIteration(array);
2542
- try {
2543
- for (const v of array) {
2544
- const subdict = call_function(loc_id, source_map, fn, v);
2545
- for (const [k, val] of subdict.entries()) {
2546
- const existing = result.get(k);
2547
- if (existing === undefined) {
2548
- result.set(k, val);
2549
- }
2550
- else {
2551
- const new_val = call_function(loc_id, source_map, onConflict, existing, val, k);
2552
- result.set(k, new_val);
2553
- }
2554
- }
2555
- }
2556
- return result;
2557
- }
2558
- finally {
2559
- unlockForIteration(array);
2560
- }
2561
- };
2562
- },
2563
- ArrayGroupFold: (loc_id, source_map, _platformDef, _T, K2, _V2) => {
2564
- const compare = compareFor(K2);
2565
- return (array, keyFn, init, folder) => {
2566
- const result = new SortedMap([], compare);
2567
- lockForIteration(array);
2568
- try {
2569
- for (let i = 0; i < array.length; i++) {
2570
- const v = array[i];
2571
- const k = call_function(loc_id, source_map, keyFn, v, BigInt(i));
2572
- let existing = result.get(k);
2573
- if (existing === undefined) {
2574
- existing = call_function(loc_id, source_map, init, k);
2575
- }
2576
- const new_val = call_function(loc_id, source_map, folder, existing, v, BigInt(i));
2577
- result.set(k, new_val);
2578
- }
2579
- return result;
2580
- }
2581
- finally {
2582
- unlockForIteration(array);
2583
- }
2584
- };
2585
- },
2586
- SetGenerate: (loc_id, source_map, _platformDef, K) => {
2587
- const keyComparer = compareFor(K);
2588
- return (size, keyFn, onConflict) => {
2589
- const result = new SortedSet([], keyComparer);
2590
- for (let i = 0n; i < size; i += 1n) {
2591
- const k = call_function(loc_id, source_map, keyFn, i);
2592
- if (result.has(k)) {
2593
- call_function(loc_id, source_map, onConflict, k);
2594
- }
2595
- else {
2596
- result.add(k);
2597
- }
2598
- }
2599
- return result;
2600
- };
2601
- },
2602
- SetSize: (_loc_id, _source_map, _platformDef, _K) => (s) => BigInt(s.size),
2603
- SetHas: (_loc_id, _source_map, _platformDef, _K) => (s, key) => s.has(key),
2604
- SetInsert: (loc_id, source_map, _platformDef, K) => {
2605
- const print = printFor(K);
2606
- return (s, key) => {
2607
- if (isFrozenValue(s)) {
2608
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2609
- }
2610
- if ((iterationLocks.get(s) || 0) > 0) {
2611
- throw new EastError("Cannot modify Set during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2612
- }
2613
- const size_before = s.size;
2614
- s.add(key);
2615
- if (s.size === size_before) {
2616
- throw new EastError(`Set already contains key ${print(key)}`, { location: (source_map?.resolve(loc_id) ?? []) });
2617
- }
2618
- return null;
2619
- };
2620
- },
2621
- SetTryInsert: (loc_id, source_map, _platformDef, _K) => (s, key) => {
2622
- if (isFrozenValue(s)) {
2623
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2624
- }
2625
- if ((iterationLocks.get(s) || 0) > 0) {
2626
- throw new EastError("Cannot modify Set during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2627
- }
2628
- const size_before = s.size;
2629
- s.add(key);
2630
- return s.size > size_before;
2631
- },
2632
- SetDelete: (loc_id, source_map, _platformDef, K) => {
2633
- const print = printFor(K);
2634
- return (s, key) => {
2635
- if (isFrozenValue(s)) {
2636
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2637
- }
2638
- if ((iterationLocks.get(s) || 0) > 0) {
2639
- throw new EastError("Cannot modify Set during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2640
- }
2641
- if (!s.delete(key)) {
2642
- throw new EastError(`Set does not contain key ${print(key)}`, { location: (source_map?.resolve(loc_id) ?? []) });
2643
- }
2644
- return null;
2645
- };
2646
- },
2647
- SetTryDelete: (loc_id, source_map, _platformDef, _K) => (s, key) => {
2648
- if (isFrozenValue(s)) {
2649
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2650
- }
2651
- if ((iterationLocks.get(s) || 0) > 0) {
2652
- throw new EastError("Cannot modify Set during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2653
- }
2654
- return s.delete(key);
2655
- },
2656
- SetClear: (loc_id, source_map, _platformDef, _K) => (s) => {
2657
- if (isFrozenValue(s)) {
2658
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2659
- }
2660
- if ((iterationLocks.get(s) || 0) > 0) {
2661
- throw new EastError("Cannot modify Set during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2662
- }
2663
- s.clear();
2664
- return null;
2665
- },
2666
- SetUnionInPlace: (loc_id, source_map, _platformDef, _K) => (s1, s2) => {
2667
- if (isFrozenValue(s1)) {
2668
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
2669
- }
2670
- if ((iterationLocks.get(s1) || 0) > 0) {
2671
- throw new EastError("Cannot modify Set during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
2672
- }
2673
- s2.forEach(v => s1.add(v));
2674
- return null;
2675
- },
2676
- SetUnion: (_loc_id, _source_map, _platformDef, _K) => (s1, s2) => s1.union(s2),
2677
- SetIntersect: (_loc_id, _source_map, _platformDef, _K) => (s1, s2) => s1.intersection(s2),
2678
- SetDiff: (_loc_id, _source_map, _platformDef, _K) => (s1, s2) => s1.difference(s2),
2679
- SetSymDiff: (_loc_id, _source_map, _platformDef, _K) => (s1, s2) => s1.symmetricDifference(s2),
2680
- SetIsSubset: (_loc_id, _source_map, _platformDef, _K) => (s1, s2) => s1.isSubsetOf(s2),
2681
- SetIsDisjoint: (_loc_id, _source_map, _platformDef, _K) => (s1, s2) => s1.isDisjointFrom(s2),
2682
- SetCopy: (loc_id, source_map, _platformDef, K) => {
2683
- const compare = compareFor(K);
2684
- return (s) => {
2685
- return new SortedSet([...s], compare);
2686
- };
2687
- },
2688
- SetForEach: (loc_id, source_map, _platformDef, _K, _T2) => (s, f) => {
2689
- lockForIteration(s);
2690
- try {
2691
- s.forEach(x => {
2692
- call_function(loc_id, source_map, f, x);
2693
- });
2694
- return null;
2695
- }
2696
- finally {
2697
- unlockForIteration(s);
2698
- }
2699
- },
2700
- SetFilter: (loc_id, source_map, _platformDef, K) => {
2701
- const compare = compareFor(K);
2702
- return (s, f) => {
2703
- const result = new SortedSet([], compare);
2704
- lockForIteration(s);
2705
- try {
2706
- s.forEach(x => {
2707
- const keep = call_function(loc_id, source_map, f, x);
2708
- if (keep) {
2709
- result.add(x);
2710
- }
2711
- });
2712
- return result;
2713
- }
2714
- finally {
2715
- unlockForIteration(s);
2716
- }
2717
- };
2718
- },
2719
- SetFilterMap: (loc_id, source_map, _platformDef, K, _V2) => {
2720
- const compare = compareFor(K);
2721
- return (s, f) => {
2722
- const result = new SortedMap([], compare);
2723
- lockForIteration(s);
2724
- try {
2725
- s.forEach(k => {
2726
- const v2 = call_function(loc_id, source_map, f, k);
2727
- if (v2.type === "some") {
2728
- result.set(k, v2.value);
2729
- }
2730
- });
2731
- return result;
2732
- }
2733
- finally {
2734
- unlockForIteration(s);
2735
- }
2736
- };
2737
- },
2738
- SetFirstMap: (loc_id, source_map, _platformDef, _K, _T2) => (s, f) => {
2739
- lockForIteration(s);
2740
- try {
2741
- for (const k of s) {
2742
- const v = call_function(loc_id, source_map, f, k);
2743
- if (v.type === "some") {
2744
- return v;
2745
- }
2746
- }
2747
- return variant("none", null);
2748
- }
2749
- finally {
2750
- unlockForIteration(s);
2751
- }
2752
- },
2753
- SetMapReduce: (loc_id, source_map, _platformDef, _K, _T2) => (s, mapFn, reduceFn) => {
2754
- if (s.size === 0) {
2755
- throw new EastError("Cannot reduce empty set with no initial value", { location: (source_map?.resolve(loc_id) ?? []) });
2756
- }
2757
- lockForIteration(s);
2758
- try {
2759
- const iterator = s[Symbol.iterator]();
2760
- const first = iterator.next().value;
2761
- let acc = call_function(loc_id, source_map, mapFn, first);
2762
- for (const k of iterator) {
2763
- const mapped = call_function(loc_id, source_map, mapFn, k);
2764
- acc = call_function(loc_id, source_map, reduceFn, acc, mapped);
2765
- }
2766
- return acc;
2767
- }
2768
- finally {
2769
- unlockForIteration(s);
2770
- }
2771
- },
2772
- SetMap: (loc_id, source_map, _platformDef, K, _T2) => {
2773
- const compare = compareFor(K);
2774
- return (s, f) => {
2775
- const result = new SortedMap([], compare);
2776
- lockForIteration(s);
2777
- try {
2778
- s.forEach(x => {
2779
- const v = call_function(loc_id, source_map, f, x);
2780
- result.set(x, v);
2781
- });
2782
- return result;
2783
- }
2784
- finally {
2785
- unlockForIteration(s);
2786
- }
2787
- };
2788
- },
2789
- SetReduce: (loc_id, source_map, _platformDef, _K, _T2) => (s, f, init) => {
2790
- let acc = init;
2791
- lockForIteration(s);
2792
- try {
2793
- for (const x of s) {
2794
- acc = call_function(loc_id, source_map, f, acc, x);
2795
- }
2796
- return acc;
2797
- }
2798
- finally {
2799
- unlockForIteration(s);
2800
- }
2801
- },
2802
- SetScan: (loc_id, source_map, _platformDef, _K, _T2) => (s, f, init) => {
2803
- const result = [];
2804
- let acc = init;
2805
- lockForIteration(s);
2806
- try {
2807
- for (const x of s) {
2808
- acc = call_function(loc_id, source_map, f, acc, x);
2809
- result.push(acc);
2810
- }
2811
- return result;
2812
- }
2813
- finally {
2814
- unlockForIteration(s);
2815
- }
2816
- },
2817
- SetToArray: (loc_id, source_map, _platformDef, _K, _T2) => (s, valueFn) => {
2818
- const ret = [];
2819
- lockForIteration(s);
2820
- try {
2821
- for (const k of s) {
2822
- const v = call_function(loc_id, source_map, valueFn, k);
2823
- ret.push(v);
2824
- }
2825
- return ret;
2826
- }
2827
- finally {
2828
- unlockForIteration(s);
2829
- }
2830
- },
2831
- SetToSet: (loc_id, source_map, _platformDef, K, K2) => {
2832
- const compare = compareFor(K2);
2833
- return (s, f) => {
2834
- const result = new SortedSet([], compare);
2835
- lockForIteration(s);
2836
- try {
2837
- for (const x of s) {
2838
- const v = call_function(loc_id, source_map, f, x);
2839
- result.add(v);
2840
- }
2841
- ;
2842
- return result;
2843
- }
2844
- finally {
2845
- unlockForIteration(s);
2846
- }
2847
- };
2848
- },
2849
- SetToDict: (loc_id, source_map, _platformDef, K, K2, _V2) => {
2850
- const compare = compareFor(K2);
2851
- return (s, keyFn, valueFn, onConflict) => {
2852
- const result = new SortedMap([], compare);
2853
- lockForIteration(s);
2854
- try {
2855
- for (const k of s) {
2856
- const k2 = call_function(loc_id, source_map, keyFn, k);
2857
- let v2 = call_function(loc_id, source_map, valueFn, k);
2858
- const existing = result.get(k2);
2859
- if (existing !== undefined) {
2860
- v2 = call_function(loc_id, source_map, onConflict, existing, v2, k2);
2861
- result.set(k2, v2);
2862
- }
2863
- else {
2864
- result.set(k2, v2);
2865
- }
2866
- }
2867
- return result;
2868
- }
2869
- finally {
2870
- unlockForIteration(s);
2871
- }
2872
- };
2873
- },
2874
- SetFlattenToArray: (loc_id, source_map, _platformDef, _K, _T2) => (s, fn) => {
2875
- const ret = [];
2876
- lockForIteration(s);
2877
- try {
2878
- for (const k of s) {
2879
- const subarray = call_function(loc_id, source_map, fn, k);
2880
- ret.push(...subarray);
2881
- }
2882
- return ret;
2883
- }
2884
- finally {
2885
- unlockForIteration(s);
2886
- }
2887
- },
2888
- SetFlattenToSet: (loc_id, source_map, _platformDef, _K, K2) => {
2889
- const compare = compareFor(K2);
2890
- return (s, fn) => {
2891
- const result = new SortedSet([], compare);
2892
- lockForIteration(s);
2893
- try {
2894
- for (const k of s) {
2895
- const subset = call_function(loc_id, source_map, fn, k);
2896
- for (const k2 of subset) {
2897
- result.add(k2);
2898
- }
2899
- }
2900
- return result;
2901
- }
2902
- finally {
2903
- unlockForIteration(s);
2904
- }
2905
- };
2906
- },
2907
- SetFlattenToDict: (loc_id, source_map, _platformDef, _K, K2, _V2) => {
2908
- const compare = compareFor(K2);
2909
- return (s, fn, onConflict) => {
2910
- const result = new SortedMap([], compare);
2911
- lockForIteration(s);
2912
- try {
2913
- for (const k of s) {
2914
- const subdict = call_function(loc_id, source_map, fn, k);
2915
- for (const [k2, v2] of subdict.entries()) {
2916
- const existing = result.get(k2);
2917
- if (existing === undefined) {
2918
- result.set(k2, v2);
2919
- }
2920
- else {
2921
- const new_v2 = call_function(loc_id, source_map, onConflict, existing, v2, k2);
2922
- result.set(k2, new_v2);
2923
- }
2924
- }
2925
- }
2926
- return result;
2927
- }
2928
- finally {
2929
- unlockForIteration(s);
2930
- }
2931
- };
2932
- },
2933
- SetGroupFold: (loc_id, source_map, _platformDef, _K, K2, _T2) => {
2934
- const compare = compareFor(K2);
2935
- return (s, keyFn, init, folder) => {
2936
- const result = new SortedMap([], compare);
2937
- lockForIteration(s);
2938
- try {
2939
- for (const k of s) {
2940
- const k2 = call_function(loc_id, source_map, keyFn, k);
2941
- let existing = result.get(k2);
2942
- if (existing === undefined) {
2943
- existing = call_function(loc_id, source_map, init, k2);
2944
- }
2945
- const new_val = call_function(loc_id, source_map, folder, existing, k);
2946
- result.set(k2, new_val);
2947
- }
2948
- return result;
2949
- }
2950
- finally {
2951
- unlockForIteration(s);
2952
- }
2953
- };
2954
- },
2955
- DictGenerate: (loc_id, source_map, _platformDef, K, _V) => {
2956
- const keyComparer = compareFor(K);
2957
- return (size, keyFn, valueFn, onConflict) => {
2958
- const result = new SortedMap([], keyComparer);
2959
- for (let i = 0n; i < size; i += 1n) {
2960
- const k = call_function(loc_id, source_map, keyFn, i);
2961
- const v = call_function(loc_id, source_map, valueFn, i);
2962
- const existing = result.get(k);
2963
- if (existing !== undefined) {
2964
- const v2 = call_function(loc_id, source_map, onConflict, existing, v, k);
2965
- result.set(k, v2);
2966
- }
2967
- else {
2968
- result.set(k, v);
2969
- }
2970
- }
2971
- return result;
2972
- };
2973
- },
2974
- DictSize: (_loc_id, _source_map, _platformDef, _K, _V) => (d) => BigInt(d.size),
2975
- DictHas: (_loc_id, _source_map, _platformDef, _K, _V) => (d, key) => d.has(key),
2976
- DictGet: (loc_id, source_map, _platformDef, K, _V) => {
2977
- const print = printFor(K);
2978
- return (d, key) => {
2979
- const result = d.get(key);
2980
- if (result === undefined) {
2981
- throw new EastError(`Dict does not contain key ${print(key)}`, { location: (source_map?.resolve(loc_id) ?? []) });
2982
- }
2983
- else {
2984
- return result;
2985
- }
2986
- };
2987
- },
2988
- DictGetOrDefault: (loc_id, source_map, _platformDef, _K, _V) => (d, key, onMissingFn) => {
2989
- const result = d.get(key);
2990
- if (result === undefined) {
2991
- return call_function(loc_id, source_map, onMissingFn, key);
2992
- }
2993
- else {
2994
- return result;
2995
- }
2996
- },
2997
- DictTryGet: (_loc_id, _source_map, _platformDef, _K, _V) => (d, key) => {
2998
- const result = d.get(key);
2999
- if (result === undefined) {
3000
- return variant("none", null);
3001
- }
3002
- else {
3003
- return variant("some", result);
3004
- }
3005
- },
3006
- DictInsert: (loc_id, source_map, _platformDef, K, _V) => {
3007
- const print = printFor(K);
3008
- return (d, key, value) => {
3009
- if (isFrozenValue(d)) {
3010
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3011
- }
3012
- if ((iterationLocks.get(d) || 0) > 0) {
3013
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3014
- }
3015
- const existing = d.get(key);
3016
- if (existing !== undefined) {
3017
- throw new EastError(`Dict already contains key ${print(key)}`, { location: (source_map?.resolve(loc_id) ?? []) });
3018
- }
3019
- else {
3020
- d.set(key, value);
3021
- }
3022
- return null;
3023
- };
3024
- },
3025
- DictGetOrInsert: (loc_id, source_map, _platformDef, _K, _V) => (d, key, onMissing) => {
3026
- if (isFrozenValue(d)) {
3027
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3028
- }
3029
- if ((iterationLocks.get(d) || 0) > 0) {
3030
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3031
- }
3032
- const existing = d.get(key);
3033
- if (existing === undefined) {
3034
- const newValue = call_function(loc_id, source_map, onMissing, key);
3035
- d.set(key, newValue);
3036
- return newValue;
3037
- }
3038
- else {
3039
- return existing;
3040
- }
3041
- },
3042
- DictInsertOrUpdate: (loc_id, source_map, _platformDef, _K, _V) => (d, key, value, onConflictFn) => {
3043
- if (isFrozenValue(d)) {
3044
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3045
- }
3046
- if ((iterationLocks.get(d) || 0) > 0) {
3047
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3048
- }
3049
- const existing = d.get(key);
3050
- if (existing !== undefined) {
3051
- const result = call_function(loc_id, source_map, onConflictFn, existing, value, key);
3052
- d.set(key, result);
3053
- }
3054
- else {
3055
- d.set(key, value);
3056
- }
3057
- return null;
3058
- },
3059
- DictUpdate: (loc_id, source_map, _platformDef, K, _V) => {
3060
- const print = printFor(K);
3061
- return (d, key, value) => {
3062
- if (isFrozenValue(d)) {
3063
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3064
- }
3065
- if (d.has(key)) {
3066
- d.set(key, value);
3067
- return null;
3068
- }
3069
- else {
3070
- throw new EastError(`Dict does not contain key ${print(key)}`, { location: (source_map?.resolve(loc_id) ?? []) });
3071
- }
3072
- };
3073
- },
3074
- DictSwap: (loc_id, source_map, _platformDef, K, _V) => {
3075
- const print = printFor(K);
3076
- return (d, key, value) => {
3077
- if (isFrozenValue(d)) {
3078
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3079
- }
3080
- let existing = d.get(key);
3081
- if (existing === undefined) {
3082
- throw new EastError(`Dict does not contain key ${print(key)}`, { location: (source_map?.resolve(loc_id) ?? []) });
3083
- }
3084
- d.set(key, value);
3085
- return existing;
3086
- };
3087
- },
3088
- DictMerge: (loc_id, source_map, _platformDef, _K, _V) => (d, key, value, mergeFn, initialFn) => {
3089
- if (isFrozenValue(d)) {
3090
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3091
- }
3092
- if ((iterationLocks.get(d) || 0) > 0) {
3093
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3094
- }
3095
- let existing = d.get(key);
3096
- if (existing === undefined) {
3097
- existing = call_function(loc_id, source_map, initialFn, key);
3098
- }
3099
- const new_value = call_function(loc_id, source_map, mergeFn, existing, value, key);
3100
- d.set(key, new_value);
3101
- return null;
3102
- },
3103
- DictDelete: (loc_id, source_map, _platformDef, K, _V) => {
3104
- const print = printFor(K);
3105
- return (d, key) => {
3106
- if (isFrozenValue(d)) {
3107
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3108
- }
3109
- if ((iterationLocks.get(d) || 0) > 0) {
3110
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3111
- }
3112
- const existed = d.delete(key);
3113
- if (!existed) {
3114
- throw new EastError(`Dict does not contain key ${print(key)}`, { location: (source_map?.resolve(loc_id) ?? []) });
3115
- }
3116
- return null;
3117
- };
3118
- },
3119
- DictTryDelete: (loc_id, source_map, _platformDef, _K, _V) => (d, key) => {
3120
- if (isFrozenValue(d)) {
3121
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3122
- }
3123
- if ((iterationLocks.get(d) || 0) > 0) {
3124
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3125
- }
3126
- return d.delete(key);
3127
- },
3128
- DictPop: (loc_id, source_map, _platformDef, K, _V) => {
3129
- const print = printFor(K);
3130
- return (d, key) => {
3131
- if (isFrozenValue(d)) {
3132
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3133
- }
3134
- if ((iterationLocks.get(d) || 0) > 0) {
3135
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3136
- }
3137
- const existing = d.get(key);
3138
- if (existing === undefined) {
3139
- throw new EastError(`Dict does not contain key ${print(key)}`, { location: (source_map?.resolve(loc_id) ?? []) });
3140
- }
3141
- else {
3142
- d.delete(key);
3143
- return existing;
3144
- }
3145
- };
3146
- },
3147
- DictClear: (loc_id, source_map, _platformDef, _K, _V) => (d) => {
3148
- if (isFrozenValue(d)) {
3149
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3150
- }
3151
- if ((iterationLocks.get(d) || 0) > 0) {
3152
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3153
- }
3154
- d.clear();
3155
- return null;
3156
- },
3157
- DictUnionInPlace: (loc_id, source_map, _platformDef, _K, _V) => (d1, d2, onConflict) => {
3158
- if (isFrozenValue(d1)) {
3159
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3160
- }
3161
- if ((iterationLocks.get(d1) || 0) > 0) {
3162
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3163
- }
3164
- d2.forEach((v2, k) => {
3165
- const v1 = d1.get(k);
3166
- if (v1 === undefined) {
3167
- d1.set(k, v2);
3168
- }
3169
- else {
3170
- const new_value = call_function(loc_id, source_map, onConflict, v1, v2, k);
3171
- d1.set(k, new_value);
3172
- }
3173
- });
3174
- return null;
3175
- },
3176
- DictMergeAll: (loc_id, source_map, _platformDef, _K, _V) => (d1, d2, mergeFn, initialFn) => {
3177
- if (isFrozenValue(d1)) {
3178
- throw new EastError(FROZEN_MESSAGE, { location: (source_map?.resolve(loc_id) ?? []) });
3179
- }
3180
- if ((iterationLocks.get(d1) || 0) > 0) {
3181
- throw new EastError("Cannot modify Dict during iteration", { location: (source_map?.resolve(loc_id) ?? []) });
3182
- }
3183
- d2.forEach((v2, k) => {
3184
- let v1 = d1.get(k);
3185
- if (v1 === undefined) {
3186
- v1 = call_function(loc_id, source_map, initialFn, k);
3187
- }
3188
- const new_value = call_function(loc_id, source_map, mergeFn, v1, v2, k);
3189
- d1.set(k, new_value);
3190
- });
3191
- return null;
3192
- },
3193
- DictKeys: (loc_id, source_map, _platformDef, K, _V) => {
3194
- const compare = compareFor(K);
3195
- return (d) => {
3196
- return new SortedSet([...d.keys()], compare);
3197
- };
3198
- },
3199
- DictGetKeys: (loc_id, source_map, _platformDef, K, _V) => {
3200
- const compare = compareFor(K);
3201
- return (d, keys, onMissing) => {
3202
- const result = new SortedMap([], compare);
3203
- for (const k of keys) {
3204
- const v = d.get(k);
3205
- if (v !== undefined) {
3206
- result.set(k, v);
3207
- }
3208
- else {
3209
- const new_v = call_function(loc_id, source_map, onMissing, k);
3210
- result.set(k, new_v);
3211
- }
3212
- }
3213
- return result;
3214
- };
3215
- },
3216
- DictForEach: (loc_id, source_map, _platformDef, _K, _V, _T2) => (d, f) => {
3217
- lockForIteration(d);
3218
- try {
3219
- d.forEach((v, k) => {
3220
- call_function(loc_id, source_map, f, v, k);
3221
- });
3222
- return null;
3223
- }
3224
- finally {
3225
- unlockForIteration(d);
3226
- }
3227
- },
3228
- DictCopy: (loc_id, source_map, _platformDef, K, _V) => {
3229
- const compare = compareFor(K);
3230
- return (d) => {
3231
- return new SortedMap([...d], compare);
3232
- };
3233
- },
3234
- DictMap: (loc_id, source_map, _platformDef, K, _V, _V2) => {
3235
- const compare = compareFor(K);
3236
- return (d, f) => {
3237
- const result = new SortedMap([], compare);
3238
- lockForIteration(d);
3239
- try {
3240
- for (const [k, v] of d) {
3241
- const v2 = call_function(loc_id, source_map, f, v, k);
3242
- result.set(k, v2);
3243
- }
3244
- return result;
3245
- }
3246
- finally {
3247
- unlockForIteration(d);
3248
- }
3249
- };
3250
- },
3251
- DictFilter: (loc_id, source_map, _platformDef, K, _V) => {
3252
- const compare = compareFor(K);
3253
- return (d, f) => {
3254
- const result = new SortedMap([], compare);
3255
- lockForIteration(d);
3256
- try {
3257
- for (const [k, v] of d) {
3258
- const keep = call_function(loc_id, source_map, f, v, k);
3259
- if (keep) {
3260
- result.set(k, v);
3261
- }
3262
- }
3263
- return result;
3264
- }
3265
- finally {
3266
- unlockForIteration(d);
3267
- }
3268
- };
3269
- },
3270
- DictFilterMap: (loc_id, source_map, _platformDef, K, _V, _V2) => {
3271
- const compare = compareFor(K);
3272
- return (d, f) => {
3273
- const result = new SortedMap([], compare);
3274
- lockForIteration(d);
3275
- try {
3276
- for (const [k, v] of d) {
3277
- const v2 = call_function(loc_id, source_map, f, v, k);
3278
- if (v2.type === "some") {
3279
- result.set(k, v2.value);
3280
- }
3281
- }
3282
- return result;
3283
- }
3284
- finally {
3285
- unlockForIteration(d);
3286
- }
3287
- };
3288
- },
3289
- DictFirstMap: (loc_id, source_map, _platformDef, _K, _V, _T2) => (d, f) => {
3290
- lockForIteration(d);
3291
- try {
3292
- for (const [k, v] of d) {
3293
- const result = call_function(loc_id, source_map, f, v, k);
3294
- if (result.type === "some") {
3295
- return result;
3296
- }
3297
- }
3298
- return variant("none", null);
3299
- }
3300
- finally {
3301
- unlockForIteration(d);
3302
- }
3303
- },
3304
- DictMapReduce: (loc_id, source_map, _platformDef, _K, _V, _T2) => (d, mapFn, reduceFn) => {
3305
- if (d.size === 0) {
3306
- throw new EastError("Cannot reduce empty dictionary with no initial value", { location: (source_map?.resolve(loc_id) ?? []) });
3307
- }
3308
- lockForIteration(d);
3309
- try {
3310
- const iterator = d[Symbol.iterator]();
3311
- const first = iterator.next().value;
3312
- let acc = call_function(loc_id, source_map, mapFn, first[1], first[0]);
3313
- for (const [k, v] of iterator) {
3314
- const mapped = call_function(loc_id, source_map, mapFn, v, k);
3315
- acc = call_function(loc_id, source_map, reduceFn, acc, mapped);
3316
- }
3317
- return acc;
3318
- }
3319
- finally {
3320
- unlockForIteration(d);
3321
- }
3322
- },
3323
- DictReduce: (loc_id, source_map, _platformDef, _K, _V, _T2) => (d, f, init) => {
3324
- let acc = init;
3325
- lockForIteration(d);
3326
- try {
3327
- for (const [k, v] of d) {
3328
- acc = call_function(loc_id, source_map, f, acc, v, k);
3329
- }
3330
- return acc;
3331
- }
3332
- finally {
3333
- unlockForIteration(d);
3334
- }
3335
- },
3336
- DictScan: (loc_id, source_map, _platformDef, _K, _V, _T2) => (d, f, init) => {
3337
- const result = [];
3338
- let acc = init;
3339
- lockForIteration(d);
3340
- try {
3341
- for (const [k, v] of d) {
3342
- acc = call_function(loc_id, source_map, f, acc, v, k);
3343
- result.push(acc);
3344
- }
3345
- return result;
3346
- }
3347
- finally {
3348
- unlockForIteration(d);
3349
- }
3350
- },
3351
- DictToArray: (loc_id, source_map, _platformDef, _K, _V, _T2) => (d, valueFn) => {
3352
- const ret = [];
3353
- lockForIteration(d);
3354
- try {
3355
- for (const [k, v] of d) {
3356
- const v2 = call_function(loc_id, source_map, valueFn, v, k);
3357
- ret.push(v2);
3358
- }
3359
- return ret;
3360
- }
3361
- finally {
3362
- unlockForIteration(d);
3363
- }
3364
- },
3365
- DictToSet: (loc_id, source_map, _platformDef, _K, _V, K2) => {
3366
- const compare = compareFor(K2);
3367
- return (d, fn) => {
3368
- const result = new SortedSet([], compare);
3369
- lockForIteration(d);
3370
- try {
3371
- for (const [k, v] of d) {
3372
- const k2 = call_function(loc_id, source_map, fn, v, k);
3373
- result.add(k2);
3374
- }
3375
- return result;
3376
- }
3377
- finally {
3378
- unlockForIteration(d);
3379
- }
3380
- };
3381
- },
3382
- DictToDict: (loc_id, source_map, _platformDef, K, _V, K2, _V2) => {
3383
- const compare = compareFor(K2);
3384
- return (d, keyFn, valueFn, onConflict) => {
3385
- const result = new SortedMap([], compare);
3386
- lockForIteration(d);
3387
- try {
3388
- for (const [k, v] of d) {
3389
- const k2 = call_function(loc_id, source_map, keyFn, v, k);
3390
- const v2 = call_function(loc_id, source_map, valueFn, v, k);
3391
- const existing = result.get(k2);
3392
- if (existing !== undefined) {
3393
- const v3 = call_function(loc_id, source_map, onConflict, existing, v2, k2);
3394
- result.set(k2, v3);
3395
- }
3396
- else {
3397
- result.set(k2, v2);
3398
- }
3399
- }
3400
- return result;
3401
- }
3402
- finally {
3403
- unlockForIteration(d);
3404
- }
3405
- };
3406
- },
3407
- DictFlattenToArray: (loc_id, source_map, _platformDef, _K, _V, _T2) => (d, fn) => {
3408
- const ret = [];
3409
- lockForIteration(d);
3410
- try {
3411
- for (const [k, v] of d.entries()) {
3412
- const subarray = call_function(loc_id, source_map, fn, v, k);
3413
- for (const item of subarray) {
3414
- ret.push(item);
3415
- }
3416
- }
3417
- return ret;
3418
- }
3419
- finally {
3420
- unlockForIteration(d);
3421
- }
3422
- },
3423
- DictFlattenToSet: (loc_id, source_map, _platformDef, _K, _V, K2) => {
3424
- const compare = compareFor(K2);
3425
- return (d, fn) => {
3426
- const result = new SortedSet([], compare);
3427
- lockForIteration(d);
3428
- try {
3429
- for (const [k, v] of d.entries()) {
3430
- const subset = call_function(loc_id, source_map, fn, v, k);
3431
- for (const k2 of subset) {
3432
- result.add(k2);
3433
- }
3434
- }
3435
- return result;
3436
- }
3437
- finally {
3438
- unlockForIteration(d);
3439
- }
3440
- };
3441
- },
3442
- DictFlattenToDict: (loc_id, source_map, _platformDef, _K, _V, K2, _V2) => {
3443
- const compare = compareFor(K2);
3444
- return (d, fn, onConflict) => {
3445
- const result = new SortedMap([], compare);
3446
- lockForIteration(d);
3447
- try {
3448
- for (const [k, v] of d.entries()) {
3449
- const subdict = call_function(loc_id, source_map, fn, v, k);
3450
- for (const [k2, v2] of subdict.entries()) {
3451
- const existing = result.get(k2);
3452
- if (existing === undefined) {
3453
- result.set(k2, v2);
3454
- }
3455
- else {
3456
- const new_v2 = call_function(loc_id, source_map, onConflict, existing, v2, k2);
3457
- result.set(k2, new_v2);
3458
- }
3459
- }
3460
- }
3461
- return result;
3462
- }
3463
- finally {
3464
- unlockForIteration(d);
3465
- }
3466
- };
3467
- },
3468
- DictGroupFold: (loc_id, source_map, _platformDef, _K, _V, K2, _T2) => {
3469
- const compare = compareFor(K2);
3470
- return (d, keyFn, init, folder) => {
3471
- const result = new SortedMap([], compare);
3472
- lockForIteration(d);
3473
- try {
3474
- for (const [k, v] of d.entries()) {
3475
- const k2 = call_function(loc_id, source_map, keyFn, v, k);
3476
- let existing = result.get(k2);
3477
- if (existing === undefined) {
3478
- existing = call_function(loc_id, source_map, init, k2);
3479
- }
3480
- const new_val = call_function(loc_id, source_map, folder, existing, v, k);
3481
- result.set(k2, new_val);
3482
- }
3483
- return result;
3484
- }
3485
- finally {
3486
- unlockForIteration(d);
3487
- }
3488
- };
3489
- },
3490
- // Vector builtins
3491
- VectorLength: (_loc_id, _source_map, _platformDef, _T) => (vec) => BigInt(vec.length),
3492
- VectorGet: (loc_id, source_map, _platformDef, _T) => (vec, idx) => {
3493
- const i = Number(idx);
3494
- if (i < 0 || i >= vec.length) {
3495
- throw new EastError(`Vector index ${idx} out of bounds (length ${vec.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
3496
- }
3497
- if (vec instanceof Uint8ClampedArray)
3498
- return vec[i] !== 0;
3499
- return vec[i];
3500
- },
3501
- VectorSet: (loc_id, source_map, _platformDef, _T) => (vec, idx, value) => {
3502
- const i = Number(idx);
3503
- if (i < 0 || i >= vec.length) {
3504
- throw new EastError(`Vector index ${idx} out of bounds (length ${vec.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
3505
- }
3506
- const result = vec.slice();
3507
- if (result instanceof Uint8ClampedArray) {
3508
- result[i] = value ? 1 : 0;
3509
- }
3510
- else {
3511
- result[i] = value;
3512
- }
3513
- return result;
3514
- },
3515
- VectorSlice: (loc_id, source_map, _platformDef, _T) => (vec, start, end) => {
3516
- const s = Number(start);
3517
- const e = Number(end);
3518
- if (s < 0 || e > vec.length || s > e) {
3519
- throw new EastError(`Vector slice [${start}, ${end}) out of bounds (length ${vec.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
3520
- }
3521
- return vec.slice(s, e);
3522
- },
3523
- VectorConcat: (loc_id, source_map, _platformDef, T) => (a, b) => {
3524
- const result = allocateTypedArray(T, a.length + b.length);
3525
- result.set(a);
3526
- result.set(b, a.length);
3527
- return result;
3528
- },
3529
- VectorFromArray: (loc_id, source_map, _platformDef, T) => (arr) => {
3530
- return createTypedArray(T, arr);
3531
- },
3532
- VectorToArray: (_loc_id, _source_map, _platformDef, _T) => (vec) => {
3533
- if (vec instanceof Uint8ClampedArray) {
3534
- return Array.from(vec, v => v !== 0);
3535
- }
3536
- if (vec instanceof BigInt64Array) {
3537
- const result = [];
3538
- for (let i = 0; i < vec.length; i++)
3539
- result.push(vec[i]);
3540
- return result;
3541
- }
3542
- return Array.from(vec);
3543
- },
3544
- VectorToMatrix: (loc_id, source_map, _platformDef, _T) => (vec, rows, cols) => {
3545
- const r = Number(rows);
3546
- const c = Number(cols);
3547
- if (r * c !== vec.length) {
3548
- throw new EastError(`Cannot reshape vector of length ${vec.length} to matrix ${r}×${c}`, { location: (source_map?.resolve(loc_id) ?? []) });
3549
- }
3550
- return matrix(vec.slice(), r, c);
3551
- },
3552
- VectorZeros: (_loc_id, _source_map, _platformDef, T) => (len) => {
3553
- return allocateTypedArray(T, Number(len));
3554
- },
3555
- VectorOnes: (_loc_id, _source_map, _platformDef, T) => (len) => {
3556
- const arr = allocateTypedArray(T, Number(len));
3557
- arr.fill((arr instanceof BigInt64Array ? 1n : 1));
3558
- return arr;
3559
- },
3560
- VectorFill: (loc_id, source_map, _platformDef, T) => (len, value) => {
3561
- const n = Number(len);
3562
- if (T.type === "Float") {
3563
- const arr = new Float64Array(n);
3564
- arr.fill(value);
3565
- return arr;
3566
- }
3567
- else if (T.type === "Integer") {
3568
- const arr = new BigInt64Array(n);
3569
- arr.fill(value);
3570
- return arr;
3571
- }
3572
- else {
3573
- const arr = new Uint8ClampedArray(n);
3574
- arr.fill(value ? 1 : 0);
3575
- return arr;
3576
- }
3577
- },
3578
- VectorMap: (loc_id, source_map, _platformDef, _T, U) => (vec, f) => {
3579
- const len = vec.length;
3580
- const results = [];
3581
- for (let i = 0; i < len; i++) {
3582
- const elem = vec instanceof Uint8ClampedArray ? (vec[i] !== 0) : vec[i];
3583
- results.push(call_function(loc_id, source_map, f, elem, BigInt(i)));
3584
- }
3585
- return createTypedArray(U, results);
3586
- },
3587
- VectorFold: (loc_id, source_map, _platformDef, _T, _U) => (vec, init, f) => {
3588
- let acc = init;
3589
- for (let i = 0; i < vec.length; i++) {
3590
- const elem = vec instanceof Uint8ClampedArray ? (vec[i] !== 0) : vec[i];
3591
- acc = call_function(loc_id, source_map, f, acc, elem, BigInt(i));
3592
- }
3593
- return acc;
3594
- },
3595
- // Vector elementwise arithmetic + reductions. Reductions fold in index
3596
- // order, left to right — part of the cross-runtime contract, since a
3597
- // reassociated float sum gives a different last bit.
3598
- VectorScale: (loc_id, source_map, _platformDef, T) => {
3599
- const elem = requireNumericElem("VectorScale", T, loc_id, source_map);
3600
- return (v, alpha) => {
3601
- if (elem === "Float") {
3602
- const result = new Float64Array(v.length);
3603
- for (let i = 0; i < v.length; i++)
3604
- result[i] = v[i] * alpha;
3605
- return result;
3606
- }
3607
- const result = new BigInt64Array(v.length);
3608
- for (let i = 0; i < v.length; i++)
3609
- result[i] = wrapI64(v[i] * alpha);
3610
- return result;
3611
- };
3612
- },
3613
- VectorSum: (loc_id, source_map, _platformDef, T) => {
3614
- const elem = requireNumericElem("VectorSum", T, loc_id, source_map);
3615
- return (v) => {
3616
- if (elem === "Float") {
3617
- let acc = 0;
3618
- for (let i = 0; i < v.length; i++)
3619
- acc += v[i];
3620
- return acc;
3621
- }
3622
- let acc = 0n;
3623
- for (let i = 0; i < v.length; i++)
3624
- acc = wrapI64(acc + v[i]);
3625
- return acc;
3626
- };
3627
- },
3628
- VectorAddScaled: (loc_id, source_map, _platformDef, T) => {
3629
- const elem = requireNumericElem("VectorAddScaled", T, loc_id, source_map);
3630
- return (a, b, alpha) => {
3631
- requireSameLength(a, b, loc_id, source_map);
3632
- if (elem === "Float") {
3633
- const result = new Float64Array(a.length);
3634
- for (let i = 0; i < a.length; i++)
3635
- result[i] = a[i] + alpha * b[i];
3636
- return result;
3637
- }
3638
- const result = new BigInt64Array(a.length);
3639
- for (let i = 0; i < a.length; i++)
3640
- result[i] = wrapI64(a[i] + wrapI64(alpha * b[i]));
3641
- return result;
3642
- };
3643
- },
3644
- VectorMul: (loc_id, source_map, _platformDef, T) => {
3645
- const elem = requireNumericElem("VectorMul", T, loc_id, source_map);
3646
- return (a, b) => {
3647
- requireSameLength(a, b, loc_id, source_map);
3648
- if (elem === "Float") {
3649
- const result = new Float64Array(a.length);
3650
- for (let i = 0; i < a.length; i++)
3651
- result[i] = a[i] * b[i];
3652
- return result;
3653
- }
3654
- const result = new BigInt64Array(a.length);
3655
- for (let i = 0; i < a.length; i++)
3656
- result[i] = wrapI64(a[i] * b[i]);
3657
- return result;
3658
- };
3659
- },
3660
- VectorAddScalar: (loc_id, source_map, _platformDef, T) => {
3661
- const elem = requireNumericElem("VectorAddScalar", T, loc_id, source_map);
3662
- return (v, c) => {
3663
- if (elem === "Float") {
3664
- const result = new Float64Array(v.length);
3665
- for (let i = 0; i < v.length; i++)
3666
- result[i] = v[i] + c;
3667
- return result;
3668
- }
3669
- const result = new BigInt64Array(v.length);
3670
- for (let i = 0; i < v.length; i++)
3671
- result[i] = wrapI64(v[i] + c);
3672
- return result;
3673
- };
3674
- },
3675
- VectorDot: (loc_id, source_map, _platformDef, T) => {
3676
- const elem = requireNumericElem("VectorDot", T, loc_id, source_map);
3677
- return (a, b) => {
3678
- requireSameLength(a, b, loc_id, source_map);
3679
- if (elem === "Float") {
3680
- let acc = 0;
3681
- for (let i = 0; i < a.length; i++)
3682
- acc += a[i] * b[i];
3683
- return acc;
3684
- }
3685
- let acc = 0n;
3686
- for (let i = 0; i < a.length; i++)
3687
- acc = wrapI64(acc + wrapI64(a[i] * b[i]));
3688
- return acc;
3689
- };
3690
- },
3691
- VectorMax: (loc_id, source_map, _platformDef, T) => {
3692
- requireNumericElem("VectorMax", T, loc_id, source_map);
3693
- const less = lessFor(T);
3694
- return (v) => {
3695
- if (v.length === 0) {
3696
- throw new EastError("Cannot reduce empty Vector", { location: (source_map?.resolve(loc_id) ?? []) });
3697
- }
3698
- let best = v[0];
3699
- for (let i = 1; i < v.length; i++) {
3700
- if (less(best, v[i]))
3701
- best = v[i];
3702
- }
3703
- return best;
3704
- };
3705
- },
3706
- VectorMin: (loc_id, source_map, _platformDef, T) => {
3707
- requireNumericElem("VectorMin", T, loc_id, source_map);
3708
- const less = lessFor(T);
3709
- return (v) => {
3710
- if (v.length === 0) {
3711
- throw new EastError("Cannot reduce empty Vector", { location: (source_map?.resolve(loc_id) ?? []) });
3712
- }
3713
- let best = v[0];
3714
- for (let i = 1; i < v.length; i++) {
3715
- if (less(v[i], best))
3716
- best = v[i];
3717
- }
3718
- return best;
3719
- };
3720
- },
3721
- VectorArgMax: (loc_id, source_map, _platformDef, T) => {
3722
- requireNumericElem("VectorArgMax", T, loc_id, source_map);
3723
- const less = lessFor(T);
3724
- return (v) => {
3725
- if (v.length === 0) {
3726
- throw new EastError("Cannot reduce empty Vector", { location: (source_map?.resolve(loc_id) ?? []) });
3727
- }
3728
- let bestIdx = 0;
3729
- for (let i = 1; i < v.length; i++) {
3730
- if (less(v[bestIdx], v[i]))
3731
- bestIdx = i;
3732
- }
3733
- return BigInt(bestIdx);
3734
- };
3735
- },
3736
- VectorArgMin: (loc_id, source_map, _platformDef, T) => {
3737
- requireNumericElem("VectorArgMin", T, loc_id, source_map);
3738
- const less = lessFor(T);
3739
- return (v) => {
3740
- if (v.length === 0) {
3741
- throw new EastError("Cannot reduce empty Vector", { location: (source_map?.resolve(loc_id) ?? []) });
3742
- }
3743
- let bestIdx = 0;
3744
- for (let i = 1; i < v.length; i++) {
3745
- if (less(v[i], v[bestIdx]))
3746
- bestIdx = i;
3747
- }
3748
- return BigInt(bestIdx);
3749
- };
3750
- },
3751
- VectorMean: (loc_id, source_map, _platformDef, T) => {
3752
- requireNumericElem("VectorMean", T, loc_id, source_map);
3753
- return (v) => {
3754
- let acc = 0;
3755
- for (let i = 0; i < v.length; i++)
3756
- acc += Number(v[i]);
3757
- return acc / v.length;
3758
- };
3759
- },
3760
- VectorCumSum: (loc_id, source_map, _platformDef, T) => {
3761
- const elem = requireNumericElem("VectorCumSum", T, loc_id, source_map);
3762
- return (v) => {
3763
- if (elem === "Float") {
3764
- const result = new Float64Array(v.length);
3765
- let acc = 0;
3766
- for (let i = 0; i < v.length; i++) {
3767
- acc += v[i];
3768
- result[i] = acc;
3769
- }
3770
- return result;
3771
- }
3772
- const result = new BigInt64Array(v.length);
3773
- let acc = 0n;
3774
- for (let i = 0; i < v.length; i++) {
3775
- acc = wrapI64(acc + v[i]);
3776
- result[i] = acc;
3777
- }
3778
- return result;
3779
- };
3780
- },
3781
- VectorAbs: (loc_id, source_map, _platformDef, T) => {
3782
- const elem = requireNumericElem("VectorAbs", T, loc_id, source_map);
3783
- return (v) => {
3784
- if (elem === "Float") {
3785
- const result = new Float64Array(v.length);
3786
- for (let i = 0; i < v.length; i++) {
3787
- const x = v[i];
3788
- result[i] = x < 0 ? -x : x;
3789
- }
3790
- return result;
3791
- }
3792
- const result = new BigInt64Array(v.length);
3793
- for (let i = 0; i < v.length; i++) {
3794
- const x = v[i];
3795
- result[i] = wrapI64(x < 0n ? -x : x);
3796
- }
3797
- return result;
3798
- };
3799
- },
3800
- VectorClamp: (loc_id, source_map, _platformDef, T) => {
3801
- const elem = requireNumericElem("VectorClamp", T, loc_id, source_map);
3802
- const less = lessFor(T);
3803
- return (v, lo, hi) => {
3804
- const result = elem === "Float" ? new Float64Array(v.length) : new BigInt64Array(v.length);
3805
- for (let i = 0; i < v.length; i++) {
3806
- const x = v[i];
3807
- result[i] = less(x, lo) ? lo : less(hi, x) ? hi : x;
3808
- }
3809
- return result;
3810
- };
3811
- },
3812
- // Vector gather/scatter and sorted search
3813
- VectorGather: (loc_id, source_map, _platformDef, T) => (v, idx) => {
3814
- const result = allocateTypedArray(T, idx.length);
3815
- for (let j = 0; j < idx.length; j++) {
3816
- const i = Number(idx[j]);
3817
- if (i < 0 || i >= v.length) {
3818
- throw new EastError(`Vector index ${idx[j]} out of bounds (length ${v.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
3819
- }
3820
- result[j] = v[i];
3821
- }
3822
- return result;
3823
- },
3824
- VectorScatterAdd: (loc_id, source_map, _platformDef, T) => {
3825
- const elem = requireNumericElem("VectorScatterAdd", T, loc_id, source_map);
3826
- return (dst, idx, src) => {
3827
- requireSameLength(idx, src, loc_id, source_map);
3828
- const result = dst.slice();
3829
- for (let j = 0; j < idx.length; j++) {
3830
- const i = Number(idx[j]);
3831
- if (i < 0 || i >= dst.length) {
3832
- throw new EastError(`Vector index ${idx[j]} out of bounds (length ${dst.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
3833
- }
3834
- if (elem === "Float") {
3835
- result[i] = (result[i]) + src[j];
3836
- }
3837
- else {
3838
- result[i] = wrapI64((result[i]) + src[j]);
3839
- }
3840
- }
3841
- return result;
3842
- };
3843
- },
3844
- VectorSearchSorted: (loc_id, source_map, _platformDef, T) => {
3845
- const less = lessFor(T);
3846
- const readElem = T.type === "Boolean"
3847
- ? (v, i) => v[i] !== 0
3848
- : (v, i) => v[i];
3849
- return (haystack, needles) => {
3850
- const result = new BigInt64Array(needles.length);
3851
- for (let j = 0; j < needles.length; j++) {
3852
- const needle = readElem(needles, j);
3853
- let lo = 0;
3854
- let hi = haystack.length;
3855
- while (lo < hi) {
3856
- const mid = (lo + hi) >>> 1;
3857
- if (less(readElem(haystack, mid), needle)) {
3858
- lo = mid + 1;
3859
- }
3860
- else {
3861
- hi = mid;
3862
- }
3863
- }
3864
- result[j] = BigInt(lo);
3865
- }
3866
- return result;
3867
- };
3868
- },
3869
- // Vector masks and selection (comparisons use East's total order)
3870
- VectorEq: (loc_id, source_map, _platformDef, T) => {
3871
- const equal = equalFor(T);
3872
- const readElem = T.type === "Boolean"
3873
- ? (v, i) => v[i] !== 0
3874
- : (v, i) => v[i];
3875
- return (a, b) => {
3876
- requireSameLength(a, b, loc_id, source_map);
3877
- const result = new Uint8ClampedArray(a.length);
3878
- for (let i = 0; i < a.length; i++)
3879
- result[i] = equal(readElem(a, i), readElem(b, i)) ? 1 : 0;
3880
- return result;
3881
- };
3882
- },
3883
- VectorLt: (loc_id, source_map, _platformDef, T) => {
3884
- const less = lessFor(T);
3885
- const readElem = T.type === "Boolean"
3886
- ? (v, i) => v[i] !== 0
3887
- : (v, i) => v[i];
3888
- return (a, b) => {
3889
- requireSameLength(a, b, loc_id, source_map);
3890
- const result = new Uint8ClampedArray(a.length);
3891
- for (let i = 0; i < a.length; i++)
3892
- result[i] = less(readElem(a, i), readElem(b, i)) ? 1 : 0;
3893
- return result;
3894
- };
3895
- },
3896
- VectorGt: (loc_id, source_map, _platformDef, T) => {
3897
- const greater = greaterFor(T);
3898
- const readElem = T.type === "Boolean"
3899
- ? (v, i) => v[i] !== 0
3900
- : (v, i) => v[i];
3901
- return (a, b) => {
3902
- requireSameLength(a, b, loc_id, source_map);
3903
- const result = new Uint8ClampedArray(a.length);
3904
- for (let i = 0; i < a.length; i++)
3905
- result[i] = greater(readElem(a, i), readElem(b, i)) ? 1 : 0;
3906
- return result;
3907
- };
3908
- },
3909
- VectorSelect: (loc_id, source_map, _platformDef, T) => (mask, a, b) => {
3910
- requireSameLength(mask, a, loc_id, source_map);
3911
- requireSameLength(a, b, loc_id, source_map);
3912
- const result = allocateTypedArray(T, mask.length);
3913
- for (let i = 0; i < mask.length; i++)
3914
- result[i] = (mask[i] !== 0 ? a[i] : b[i]);
3915
- return result;
3916
- },
3917
- VectorCompress: (loc_id, source_map, _platformDef, T) => (mask, v) => {
3918
- requireSameLength(mask, v, loc_id, source_map);
3919
- let count = 0;
3920
- for (let i = 0; i < mask.length; i++) {
3921
- if (mask[i] !== 0)
3922
- count++;
3923
- }
3924
- const result = allocateTypedArray(T, count);
3925
- let j = 0;
3926
- for (let i = 0; i < mask.length; i++) {
3927
- if (mask[i] !== 0)
3928
- result[j++] = v[i];
3929
- }
3930
- return result;
3931
- },
3932
- VectorCountTrue: (_loc_id, _source_map, _platformDef) => (mask) => {
3933
- let count = 0n;
3934
- for (let i = 0; i < mask.length; i++) {
3935
- if (mask[i] !== 0)
3936
- count += 1n;
3937
- }
3938
- return count;
3939
- },
3940
- // Sparse accumulators: parallel (ix, v) with strictly ascending ix.
3941
- // Entries absent from a side are structurally absent, not explicit zeros:
3942
- // an A-only entry passes through unscaled, a B-only entry contributes
3943
- // alpha*vB even when alpha is NaN or infinite.
3944
- SparseAxpy: (loc_id, source_map, _platformDef, T) => {
3945
- const elem = requireNumericElem("SparseAxpy", T, loc_id, source_map);
3946
- return (ixA, vA, ixB, vB, alpha) => {
3947
- requireSparse(ixA, vA, loc_id, source_map);
3948
- requireSparse(ixB, vB, loc_id, source_map);
3949
- let count = 0;
3950
- let i = 0;
3951
- let j = 0;
3952
- while (i < ixA.length && j < ixB.length) {
3953
- const a = ixA[i];
3954
- const b = ixB[j];
3955
- if (a < b)
3956
- i++;
3957
- else if (b < a)
3958
- j++;
3959
- else {
3960
- i++;
3961
- j++;
3962
- }
3963
- count++;
3964
- }
3965
- count += (ixA.length - i) + (ixB.length - j);
3966
- const outIx = new BigInt64Array(count);
3967
- const outV = elem === "Float" ? new Float64Array(count) : new BigInt64Array(count);
3968
- i = 0;
3969
- j = 0;
3970
- let k = 0;
3971
- while (i < ixA.length && j < ixB.length) {
3972
- const a = ixA[i];
3973
- const b = ixB[j];
3974
- if (a < b) {
3975
- outIx[k] = a;
3976
- outV[k] = vA[i];
3977
- i++;
3978
- }
3979
- else if (b < a) {
3980
- outIx[k] = b;
3981
- outV[k] = elem === "Float" ? alpha * vB[j] : wrapI64(alpha * vB[j]);
3982
- j++;
3983
- }
3984
- else {
3985
- outIx[k] = a;
3986
- outV[k] = elem === "Float"
3987
- ? vA[i] + alpha * vB[j]
3988
- : wrapI64(vA[i] + wrapI64(alpha * vB[j]));
3989
- i++;
3990
- j++;
3991
- }
3992
- k++;
3993
- }
3994
- for (; i < ixA.length; i++, k++) {
3995
- outIx[k] = ixA[i];
3996
- outV[k] = vA[i];
3997
- }
3998
- for (; j < ixB.length; j++, k++) {
3999
- outIx[k] = ixB[j];
4000
- outV[k] = elem === "Float" ? alpha * vB[j] : wrapI64(alpha * vB[j]);
4001
- }
4002
- return { ix: outIx, v: outV };
4003
- };
4004
- },
4005
- SparseFromPairs: (loc_id, source_map, _platformDef, T) => {
4006
- const elem = requireNumericElem("SparseFromPairs", T, loc_id, source_map);
4007
- return (ix, v) => {
4008
- if (ix.length !== v.length) {
4009
- throw new EastError(`Sparse index and value lengths differ (${ix.length} vs ${v.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
4010
- }
4011
- // Stable: order by (index, original position) so equal indices
4012
- // accumulate in input order and the float result is deterministic.
4013
- const order = new Array(ix.length);
4014
- for (let i = 0; i < ix.length; i++)
4015
- order[i] = i;
4016
- order.sort((p, q) => {
4017
- const a = ix[p];
4018
- const b = ix[q];
4019
- if (a < b)
4020
- return -1;
4021
- if (a > b)
4022
- return 1;
4023
- return p - q;
4024
- });
4025
- let count = 0;
4026
- for (let i = 0; i < order.length; i++) {
4027
- if (i === 0 || ix[order[i]] !== ix[order[i - 1]])
4028
- count++;
4029
- }
4030
- const outIx = new BigInt64Array(count);
4031
- const outV = elem === "Float" ? new Float64Array(count) : new BigInt64Array(count);
4032
- let k = -1;
4033
- for (let i = 0; i < order.length; i++) {
4034
- const p = order[i];
4035
- if (i === 0 || ix[p] !== outIx[k]) {
4036
- k++;
4037
- outIx[k] = ix[p];
4038
- outV[k] = v[p];
4039
- }
4040
- else {
4041
- outV[k] = elem === "Float"
4042
- ? (outV[k]) + v[p]
4043
- : wrapI64((outV[k]) + v[p]);
4044
- }
4045
- }
4046
- return { ix: outIx, v: outV };
4047
- };
4048
- },
4049
- SparseFilterGt: (loc_id, source_map, _platformDef, T) => {
4050
- const elem = requireNumericElem("SparseFilterGt", T, loc_id, source_map);
4051
- const greater = greaterFor(T);
4052
- return (ix, v, threshold) => {
4053
- requireSparse(ix, v, loc_id, source_map);
4054
- let count = 0;
4055
- for (let i = 0; i < v.length; i++) {
4056
- if (greater(v[i], threshold))
4057
- count++;
4058
- }
4059
- const outIx = new BigInt64Array(count);
4060
- const outV = elem === "Float" ? new Float64Array(count) : new BigInt64Array(count);
4061
- let k = 0;
4062
- for (let i = 0; i < v.length; i++) {
4063
- if (greater(v[i], threshold)) {
4064
- outIx[k] = ix[i];
4065
- outV[k] = v[i];
4066
- k++;
4067
- }
4068
- }
4069
- return { ix: outIx, v: outV };
4070
- };
4071
- },
4072
- // Matrix builtins
4073
- MatrixRows: (_loc_id, _source_map, _platformDef, _T) => (m) => BigInt(m.rows),
4074
- MatrixCols: (_loc_id, _source_map, _platformDef, _T) => (m) => BigInt(m.cols),
4075
- MatrixGet: (loc_id, source_map, _platformDef, _T) => (m, row, col) => {
4076
- const r = Number(row);
4077
- const c = Number(col);
4078
- if (r < 0 || r >= m.rows || c < 0 || c >= m.cols) {
4079
- throw new EastError(`Matrix index (${row}, ${col}) out of bounds (${m.rows}×${m.cols})`, { location: (source_map?.resolve(loc_id) ?? []) });
4080
- }
4081
- const val = m.data[r * m.cols + c];
4082
- if (m.data instanceof Uint8ClampedArray)
4083
- return val !== 0;
4084
- return val;
4085
- },
4086
- MatrixSet: (loc_id, source_map, _platformDef, _T) => (m, row, col, value) => {
4087
- const r = Number(row);
4088
- const c = Number(col);
4089
- if (r < 0 || r >= m.rows || c < 0 || c >= m.cols) {
4090
- throw new EastError(`Matrix index (${row}, ${col}) out of bounds (${m.rows}×${m.cols})`, { location: (source_map?.resolve(loc_id) ?? []) });
4091
- }
4092
- const data = m.data.slice();
4093
- if (data instanceof Uint8ClampedArray) {
4094
- data[r * m.cols + c] = value ? 1 : 0;
4095
- }
4096
- else {
4097
- data[r * m.cols + c] = value;
4098
- }
4099
- return matrix(data, m.rows, m.cols);
4100
- },
4101
- MatrixGetRow: (loc_id, source_map, _platformDef, _T) => (m, row) => {
4102
- const r = Number(row);
4103
- if (r < 0 || r >= m.rows) {
4104
- throw new EastError(`Matrix row ${row} out of bounds (${m.rows} rows)`, { location: (source_map?.resolve(loc_id) ?? []) });
4105
- }
4106
- const start = r * m.cols;
4107
- return m.data.slice(start, start + m.cols);
4108
- },
4109
- MatrixGetCol: (loc_id, source_map, _platformDef, T) => (m, col) => {
4110
- const c = Number(col);
4111
- if (c < 0 || c >= m.cols) {
4112
- throw new EastError(`Matrix column ${col} out of bounds (${m.cols} cols)`, { location: (source_map?.resolve(loc_id) ?? []) });
4113
- }
4114
- const result = allocateTypedArray(T, m.rows);
4115
- for (let r = 0; r < m.rows; r++)
4116
- result[r] = m.data[r * m.cols + c];
4117
- return result;
4118
- },
4119
- MatrixToVector: (_loc_id, _source_map, _platformDef, _T) => (m) => {
4120
- return m.data.slice();
4121
- },
4122
- MatrixFromArray: (loc_id, source_map, _platformDef, T) => (arr) => {
4123
- if (arr.length === 0) {
4124
- return matrix(createTypedArray(T, []), 0, 0);
4125
- }
4126
- const rows = arr.length;
4127
- const cols = arr[0].length;
4128
- for (let i = 1; i < rows; i++) {
4129
- if (arr[i].length !== cols) {
4130
- throw new EastError(`Jagged array: row 0 has ${cols} columns but row ${i} has ${arr[i].length}`, { location: (source_map?.resolve(loc_id) ?? []) });
4131
- }
4132
- }
4133
- const flat = [];
4134
- for (const row of arr) {
4135
- flat.push(...row);
4136
- }
4137
- return matrix(createTypedArray(T, flat), rows, cols);
4138
- },
4139
- MatrixToArray: (_loc_id, _source_map, _platformDef, _T) => (m) => {
4140
- const result = [];
4141
- for (let r = 0; r < m.rows; r++) {
4142
- const row = [];
4143
- for (let c = 0; c < m.cols; c++) {
4144
- const val = m.data[r * m.cols + c];
4145
- row.push(m.data instanceof Uint8ClampedArray ? val !== 0 : val);
4146
- }
4147
- result.push(row);
4148
- }
4149
- return result;
4150
- },
4151
- MatrixTranspose: (loc_id, source_map, _platformDef, T) => (m) => {
4152
- const result = allocateTypedArray(T, m.rows * m.cols);
4153
- for (let r = 0; r < m.rows; r++) {
4154
- for (let c = 0; c < m.cols; c++) {
4155
- result[c * m.rows + r] = m.data[r * m.cols + c];
4156
- }
4157
- }
4158
- return matrix(result, m.cols, m.rows);
4159
- },
4160
- MatrixZeros: (_loc_id, _source_map, _platformDef, T) => (rows, cols) => {
4161
- return matrix(allocateTypedArray(T, Number(rows) * Number(cols)), Number(rows), Number(cols));
4162
- },
4163
- MatrixOnes: (_loc_id, _source_map, _platformDef, T) => (rows, cols) => {
4164
- const data = allocateTypedArray(T, Number(rows) * Number(cols));
4165
- data.fill((data instanceof BigInt64Array ? 1n : 1));
4166
- return matrix(data, Number(rows), Number(cols));
4167
- },
4168
- MatrixFill: (loc_id, source_map, _platformDef, T) => (rows, cols, value) => {
4169
- const r = Number(rows);
4170
- const c = Number(cols);
4171
- const n = r * c;
4172
- if (T.type === "Float") {
4173
- const data = new Float64Array(n);
4174
- data.fill(value);
4175
- return matrix(data, r, c);
4176
- }
4177
- else if (T.type === "Integer") {
4178
- const data = new BigInt64Array(n);
4179
- data.fill(value);
4180
- return matrix(data, r, c);
4181
- }
4182
- else {
4183
- const data = new Uint8ClampedArray(n);
4184
- data.fill(value ? 1 : 0);
4185
- return matrix(data, r, c);
4186
- }
4187
- },
4188
- MatrixMapElements: (loc_id, source_map, _platformDef, _T, U) => (m, f) => {
4189
- const results = [];
4190
- for (let r = 0; r < m.rows; r++) {
4191
- for (let c = 0; c < m.cols; c++) {
4192
- const val = m.data[r * m.cols + c];
4193
- const elem = m.data instanceof Uint8ClampedArray ? val !== 0 : val;
4194
- results.push(call_function(loc_id, source_map, f, elem, BigInt(r), BigInt(c)));
4195
- }
4196
- }
4197
- return matrix(createTypedArray(U, results), m.rows, m.cols);
4198
- },
4199
- MatrixMapRows: (loc_id, source_map, _platformDef, _T, U) => (m, f) => {
4200
- const resultRows = [];
4201
- for (let r = 0; r < m.rows; r++) {
4202
- const start = r * m.cols;
4203
- const rowVec = m.data.slice(start, start + m.cols);
4204
- const resultRow = call_function(loc_id, source_map, f, rowVec, BigInt(r));
4205
- resultRows.push(resultRow);
4206
- }
4207
- if (resultRows.length === 0) {
4208
- return matrix(allocateTypedArray(U, 0), 0, 0);
4209
- }
4210
- const newCols = resultRows[0].length;
4211
- const data = allocateTypedArray(U, m.rows * newCols);
4212
- for (let r = 0; r < m.rows; r++) {
4213
- data.set(resultRows[r], r * newCols);
4214
- }
4215
- return matrix(data, m.rows, newCols);
4216
- },
4217
- MatrixToRows: (_loc_id, _source_map, _platformDef, _T) => (m) => {
4218
- const rows = [];
4219
- for (let r = 0; r < m.rows; r++) {
4220
- rows.push(m.data.slice(r * m.cols, (r + 1) * m.cols));
4221
- }
4222
- return rows;
4223
- },
4224
- MatrixFromRows: (loc_id, source_map, _platformDef, T) => (arr) => {
4225
- if (arr.length === 0) {
4226
- return matrix(allocateTypedArray(T, 0), 0, 0);
4227
- }
4228
- const cols = arr[0].length;
4229
- for (let i = 1; i < arr.length; i++) {
4230
- if (arr[i].length !== cols) {
4231
- throw new EastError(`Jagged rows: row 0 has ${cols} columns but row ${i} has ${arr[i].length}`, { location: (source_map?.resolve(loc_id) ?? []) });
4232
- }
4233
- }
4234
- const data = allocateTypedArray(T, arr.length * cols);
4235
- for (let r = 0; r < arr.length; r++)
4236
- data.set(arr[r], r * cols);
4237
- return matrix(data, arr.length, cols);
4238
- },
4239
- // Matrix elementwise arithmetic + reductions. Sums accumulate in ascending
4240
- // index order (row-major for whole-matrix walks, ascending row for column
4241
- // sums, ascending column within each row for row sums and vec-mul) — the
4242
- // same left-to-right contract as the Vector reductions.
4243
- MatrixScale: (loc_id, source_map, _platformDef, T) => {
4244
- const elem = requireNumericElem("MatrixScale", T, loc_id, source_map);
4245
- return (m, alpha) => {
4246
- const src = m.data;
4247
- if (elem === "Float") {
4248
- const data = new Float64Array(src.length);
4249
- for (let i = 0; i < src.length; i++)
4250
- data[i] = src[i] * alpha;
4251
- return matrix(data, m.rows, m.cols);
4252
- }
4253
- const data = new BigInt64Array(src.length);
4254
- for (let i = 0; i < src.length; i++)
4255
- data[i] = wrapI64(src[i] * alpha);
4256
- return matrix(data, m.rows, m.cols);
4257
- };
4258
- },
4259
- MatrixAddScaled: (loc_id, source_map, _platformDef, T) => {
4260
- const elem = requireNumericElem("MatrixAddScaled", T, loc_id, source_map);
4261
- return (a, b, alpha) => {
4262
- requireSameDims(a, b, loc_id, source_map);
4263
- const ad = a.data;
4264
- const bd = b.data;
4265
- if (elem === "Float") {
4266
- const data = new Float64Array(ad.length);
4267
- for (let i = 0; i < ad.length; i++)
4268
- data[i] = ad[i] + alpha * bd[i];
4269
- return matrix(data, a.rows, a.cols);
4270
- }
4271
- const data = new BigInt64Array(ad.length);
4272
- for (let i = 0; i < ad.length; i++)
4273
- data[i] = wrapI64(ad[i] + wrapI64(alpha * bd[i]));
4274
- return matrix(data, a.rows, a.cols);
4275
- };
4276
- },
4277
- MatrixMulElementwise: (loc_id, source_map, _platformDef, T) => {
4278
- const elem = requireNumericElem("MatrixMulElementwise", T, loc_id, source_map);
4279
- return (a, b) => {
4280
- requireSameDims(a, b, loc_id, source_map);
4281
- const ad = a.data;
4282
- const bd = b.data;
4283
- if (elem === "Float") {
4284
- const data = new Float64Array(ad.length);
4285
- for (let i = 0; i < ad.length; i++)
4286
- data[i] = ad[i] * bd[i];
4287
- return matrix(data, a.rows, a.cols);
4288
- }
4289
- const data = new BigInt64Array(ad.length);
4290
- for (let i = 0; i < ad.length; i++)
4291
- data[i] = wrapI64(ad[i] * bd[i]);
4292
- return matrix(data, a.rows, a.cols);
4293
- };
4294
- },
4295
- MatrixRowSums: (loc_id, source_map, _platformDef, T) => {
4296
- const elem = requireNumericElem("MatrixRowSums", T, loc_id, source_map);
4297
- return (m) => {
4298
- const src = m.data;
4299
- if (elem === "Float") {
4300
- const result = new Float64Array(m.rows);
4301
- for (let r = 0; r < m.rows; r++) {
4302
- let acc = 0;
4303
- for (let c = 0; c < m.cols; c++)
4304
- acc += src[r * m.cols + c];
4305
- result[r] = acc;
4306
- }
4307
- return result;
4308
- }
4309
- const result = new BigInt64Array(m.rows);
4310
- for (let r = 0; r < m.rows; r++) {
4311
- let acc = 0n;
4312
- for (let c = 0; c < m.cols; c++)
4313
- acc = wrapI64(acc + src[r * m.cols + c]);
4314
- result[r] = acc;
4315
- }
4316
- return result;
4317
- };
4318
- },
4319
- MatrixColSums: (loc_id, source_map, _platformDef, T) => {
4320
- const elem = requireNumericElem("MatrixColSums", T, loc_id, source_map);
4321
- return (m) => {
4322
- const src = m.data;
4323
- if (elem === "Float") {
4324
- const result = new Float64Array(m.cols);
4325
- for (let c = 0; c < m.cols; c++) {
4326
- let acc = 0;
4327
- for (let r = 0; r < m.rows; r++)
4328
- acc += src[r * m.cols + c];
4329
- result[c] = acc;
4330
- }
4331
- return result;
4332
- }
4333
- const result = new BigInt64Array(m.cols);
4334
- for (let c = 0; c < m.cols; c++) {
4335
- let acc = 0n;
4336
- for (let r = 0; r < m.rows; r++)
4337
- acc = wrapI64(acc + src[r * m.cols + c]);
4338
- result[c] = acc;
4339
- }
4340
- return result;
4341
- };
4342
- },
4343
- MatrixVecMul: (loc_id, source_map, _platformDef, T) => {
4344
- const elem = requireNumericElem("MatrixVecMul", T, loc_id, source_map);
4345
- return (m, v) => {
4346
- if (v.length !== m.cols) {
4347
- throw new EastError(`MatrixVecMul dimension mismatch (${m.rows}x${m.cols} vs length ${v.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
4348
- }
4349
- const src = m.data;
4350
- if (elem === "Float") {
4351
- const result = new Float64Array(m.rows);
4352
- for (let r = 0; r < m.rows; r++) {
4353
- let acc = 0;
4354
- for (let c = 0; c < m.cols; c++)
4355
- acc += src[r * m.cols + c] * v[c];
4356
- result[r] = acc;
4357
- }
4358
- return result;
4359
- }
4360
- const result = new BigInt64Array(m.rows);
4361
- for (let r = 0; r < m.rows; r++) {
4362
- let acc = 0n;
4363
- for (let c = 0; c < m.cols; c++)
4364
- acc = wrapI64(acc + wrapI64(src[r * m.cols + c] * v[c]));
4365
- result[r] = acc;
4366
- }
4367
- return result;
4368
- };
4369
- },
4370
- };
4371
- /** @internal */
4372
- export function applyTypeParameters(t, params) {
4373
- if (typeof (t) === "string") {
4374
- let ret = params.get(t);
4375
- if (ret === undefined) {
4376
- throw new Error(`Unable to find type parameter ${JSON.stringify(t)}`);
4377
- }
4378
- return ret;
4379
- }
4380
- else if (t.type === "Null" || t.type === "Boolean" || t.type === "Integer" || t.type === "Float" || t.type === "String" || t.type === "DateTime" || t.type === "Blob" || t.type === "Never") {
4381
- return t;
4382
- }
4383
- else if (t.type === "Ref") {
4384
- return variant("Ref", applyTypeParameters(t.value, params));
4385
- }
4386
- else if (t.type === "Array") {
4387
- return variant("Array", applyTypeParameters(t.value, params));
4388
- }
4389
- else if (t.type === "Set") {
4390
- return variant("Set", applyTypeParameters(t.value, params));
4391
- }
4392
- else if (t.type === "Dict") {
4393
- return variant("Dict", { key: applyTypeParameters(t.value.key, params), value: applyTypeParameters(t.value.value, params) });
4394
- }
4395
- else if (t.type === "Struct") {
4396
- return variant("Struct", t.value.map(({ name, type }) => ({ name, type: applyTypeParameters(type, params) })));
4397
- }
4398
- else if (t.type === "Variant") {
4399
- return variant("Variant", t.value.map(({ name, type }) => ({ name, type: applyTypeParameters(type, params) })));
4400
- }
4401
- else if (t.type === "Recursive") {
4402
- return t;
4403
- }
4404
- else if (t.type === "Function") {
4405
- return variant("Function", { inputs: t.value.inputs.map(i => applyTypeParameters(i, params)), output: applyTypeParameters(t.value.output, params) });
4406
- }
4407
- else if (t.type === "AsyncFunction") {
4408
- return variant("AsyncFunction", { inputs: t.value.inputs.map(i => applyTypeParameters(i, params)), output: applyTypeParameters(t.value.output, params) });
4409
- }
4410
- else if (t.type === "Vector") {
4411
- return variant("Vector", applyTypeParameters(t.value, params));
4412
- }
4413
- else if (t.type === "Matrix") {
4414
- return variant("Matrix", applyTypeParameters(t.value, params));
4415
- }
4416
- else {
4417
- throw new Error(`Unhandled type ${t.type}`);
4418
- }
4419
- }
5
+ /* The TypeScript runtime's compiler, from IR to JavaScript closures. The code
6
+ * lives in compile/: the pieces compiled code shares, the IR compiler with a
7
+ * module per node family, and the builtins with a module per domain. This
8
+ * module names what the package exports from it. */
9
+ export { isTypeValueEqual } from "./type_of_type.js";
10
+ export { printTypeValue, EAST_IR_SYMBOL, EAST_CAPTURES_SYMBOL, EAST_SOURCE_MAP_SYMBOL, requiresBoxing, ReturnException, } from "./compile/runtime.js";
11
+ export { compile_internal } from "./compile/ir.js";
12
+ export { applyTypeParameters } from "./compile/type_parameters.js";
4420
13
  //# sourceMappingURL=compile.js.map