@scriptc/compiler 0.0.36 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +7 -5
  2. package/ambient/scriptc-overrides.d.ts +0 -7
  3. package/ambient/scriptc.d.ts +1 -1
  4. package/dist/backend/c/exprs.js +69 -45
  5. package/dist/backend/c/exprs.js.map +1 -1
  6. package/dist/backend/c/may-throw.js +3 -0
  7. package/dist/backend/c/may-throw.js.map +1 -1
  8. package/dist/backend/c/stmts.js +18 -0
  9. package/dist/backend/c/stmts.js.map +1 -1
  10. package/dist/backend/c/walkers.js +5 -7
  11. package/dist/backend/c/walkers.js.map +1 -1
  12. package/dist/backend/external-c.d.ts +33 -0
  13. package/dist/backend/external-c.js +51 -0
  14. package/dist/backend/external-c.js.map +1 -0
  15. package/dist/backend/link-plan.d.ts +37 -0
  16. package/dist/backend/link-plan.js +26 -0
  17. package/dist/backend/link-plan.js.map +1 -0
  18. package/dist/backend/linker.d.ts +22 -0
  19. package/dist/backend/linker.js +236 -0
  20. package/dist/backend/linker.js.map +1 -0
  21. package/dist/backend/llvm/dyn.js +7 -0
  22. package/dist/backend/llvm/dyn.js.map +1 -1
  23. package/dist/backend/llvm/emitter.js +34 -7
  24. package/dist/backend/llvm/emitter.js.map +1 -1
  25. package/dist/backend/llvm/expr-containers.js +68 -54
  26. package/dist/backend/llvm/expr-containers.js.map +1 -1
  27. package/dist/backend/llvm/expr-context.d.ts +1 -1
  28. package/dist/backend/llvm/expr-dispatch.js +2 -0
  29. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  30. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  31. package/dist/backend/llvm/expr-primitives.js +20 -0
  32. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  33. package/dist/backend/llvm/expr-stream-bridges.js +25 -1
  34. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  35. package/dist/backend/llvm/walkers.js +31 -4
  36. package/dist/backend/llvm/walkers.js.map +1 -1
  37. package/dist/backend/native-codegen.d.ts +8 -1
  38. package/dist/backend/native-codegen.js +39 -25
  39. package/dist/backend/native-codegen.js.map +1 -1
  40. package/dist/backend/native-codegen.test.js +42 -4
  41. package/dist/backend/native-codegen.test.js.map +1 -1
  42. package/dist/backend/native-link-info.d.ts +1 -1
  43. package/dist/backend/native-link-info.js +42 -18
  44. package/dist/backend/native-link-info.js.map +1 -1
  45. package/dist/backend/native-toolchain.test.js +5 -1
  46. package/dist/backend/native-toolchain.test.js.map +1 -1
  47. package/dist/backend/runtime-pack-targets.test.d.ts +1 -0
  48. package/dist/backend/runtime-pack-targets.test.js +54 -0
  49. package/dist/backend/runtime-pack-targets.test.js.map +1 -0
  50. package/dist/backend/runtime-pack.d.ts +5 -30
  51. package/dist/backend/runtime-pack.js +46 -141
  52. package/dist/backend/runtime-pack.js.map +1 -1
  53. package/dist/backend/runtime-pack.test.js +49 -14
  54. package/dist/backend/runtime-pack.test.js.map +1 -1
  55. package/dist/backend/targets.d.ts +63 -17
  56. package/dist/backend/targets.js +251 -35
  57. package/dist/backend/targets.js.map +1 -1
  58. package/dist/backend/targets.test.js +27 -5
  59. package/dist/backend/targets.test.js.map +1 -1
  60. package/dist/coverage/surface-manifest.js +10 -1
  61. package/dist/coverage/surface-manifest.js.map +1 -1
  62. package/dist/frontend/lowering/array-values.d.ts +8 -0
  63. package/dist/frontend/lowering/array-values.js +60 -0
  64. package/dist/frontend/lowering/array-values.js.map +1 -0
  65. package/dist/frontend/lowering/lower-array-sort.d.ts +22 -0
  66. package/dist/frontend/lowering/lower-array-sort.js +619 -0
  67. package/dist/frontend/lowering/lower-array-sort.js.map +1 -0
  68. package/dist/frontend/lowering/lower-builtins.js +164 -4
  69. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  70. package/dist/frontend/lowering/lower-calls.d.ts +3 -4
  71. package/dist/frontend/lowering/lower-calls.js +260 -27
  72. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  73. package/dist/frontend/lowering/lower-containers.js +728 -655
  74. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  75. package/dist/frontend/lowering/lower-exprs.d.ts +4 -0
  76. package/dist/frontend/lowering/lower-exprs.js +769 -101
  77. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  78. package/dist/frontend/lowering/lower-inspect.js +47 -33
  79. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  80. package/dist/frontend/lowering/lower-island.d.ts +5 -4
  81. package/dist/frontend/lowering/lower-island.js +10 -5
  82. package/dist/frontend/lowering/lower-island.js.map +1 -1
  83. package/dist/frontend/lowering/lower-server.js +10 -0
  84. package/dist/frontend/lowering/lower-server.js.map +1 -1
  85. package/dist/frontend/lowering/lower-stmts.js +302 -71
  86. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  87. package/dist/frontend/lowering/lowerer.d.ts +74 -2
  88. package/dist/frontend/lowering/lowerer.js +1087 -10
  89. package/dist/frontend/lowering/lowerer.js.map +1 -1
  90. package/dist/frontend/lowering/surfaces.d.ts +10 -2
  91. package/dist/frontend/lowering/surfaces.js +15 -3
  92. package/dist/frontend/lowering/surfaces.js.map +1 -1
  93. package/dist/index.d.ts +3 -3
  94. package/dist/index.js +45 -23
  95. package/dist/index.js.map +1 -1
  96. package/dist/ir/ir.d.ts +65 -11
  97. package/dist/ir/ir.js +25 -25
  98. package/dist/ir/ir.js.map +1 -1
  99. package/dist/ir/serialize.d.ts +1 -1
  100. package/dist/ir/serialize.js +1 -1
  101. package/dist/ir/validate.js +84 -37
  102. package/dist/ir/validate.js.map +1 -1
  103. package/dist/library/fence-eval.js +3 -1
  104. package/dist/library/fence-eval.js.map +1 -1
  105. package/dist/library/int-infer.js +12 -1
  106. package/dist/library/int-infer.js.map +1 -1
  107. package/dist/library/int-infer.test.js +4 -4
  108. package/dist/library/library-cache.test.js +5 -5
  109. package/dist/startup-cache.d.ts +9 -1
  110. package/dist/startup-cache.js +16 -1
  111. package/dist/startup-cache.js.map +1 -1
  112. package/package.json +17 -4
  113. package/surface-manifest.json +5 -5
@@ -0,0 +1,619 @@
1
+ import { BOOL, BYTES_U8, F64, JSVAL, arrayOf, funcOf, } from "../../ir/ir.js";
2
+ import { numLit, varRef } from "../../ir/build.js";
3
+ function readArrayLength(arrT, loc) {
4
+ return {
5
+ kind: "varDecl",
6
+ localId: "n.0",
7
+ init: {
8
+ kind: "arrIntrinsic",
9
+ method: "length",
10
+ receiver: { kind: "varRef", localId: "a.0", type: arrT, loc },
11
+ args: [],
12
+ type: F64,
13
+ loc,
14
+ },
15
+ loc,
16
+ };
17
+ }
18
+ /** A stable bottom-up merge sort built from existing IR nodes.
19
+ *
20
+ * The first implementation used insertion sort because it was compact and
21
+ * made the stable tie rule obvious. Its worst case was quadratic, though,
22
+ * which made an ordinary descending input unusable. This implementation
23
+ * snapshots the receiver, merges runs between two buffers, and copies the
24
+ * final snapshot back into the receiver. The boundary check skips a merge
25
+ * when adjacent runs are already ordered, so naturally ordered inputs use
26
+ * only a linear number of comparator calls; the buffer copies still do
27
+ * O(n log n) data movement. Arbitrary inputs have an O(n log n) bound.
28
+ *
29
+ * The snapshot is also important for sort mutation behavior: comparator
30
+ * calls see the values captured before sorting starts, while the final copy
31
+ * preserves Array.sort receiver identity. toSorted starts by copying the
32
+ * receiver and therefore leaves that receiver untouched. The merge schedule
33
+ * intentionally differs from V8 TimSort, so exact comparator call order and
34
+ * count parity is not claimed; stable results, comparator exceptions, and
35
+ * mutations of referenced values still follow the normal IR call/ownership
36
+ * rules. */
37
+ export function buildArraySortFn(name, elem, arity, copyFirst, undefinedTag, loc) {
38
+ const arrT = arrayOf(elem);
39
+ const fnT = funcOf([elem, elem].slice(0, arity), F64);
40
+ const a = varRef("a.0", arrT, loc);
41
+ const snapshot = varRef("snapshot.0", arrT, loc);
42
+ const src = varRef("src.0", arrT, loc);
43
+ const dst = varRef("dst.0", arrT, loc);
44
+ const n = varRef("n.0", F64, loc);
45
+ const valueCount = varRef("valueCount.0", F64, loc);
46
+ const undefinedCount = varRef("undefinedCount.0", F64, loc);
47
+ const width = varRef("width.0", F64, loc);
48
+ const start = varRef("start.0", F64, loc);
49
+ const mid = varRef("mid.0", F64, loc);
50
+ const right = varRef("right.0", F64, loc);
51
+ const left = varRef("left.0", F64, loc);
52
+ const r = varRef("r.0", F64, loc);
53
+ const k = varRef("k.0", F64, loc);
54
+ const i = varRef("i.0", F64, loc);
55
+ const j = varRef("j.0", F64, loc);
56
+ const state = varRef("state.0", F64, loc);
57
+ const add = (left, right) => ({ kind: "bin", op: "+", left, right, type: F64, loc });
58
+ const sub = (left, right) => ({ kind: "bin", op: "-", left, right, type: F64, loc });
59
+ const mul = (left, right) => ({ kind: "bin", op: "*", left, right, type: F64, loc });
60
+ const lt = (left, right) => ({ kind: "bin", op: "<", left, right, type: BOOL, loc });
61
+ const eq = (left, right) => ({ kind: "bin", op: "===", left, right, type: BOOL, loc });
62
+ const not = (value) => ({ kind: "unary", op: "!", operand: value, type: BOOL, loc });
63
+ const at = (index) => ({ kind: "arrayGet", arr: src, index, type: elem, loc });
64
+ const snapshotAt = (index) => ({ kind: "arrayGet", arr: snapshot, index, type: elem, loc });
65
+ const stateAt = (index) => ({ kind: "arrayState", arr: snapshot, index, type: F64, loc });
66
+ const stateIs = (value) => eq(state, numLit(value, loc));
67
+ const isUndefined = (value) => {
68
+ if (elem.kind === "union" && undefinedTag !== null) {
69
+ return {
70
+ kind: "unionIsTag",
71
+ unionId: elem.unionId,
72
+ tag: undefinedTag,
73
+ negated: false,
74
+ value,
75
+ type: BOOL,
76
+ loc,
77
+ };
78
+ }
79
+ if (elem.kind === "jsval") {
80
+ return {
81
+ kind: "jsOp",
82
+ op: "eq",
83
+ args: [
84
+ value,
85
+ { kind: "jsOp", op: "undefLit", args: [], type: JSVAL, loc },
86
+ ],
87
+ type: BOOL,
88
+ loc,
89
+ };
90
+ }
91
+ return null;
92
+ };
93
+ const shouldTakeRight = (leftValue, rightValue) => {
94
+ const compareGreater = {
95
+ kind: "bin",
96
+ op: ">",
97
+ left: {
98
+ kind: "callValue",
99
+ callee: varRef("f.0", fnT, loc),
100
+ args: [leftValue, rightValue].slice(0, arity),
101
+ type: F64,
102
+ loc,
103
+ },
104
+ right: numLit(0, loc),
105
+ type: BOOL,
106
+ loc,
107
+ };
108
+ const leftUndefined = isUndefined(leftValue);
109
+ const rightUndefined = isUndefined(rightValue);
110
+ return leftUndefined !== null && rightUndefined !== null
111
+ ? {
112
+ kind: "ternary",
113
+ cond: leftUndefined,
114
+ then: not(rightUndefined),
115
+ else_: {
116
+ kind: "ternary",
117
+ cond: rightUndefined,
118
+ then: { kind: "boolLit", value: false, type: BOOL, loc },
119
+ else_: compareGreater,
120
+ type: BOOL,
121
+ loc,
122
+ },
123
+ type: BOOL,
124
+ loc,
125
+ }
126
+ : compareGreater;
127
+ };
128
+ const copyRange = {
129
+ kind: "while",
130
+ cond: lt(k, right),
131
+ body: [
132
+ { kind: "varDecl", localId: "v.0", init: at(k), loc },
133
+ { kind: "arraySet", arr: dst, index: k, value: varRef("v.0", elem, loc), loc },
134
+ { kind: "assign", localId: "k.0", value: add(k, numLit(1, loc)), loc },
135
+ ],
136
+ loc,
137
+ };
138
+ const mergeBody = [
139
+ {
140
+ kind: "while",
141
+ cond: {
142
+ kind: "logical",
143
+ op: "&&",
144
+ left: lt(left, mid),
145
+ right: lt(r, right),
146
+ type: BOOL,
147
+ loc,
148
+ },
149
+ body: [
150
+ { kind: "varDecl", localId: "vL.0", init: at(left), loc },
151
+ { kind: "varDecl", localId: "vR.0", init: at(r), loc },
152
+ {
153
+ kind: "if",
154
+ cond: shouldTakeRight(varRef("vL.0", elem, loc), varRef("vR.0", elem, loc)),
155
+ then: [
156
+ { kind: "arraySet", arr: dst, index: k, value: varRef("vR.0", elem, loc), loc },
157
+ { kind: "assign", localId: "r.0", value: add(r, numLit(1, loc)), loc },
158
+ ],
159
+ else_: [
160
+ { kind: "arraySet", arr: dst, index: k, value: varRef("vL.0", elem, loc), loc },
161
+ { kind: "assign", localId: "left.0", value: add(left, numLit(1, loc)), loc },
162
+ ],
163
+ loc,
164
+ },
165
+ { kind: "assign", localId: "k.0", value: add(k, numLit(1, loc)), loc },
166
+ ],
167
+ loc,
168
+ },
169
+ {
170
+ kind: "while",
171
+ cond: lt(left, mid),
172
+ body: [
173
+ { kind: "varDecl", localId: "v.0", init: at(left), loc },
174
+ { kind: "arraySet", arr: dst, index: k, value: varRef("v.0", elem, loc), loc },
175
+ { kind: "assign", localId: "left.0", value: add(left, numLit(1, loc)), loc },
176
+ { kind: "assign", localId: "k.0", value: add(k, numLit(1, loc)), loc },
177
+ ],
178
+ loc,
179
+ },
180
+ {
181
+ kind: "while",
182
+ cond: lt(r, right),
183
+ body: [
184
+ { kind: "varDecl", localId: "v.0", init: at(r), loc },
185
+ { kind: "arraySet", arr: dst, index: k, value: varRef("v.0", elem, loc), loc },
186
+ { kind: "assign", localId: "r.0", value: add(r, numLit(1, loc)), loc },
187
+ { kind: "assign", localId: "k.0", value: add(k, numLit(1, loc)), loc },
188
+ ],
189
+ loc,
190
+ },
191
+ ];
192
+ const boundaryLeft = varRef("boundaryL.0", elem, loc);
193
+ const boundaryRight = varRef("boundaryR.0", elem, loc);
194
+ const mergeOrCopy = {
195
+ kind: "if",
196
+ cond: lt(mid, right),
197
+ then: [
198
+ { kind: "varDecl", localId: "boundaryL.0", init: at(sub(mid, numLit(1, loc))), loc },
199
+ { kind: "varDecl", localId: "boundaryR.0", init: at(mid), loc },
200
+ {
201
+ kind: "if",
202
+ cond: shouldTakeRight(boundaryLeft, boundaryRight),
203
+ then: mergeBody,
204
+ else_: [copyRange],
205
+ loc,
206
+ },
207
+ ],
208
+ else_: [copyRange],
209
+ loc,
210
+ };
211
+ const mergePass = {
212
+ kind: "for",
213
+ init: { kind: "varDecl", localId: "start.0", init: numLit(0, loc), loc },
214
+ cond: lt(start, valueCount),
215
+ update: { kind: "assign", localId: "start.0", value: add(start, add(width, width)), loc },
216
+ body: [
217
+ {
218
+ kind: "varDecl",
219
+ localId: "mid.0",
220
+ init: {
221
+ kind: "ternary",
222
+ cond: lt(add(start, width), valueCount),
223
+ then: add(start, width),
224
+ else_: valueCount,
225
+ type: F64,
226
+ loc,
227
+ },
228
+ loc,
229
+ },
230
+ {
231
+ kind: "varDecl",
232
+ localId: "right.0",
233
+ init: {
234
+ kind: "ternary",
235
+ cond: lt(add(add(start, width), width), valueCount),
236
+ then: add(add(start, width), width),
237
+ else_: valueCount,
238
+ type: F64,
239
+ loc,
240
+ },
241
+ loc,
242
+ },
243
+ { kind: "varDecl", localId: "left.0", init: start, loc },
244
+ { kind: "varDecl", localId: "r.0", init: mid, loc },
245
+ { kind: "varDecl", localId: "k.0", init: start, loc },
246
+ mergeOrCopy,
247
+ ],
248
+ loc,
249
+ };
250
+ const collect = {
251
+ kind: "for",
252
+ init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
253
+ cond: lt(i, n),
254
+ update: { kind: "assign", localId: "i.0", value: add(i, numLit(1, loc)), loc },
255
+ body: [
256
+ { kind: "varDecl", localId: "state.0", init: stateAt(i), loc },
257
+ {
258
+ kind: "if",
259
+ cond: stateIs(1),
260
+ then: [
261
+ { kind: "varDecl", localId: "v.0", init: snapshotAt(i), loc },
262
+ { kind: "arraySet", arr: src, index: valueCount, value: varRef("v.0", elem, loc), loc },
263
+ { kind: "assign", localId: "valueCount.0", value: add(valueCount, numLit(1, loc)), loc },
264
+ ],
265
+ else_: [
266
+ {
267
+ kind: "if",
268
+ cond: stateIs(2),
269
+ then: [{ kind: "assign", localId: "undefinedCount.0", value: add(undefinedCount, numLit(1, loc)), loc }],
270
+ else_: null,
271
+ loc,
272
+ },
273
+ ],
274
+ loc,
275
+ },
276
+ ],
277
+ loc,
278
+ };
279
+ const writeValues = {
280
+ kind: "for",
281
+ init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
282
+ cond: lt(i, valueCount),
283
+ update: { kind: "assign", localId: "i.0", value: add(i, numLit(1, loc)), loc },
284
+ body: [
285
+ { kind: "varDecl", localId: "v.0", init: at(i), loc },
286
+ { kind: "arraySet", arr: a, index: i, value: varRef("v.0", elem, loc), loc },
287
+ ],
288
+ loc,
289
+ };
290
+ const writeUndefined = {
291
+ kind: "for",
292
+ init: { kind: "varDecl", localId: "j.0", init: valueCount, loc },
293
+ cond: lt(j, copyFirst ? n : add(valueCount, undefinedCount)),
294
+ update: { kind: "assign", localId: "j.0", value: add(j, numLit(1, loc)), loc },
295
+ body: [{ kind: "arraySetUndefined", arr: a, index: j, loc }],
296
+ loc,
297
+ };
298
+ const deleteRemaining = {
299
+ kind: "for",
300
+ init: { kind: "varDecl", localId: "j.0", init: add(valueCount, undefinedCount), loc },
301
+ cond: lt(j, n),
302
+ update: { kind: "assign", localId: "j.0", value: add(j, numLit(1, loc)), loc },
303
+ body: [{ kind: "arrayDelete", arr: a, index: j, loc }],
304
+ loc,
305
+ };
306
+ const body = [
307
+ ...(copyFirst
308
+ ? [{
309
+ kind: "assign",
310
+ localId: "a.0",
311
+ value: {
312
+ kind: "arrIntrinsic",
313
+ method: "slice",
314
+ receiver: varRef("a.0", arrT, loc),
315
+ args: [],
316
+ type: arrT,
317
+ loc,
318
+ },
319
+ loc,
320
+ }]
321
+ : []),
322
+ readArrayLength(arrT, loc),
323
+ { kind: "varDecl", localId: "snapshot.0", init: { kind: "arrIntrinsic", method: "slice", receiver: a, args: [], type: arrT, loc }, loc },
324
+ { kind: "varDecl", localId: "src.0", init: { kind: "arrayLit", elems: [], type: arrT, loc }, loc },
325
+ { kind: "varDecl", localId: "valueCount.0", init: numLit(0, loc), loc },
326
+ { kind: "varDecl", localId: "undefinedCount.0", init: numLit(0, loc), loc },
327
+ collect,
328
+ { kind: "varDecl", localId: "dst.0", init: { kind: "arrayLit", elems: [], type: arrT, loc }, loc },
329
+ { kind: "varDecl", localId: "width.0", init: numLit(1, loc), loc },
330
+ {
331
+ kind: "while",
332
+ cond: lt(width, valueCount),
333
+ body: [
334
+ mergePass,
335
+ { kind: "varDecl", localId: "tmp.0", init: src, loc },
336
+ { kind: "assign", localId: "src.0", value: dst, loc },
337
+ { kind: "assign", localId: "dst.0", value: varRef("tmp.0", arrT, loc), loc },
338
+ { kind: "assign", localId: "width.0", value: mul(width, numLit(2, loc)), loc },
339
+ ],
340
+ loc,
341
+ },
342
+ writeValues,
343
+ writeUndefined,
344
+ ...(copyFirst ? [] : [deleteRemaining]),
345
+ { kind: "return", value: a, loc },
346
+ ];
347
+ return {
348
+ name,
349
+ params: [
350
+ { localId: "a.0", name: "a", type: arrT },
351
+ { localId: "f.0", name: "f", type: fnT },
352
+ ],
353
+ returnType: arrT,
354
+ locals: [
355
+ { id: "a.0", name: "a", type: arrT, mutable: true },
356
+ { id: "f.0", name: "f", type: fnT, mutable: true },
357
+ { id: "n.0", name: "n", type: F64, mutable: false },
358
+ { id: "snapshot.0", name: "snapshot", type: arrT, mutable: false },
359
+ { id: "src.0", name: "src", type: arrT, mutable: true },
360
+ { id: "dst.0", name: "dst", type: arrT, mutable: true },
361
+ { id: "valueCount.0", name: "valueCount", type: F64, mutable: true },
362
+ { id: "undefinedCount.0", name: "undefinedCount", type: F64, mutable: true },
363
+ { id: "state.0", name: "state", type: F64, mutable: false },
364
+ { id: "width.0", name: "width", type: F64, mutable: true },
365
+ { id: "start.0", name: "start", type: F64, mutable: true },
366
+ { id: "mid.0", name: "mid", type: F64, mutable: true },
367
+ { id: "right.0", name: "right", type: F64, mutable: true },
368
+ { id: "left.0", name: "left", type: F64, mutable: true },
369
+ { id: "r.0", name: "r", type: F64, mutable: true },
370
+ { id: "k.0", name: "k", type: F64, mutable: true },
371
+ { id: "i.0", name: "i", type: F64, mutable: true },
372
+ { id: "j.0", name: "j", type: F64, mutable: true },
373
+ { id: "tmp.0", name: "tmp", type: arrT, mutable: true },
374
+ { id: "v.0", name: "v", type: elem, mutable: false },
375
+ { id: "vL.0", name: "vL", type: elem, mutable: false },
376
+ { id: "vR.0", name: "vR", type: elem, mutable: false },
377
+ { id: "boundaryL.0", name: "boundaryL", type: elem, mutable: false },
378
+ { id: "boundaryR.0", name: "boundaryR", type: elem, mutable: false },
379
+ ],
380
+ body,
381
+ loc,
382
+ };
383
+ }
384
+ export function buildBytesSortFn(name, arity, hasComparator, loc) {
385
+ const bytesT = BYTES_U8;
386
+ const fnT = funcOf([F64, F64].slice(0, arity), F64);
387
+ const a = varRef("a.0", bytesT, loc);
388
+ const src = varRef("src.0", bytesT, loc);
389
+ const dst = varRef("dst.0", bytesT, loc);
390
+ const n = varRef("n.0", F64, loc);
391
+ const width = varRef("width.0", F64, loc);
392
+ const start = varRef("start.0", F64, loc);
393
+ const mid = varRef("mid.0", F64, loc);
394
+ const right = varRef("right.0", F64, loc);
395
+ const left = varRef("left.0", F64, loc);
396
+ const r = varRef("r.0", F64, loc);
397
+ const k = varRef("k.0", F64, loc);
398
+ const add = (left, right) => ({ kind: "bin", op: "+", left, right, type: F64, loc });
399
+ const sub = (left, right) => ({ kind: "bin", op: "-", left, right, type: F64, loc });
400
+ const mul = (left, right) => ({ kind: "bin", op: "*", left, right, type: F64, loc });
401
+ const lt = (left, right) => ({ kind: "bin", op: "<", left, right, type: BOOL, loc });
402
+ const at = (receiver, index) => ({
403
+ kind: "bytesIntrinsic",
404
+ method: "get",
405
+ receiver,
406
+ args: [index],
407
+ type: F64,
408
+ loc,
409
+ });
410
+ const shouldTakeRight = (leftValue, rightValue) => ({
411
+ kind: "bin",
412
+ op: ">",
413
+ left: hasComparator
414
+ ? {
415
+ kind: "callValue",
416
+ callee: varRef("f.0", fnT, loc),
417
+ args: [leftValue, rightValue].slice(0, arity),
418
+ type: F64,
419
+ loc,
420
+ }
421
+ : {
422
+ kind: "bin",
423
+ op: "-",
424
+ left: leftValue,
425
+ right: rightValue,
426
+ type: F64,
427
+ loc,
428
+ },
429
+ right: numLit(0, loc),
430
+ type: BOOL,
431
+ loc,
432
+ });
433
+ const copyRange = {
434
+ kind: "while",
435
+ cond: lt(k, right),
436
+ body: [
437
+ { kind: "varDecl", localId: "v.0", init: at(src, k), loc },
438
+ { kind: "bytesSet", arr: dst, index: k, value: varRef("v.0", F64, loc), loc },
439
+ { kind: "assign", localId: "k.0", value: add(k, numLit(1, loc)), loc },
440
+ ],
441
+ loc,
442
+ };
443
+ const mergeBody = [
444
+ {
445
+ kind: "while",
446
+ cond: {
447
+ kind: "logical",
448
+ op: "&&",
449
+ left: lt(left, mid),
450
+ right: lt(r, right),
451
+ type: BOOL,
452
+ loc,
453
+ },
454
+ body: [
455
+ { kind: "varDecl", localId: "vL.0", init: at(src, left), loc },
456
+ { kind: "varDecl", localId: "vR.0", init: at(src, r), loc },
457
+ {
458
+ kind: "if",
459
+ cond: shouldTakeRight(varRef("vL.0", F64, loc), varRef("vR.0", F64, loc)),
460
+ then: [
461
+ { kind: "bytesSet", arr: dst, index: k, value: varRef("vR.0", F64, loc), loc },
462
+ { kind: "assign", localId: "r.0", value: add(r, numLit(1, loc)), loc },
463
+ ],
464
+ else_: [
465
+ { kind: "bytesSet", arr: dst, index: k, value: varRef("vL.0", F64, loc), loc },
466
+ { kind: "assign", localId: "left.0", value: add(left, numLit(1, loc)), loc },
467
+ ],
468
+ loc,
469
+ },
470
+ { kind: "assign", localId: "k.0", value: add(k, numLit(1, loc)), loc },
471
+ ],
472
+ loc,
473
+ },
474
+ {
475
+ kind: "while",
476
+ cond: lt(left, mid),
477
+ body: [
478
+ { kind: "varDecl", localId: "v.0", init: at(src, left), loc },
479
+ { kind: "bytesSet", arr: dst, index: k, value: varRef("v.0", F64, loc), loc },
480
+ { kind: "assign", localId: "left.0", value: add(left, numLit(1, loc)), loc },
481
+ { kind: "assign", localId: "k.0", value: add(k, numLit(1, loc)), loc },
482
+ ],
483
+ loc,
484
+ },
485
+ {
486
+ kind: "while",
487
+ cond: lt(r, right),
488
+ body: [
489
+ { kind: "varDecl", localId: "v.0", init: at(src, r), loc },
490
+ { kind: "bytesSet", arr: dst, index: k, value: varRef("v.0", F64, loc), loc },
491
+ { kind: "assign", localId: "r.0", value: add(r, numLit(1, loc)), loc },
492
+ { kind: "assign", localId: "k.0", value: add(k, numLit(1, loc)), loc },
493
+ ],
494
+ loc,
495
+ },
496
+ ];
497
+ const mergeOrCopy = {
498
+ kind: "if",
499
+ cond: lt(mid, right),
500
+ then: [
501
+ { kind: "varDecl", localId: "boundaryL.0", init: at(src, sub(mid, numLit(1, loc))), loc },
502
+ { kind: "varDecl", localId: "boundaryR.0", init: at(src, mid), loc },
503
+ {
504
+ kind: "if",
505
+ cond: shouldTakeRight(varRef("boundaryL.0", F64, loc), varRef("boundaryR.0", F64, loc)),
506
+ then: mergeBody,
507
+ else_: [copyRange],
508
+ loc,
509
+ },
510
+ ],
511
+ else_: [copyRange],
512
+ loc,
513
+ };
514
+ const mergePass = {
515
+ kind: "for",
516
+ init: { kind: "varDecl", localId: "start.0", init: numLit(0, loc), loc },
517
+ cond: lt(start, n),
518
+ update: { kind: "assign", localId: "start.0", value: add(start, add(width, width)), loc },
519
+ body: [
520
+ {
521
+ kind: "varDecl",
522
+ localId: "mid.0",
523
+ init: {
524
+ kind: "ternary",
525
+ cond: lt(add(start, width), n),
526
+ then: add(start, width),
527
+ else_: n,
528
+ type: F64,
529
+ loc,
530
+ },
531
+ loc,
532
+ },
533
+ {
534
+ kind: "varDecl",
535
+ localId: "right.0",
536
+ init: {
537
+ kind: "ternary",
538
+ cond: lt(add(add(start, width), width), n),
539
+ then: add(add(start, width), width),
540
+ else_: n,
541
+ type: F64,
542
+ loc,
543
+ },
544
+ loc,
545
+ },
546
+ { kind: "varDecl", localId: "left.0", init: start, loc },
547
+ { kind: "varDecl", localId: "r.0", init: mid, loc },
548
+ { kind: "varDecl", localId: "k.0", init: start, loc },
549
+ mergeOrCopy,
550
+ ],
551
+ loc,
552
+ };
553
+ const params = [
554
+ { localId: "a.0", name: "a", type: bytesT },
555
+ ...(hasComparator ? [{ localId: "f.0", name: "f", type: fnT }] : []),
556
+ ];
557
+ const locals = [
558
+ { id: "a.0", name: "a", type: bytesT, mutable: true },
559
+ ...(hasComparator ? [{ id: "f.0", name: "f", type: fnT, mutable: true }] : []),
560
+ { id: "n.0", name: "n", type: F64, mutable: false },
561
+ { id: "src.0", name: "src", type: bytesT, mutable: true },
562
+ { id: "dst.0", name: "dst", type: bytesT, mutable: true },
563
+ { id: "width.0", name: "width", type: F64, mutable: true },
564
+ { id: "start.0", name: "start", type: F64, mutable: true },
565
+ { id: "mid.0", name: "mid", type: F64, mutable: true },
566
+ { id: "right.0", name: "right", type: F64, mutable: true },
567
+ { id: "left.0", name: "left", type: F64, mutable: true },
568
+ { id: "r.0", name: "r", type: F64, mutable: true },
569
+ { id: "k.0", name: "k", type: F64, mutable: true },
570
+ { id: "i.0", name: "i", type: F64, mutable: true },
571
+ { id: "tmp.0", name: "tmp", type: bytesT, mutable: true },
572
+ { id: "v.0", name: "v", type: F64, mutable: false },
573
+ { id: "vL.0", name: "vL", type: F64, mutable: false },
574
+ { id: "vR.0", name: "vR", type: F64, mutable: false },
575
+ { id: "boundaryL.0", name: "boundaryL", type: F64, mutable: false },
576
+ { id: "boundaryR.0", name: "boundaryR", type: F64, mutable: false },
577
+ ];
578
+ const slice = (receiver) => ({
579
+ kind: "bytesIntrinsic",
580
+ method: "slice",
581
+ receiver,
582
+ args: [],
583
+ type: bytesT,
584
+ loc,
585
+ });
586
+ const body = [
587
+ { kind: "assign", localId: "a.0", value: slice(a), loc },
588
+ { kind: "varDecl", localId: "n.0", init: { kind: "bytesIntrinsic", method: "length", receiver: a, args: [], type: F64, loc }, loc },
589
+ { kind: "varDecl", localId: "src.0", init: slice(a), loc },
590
+ { kind: "varDecl", localId: "dst.0", init: slice(a), loc },
591
+ { kind: "varDecl", localId: "width.0", init: numLit(1, loc), loc },
592
+ {
593
+ kind: "while",
594
+ cond: lt(width, n),
595
+ body: [
596
+ mergePass,
597
+ { kind: "varDecl", localId: "tmp.0", init: src, loc },
598
+ { kind: "assign", localId: "src.0", value: dst, loc },
599
+ { kind: "assign", localId: "dst.0", value: varRef("tmp.0", bytesT, loc), loc },
600
+ { kind: "assign", localId: "width.0", value: mul(width, numLit(2, loc)), loc },
601
+ ],
602
+ loc,
603
+ },
604
+ {
605
+ kind: "for",
606
+ init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
607
+ cond: lt(varRef("i.0", F64, loc), n),
608
+ update: { kind: "assign", localId: "i.0", value: add(varRef("i.0", F64, loc), numLit(1, loc)), loc },
609
+ body: [
610
+ { kind: "varDecl", localId: "v.0", init: at(src, varRef("i.0", F64, loc)), loc },
611
+ { kind: "bytesSet", arr: a, index: varRef("i.0", F64, loc), value: varRef("v.0", F64, loc), loc },
612
+ ],
613
+ loc,
614
+ },
615
+ { kind: "return", value: a, loc },
616
+ ];
617
+ return { name, params, returnType: bytesT, locals, body, loc };
618
+ }
619
+ //# sourceMappingURL=lower-array-sort.js.map