@scriptc/compiler 0.1.5 → 0.1.7

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 (139) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +0 -1
  2. package/ambient/scriptc.d.ts +13 -5
  3. package/dist/backend/c/c-emitter.d.ts +5 -0
  4. package/dist/backend/c/c-emitter.js +15 -0
  5. package/dist/backend/c/c-emitter.js.map +1 -1
  6. package/dist/backend/c/exprs.js +81 -9
  7. package/dist/backend/c/exprs.js.map +1 -1
  8. package/dist/backend/c/stmts.js +25 -1
  9. package/dist/backend/c/stmts.js.map +1 -1
  10. package/dist/backend/c/walkers.js +2 -3
  11. package/dist/backend/c/walkers.js.map +1 -1
  12. package/dist/backend/debug-symbols.d.ts +8 -0
  13. package/dist/backend/debug-symbols.js +52 -0
  14. package/dist/backend/debug-symbols.js.map +1 -0
  15. package/dist/backend/link-plan.d.ts +1 -0
  16. package/dist/backend/link-plan.js +2 -0
  17. package/dist/backend/link-plan.js.map +1 -1
  18. package/dist/backend/linker.js +8 -0
  19. package/dist/backend/linker.js.map +1 -1
  20. package/dist/backend/llvm/blocks.d.ts +2 -0
  21. package/dist/backend/llvm/blocks.js +18 -2
  22. package/dist/backend/llvm/blocks.js.map +1 -1
  23. package/dist/backend/llvm/debug-info.d.ts +32 -0
  24. package/dist/backend/llvm/debug-info.js +203 -0
  25. package/dist/backend/llvm/debug-info.js.map +1 -0
  26. package/dist/backend/llvm/dyn.js +4 -10
  27. package/dist/backend/llvm/dyn.js.map +1 -1
  28. package/dist/backend/llvm/emitter.d.ts +2 -0
  29. package/dist/backend/llvm/emitter.js +49 -4
  30. package/dist/backend/llvm/emitter.js.map +1 -1
  31. package/dist/backend/llvm/expr-containers.js +28 -2
  32. package/dist/backend/llvm/expr-containers.js.map +1 -1
  33. package/dist/backend/llvm/expr-dynamic.js +10 -0
  34. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  35. package/dist/backend/llvm/lib-filesystem.js +37 -0
  36. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  37. package/dist/backend/llvm/lib-process.js +4 -3
  38. package/dist/backend/llvm/lib-process.js.map +1 -1
  39. package/dist/backend/llvm/lib-shared.js +9 -0
  40. package/dist/backend/llvm/lib-shared.js.map +1 -1
  41. package/dist/backend/llvm/split.js +4 -1
  42. package/dist/backend/llvm/split.js.map +1 -1
  43. package/dist/backend/llvm/split.test.js +26 -1
  44. package/dist/backend/llvm/split.test.js.map +1 -1
  45. package/dist/backend/native-toolchain.js +58 -8
  46. package/dist/backend/native-toolchain.js.map +1 -1
  47. package/dist/backend/native-toolchain.test.js +10 -0
  48. package/dist/backend/native-toolchain.test.js.map +1 -1
  49. package/dist/backend/source-locations.d.ts +12 -0
  50. package/dist/backend/source-locations.js +32 -0
  51. package/dist/backend/source-locations.js.map +1 -0
  52. package/dist/backend/source-locations.test.d.ts +1 -0
  53. package/dist/backend/source-locations.test.js +16 -0
  54. package/dist/backend/source-locations.test.js.map +1 -0
  55. package/dist/coverage/surface-manifest.js +6 -1
  56. package/dist/coverage/surface-manifest.js.map +1 -1
  57. package/dist/diagnostics/diagnostic.d.ts +4 -0
  58. package/dist/diagnostics/diagnostic.js +12 -0
  59. package/dist/diagnostics/diagnostic.js.map +1 -1
  60. package/dist/executable/executable-cache.js +28 -4
  61. package/dist/executable/executable-cache.js.map +1 -1
  62. package/dist/executable/executable-cache.test.js +23 -0
  63. package/dist/executable/executable-cache.test.js.map +1 -1
  64. package/dist/frontend/arguments-usage.d.ts +6 -0
  65. package/dist/frontend/arguments-usage.js +40 -0
  66. package/dist/frontend/arguments-usage.js.map +1 -0
  67. package/dist/frontend/binding-source.d.ts +4 -0
  68. package/dist/frontend/binding-source.js +18 -0
  69. package/dist/frontend/binding-source.js.map +1 -0
  70. package/dist/frontend/lowering/array-indexed-mutation.d.ts +8 -0
  71. package/dist/frontend/lowering/array-indexed-mutation.js +176 -0
  72. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -0
  73. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +7 -0
  74. package/dist/frontend/lowering/containers/string-and-regexp.js +190 -13
  75. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  76. package/dist/frontend/lowering/expressions/object-literals.js +13 -8
  77. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  78. package/dist/frontend/lowering/expressions/optional-chains.d.ts +5 -6
  79. package/dist/frontend/lowering/expressions/optional-chains.js +7 -6
  80. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  81. package/dist/frontend/lowering/indexed-comparison.d.ts +6 -0
  82. package/dist/frontend/lowering/indexed-comparison.js +30 -0
  83. package/dist/frontend/lowering/indexed-comparison.js.map +1 -0
  84. package/dist/frontend/lowering/lower-builtins.d.ts +1 -1
  85. package/dist/frontend/lowering/lower-builtins.js +21 -10
  86. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  87. package/dist/frontend/lowering/lower-calls.d.ts +2 -9
  88. package/dist/frontend/lowering/lower-calls.js +406 -40
  89. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  90. package/dist/frontend/lowering/lower-classes.js +3 -27
  91. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  92. package/dist/frontend/lowering/lower-containers.d.ts +8 -2
  93. package/dist/frontend/lowering/lower-containers.js +454 -104
  94. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  95. package/dist/frontend/lowering/lower-exprs.js +134 -18
  96. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  97. package/dist/frontend/lowering/lower-island.d.ts +1 -1
  98. package/dist/frontend/lowering/lower-island.js +1 -1
  99. package/dist/frontend/lowering/lower-modules.js +19 -8
  100. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  101. package/dist/frontend/lowering/lower-stmts.js +4 -37
  102. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  103. package/dist/frontend/lowering/lowerer.js +14 -3
  104. package/dist/frontend/lowering/lowerer.js.map +1 -1
  105. package/dist/frontend/lowering/surfaces.d.ts +3 -1
  106. package/dist/frontend/lowering/surfaces.js +50 -7
  107. package/dist/frontend/lowering/surfaces.js.map +1 -1
  108. package/dist/frontend/program.d.ts +5 -0
  109. package/dist/frontend/program.js +216 -32
  110. package/dist/frontend/program.js.map +1 -1
  111. package/dist/frontend/program.test.d.ts +1 -0
  112. package/dist/frontend/program.test.js +117 -0
  113. package/dist/frontend/program.test.js.map +1 -0
  114. package/dist/frontend/type-mapper.d.ts +4 -2
  115. package/dist/frontend/type-mapper.js +249 -186
  116. package/dist/frontend/type-mapper.js.map +1 -1
  117. package/dist/frontend/type-mapper.test.d.ts +1 -0
  118. package/dist/frontend/type-mapper.test.js +86 -0
  119. package/dist/frontend/type-mapper.test.js.map +1 -0
  120. package/dist/index.d.ts +2 -1
  121. package/dist/index.js +7 -2
  122. package/dist/index.js.map +1 -1
  123. package/dist/ir/analysis.js +4 -2
  124. package/dist/ir/analysis.js.map +1 -1
  125. package/dist/ir/ir.d.ts +33 -14
  126. package/dist/ir/ir.js +5 -1
  127. package/dist/ir/ir.js.map +1 -1
  128. package/dist/ir/validate.js +57 -31
  129. package/dist/ir/validate.js.map +1 -1
  130. package/dist/ir/validate.test.js +17 -0
  131. package/dist/ir/validate.test.js.map +1 -1
  132. package/dist/library/compiler-self-identity.d.ts +1 -1
  133. package/dist/library/compiler-self-identity.js +31 -15
  134. package/dist/library/compiler-self-identity.js.map +1 -1
  135. package/dist/library/compiler-self-identity.test.d.ts +1 -0
  136. package/dist/library/compiler-self-identity.test.js +93 -0
  137. package/dist/library/compiler-self-identity.test.js.map +1 -0
  138. package/package.json +17 -17
  139. package/surface-manifest.json +155 -4
@@ -0,0 +1,40 @@
1
+ import * as ts from "./ts7/adapter.js";
2
+ /** Whether an identifier in a function body reads the runtime arguments object. */
3
+ function isArgumentsRead(id) {
4
+ const parent = id.parent;
5
+ // A shorthand object property reads its value, but other `name` positions
6
+ // declare a binding or spell a property (including `o.arguments`).
7
+ if (ts.isShorthandPropertyAssignment(parent))
8
+ return true;
9
+ if (parent.name === id)
10
+ return false;
11
+ if (ts.isBindingElement(parent) && parent.propertyName === id)
12
+ return false;
13
+ if (ts.isLabeledStatement(parent) && parent.label === id)
14
+ return false;
15
+ if ((ts.isBreakStatement(parent) || ts.isContinueStatement(parent)) && parent.label === id)
16
+ return false;
17
+ return true;
18
+ }
19
+ /** Does this function's own body read `arguments`? Nested plain functions and
20
+ * methods own theirs; arrows inherit the enclosing one. */
21
+ export function bodyReadsArguments(fn) {
22
+ if (fn.body === undefined)
23
+ return false;
24
+ let found = false;
25
+ // Iterative walking preserves the frontend's nesting fence on deep trees.
26
+ ts.walkPreorder(fn.body, (node) => {
27
+ if (ts.isTypeNode(node))
28
+ return "skip";
29
+ if (ts.isIdentifier(node) && node.text === "arguments" && isArgumentsRead(node)) {
30
+ found = true;
31
+ return "stop";
32
+ }
33
+ if (ts.isFunctionLike(node) && !ts.isArrowFunction(node) && node !== fn) {
34
+ return "skip";
35
+ }
36
+ return undefined;
37
+ });
38
+ return found;
39
+ }
40
+ //# sourceMappingURL=arguments-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arguments-usage.js","sourceRoot":"","sources":["../../src/frontend/arguments-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEvC,mFAAmF;AACnF,SAAS,eAAe,CAAC,EAAiB;IACxC,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC;IACzB,0EAA0E;IAC1E,mEAAmE;IACnE,IAAI,EAAE,CAAC,6BAA6B,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,IAAK,MAAuC,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACvE,IAAI,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,YAAY,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACvE,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACzG,OAAO,IAAI,CAAC;AACd,CAAC;AAED;2DAC2D;AAC3D,MAAM,UAAU,kBAAkB,CAAC,EAAkC;IACnE,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,0EAA0E;IAC1E,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;QAChC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,MAAM,CAAC;QACvC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAChF,KAAK,GAAG,IAAI,CAAC;YACb,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;YACxE,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { IrBindingSource } from "../ir/ir.js";
2
+ import * as ts from "./ts7/adapter.js";
3
+ /** Preserve source scopes before lowering flattens bindings and control flow. */
4
+ export declare function bindingSource(name: ts.Node): IrBindingSource;
@@ -0,0 +1,18 @@
1
+ import * as ts from "./ts7/adapter.js";
2
+ import { locOf } from "./program.js";
3
+ /** Preserve source scopes before lowering flattens bindings and control flow. */
4
+ export function bindingSource(name) {
5
+ let functionScoped = false;
6
+ for (let node = name.parent; node; node = node.parent) {
7
+ if (ts.isVariableDeclarationList(node)) {
8
+ functionScoped = (node.flags & ts.NodeFlags.BlockScoped) === 0;
9
+ }
10
+ if (ts.isFunctionLike(node) || ts.isSourceFile(node) ||
11
+ (!functionScoped && (ts.isBlock(node) || ts.isCaseBlock(node) ||
12
+ ts.isForStatement(node) || ts.isForOfStatement(node) || ts.isForInStatement(node) || ts.isCatchClause(node)))) {
13
+ return { loc: locOf(name), scope: locOf(node) };
14
+ }
15
+ }
16
+ return { loc: locOf(name), scope: locOf(name) };
17
+ }
18
+ //# sourceMappingURL=binding-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding-source.js","sourceRoot":"","sources":["../../src/frontend/binding-source.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,iFAAiF;AACjF,MAAM,UAAU,aAAa,CAAC,IAAa;IACzC,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACtD,IAAI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,cAAc,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;YAClD,CAAC,CAAC,cAAc,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;gBAC3D,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAClH,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type IrExpr, type IrType, type SrcLoc } from "../../ir/ir.js";
2
+ import type { Lowerer } from "./lowerer.js";
3
+ export declare function lowerArrayFill(lowerer: Lowerer, receiver: IrExpr, value: IrExpr | null, writeUndefined: boolean, start: IrExpr, end: IrExpr, arrType: IrType & {
4
+ kind: "array";
5
+ }, loc: SrcLoc): IrExpr;
6
+ export declare function lowerArrayCopyWithin(lowerer: Lowerer, receiver: IrExpr, target: IrExpr, start: IrExpr, end: IrExpr, arrType: IrType & {
7
+ kind: "array";
8
+ }, loc: SrcLoc): IrExpr;
@@ -0,0 +1,176 @@
1
+ import { BOOL, F64 } from "../../ir/ir.js";
2
+ import { numLit, varRef } from "../../ir/build.js";
3
+ import { typeKey } from "../type-mapper.js";
4
+ import { arrayValueStore } from "./array-values.js";
5
+ const add = (left, right, loc) => ({ kind: "bin", op: "+", left, right, type: F64, loc });
6
+ const sub = (left, right, loc) => ({ kind: "bin", op: "-", left, right, type: F64, loc });
7
+ const lt = (left, right, loc) => ({ kind: "bin", op: "<", left, right, type: BOOL, loc });
8
+ const eq = (left, right, loc) => ({ kind: "bin", op: "===", left, right, type: BOOL, loc });
9
+ const math = (fn, args, loc) => ({ kind: "libCall", fn: `math.${fn}`, args, type: F64, loc });
10
+ const lengthOf = (arr, loc) => ({ kind: "arrIntrinsic", method: "length", receiver: arr, args: [], type: F64, loc });
11
+ function relativeIndex(position, length, loc) {
12
+ const integer = {
13
+ kind: "ternary",
14
+ cond: { kind: "libCall", fn: "num.isNaN", args: [position], type: BOOL, loc },
15
+ then: numLit(0, loc),
16
+ else_: math("trunc", [position], loc),
17
+ type: F64,
18
+ loc,
19
+ };
20
+ return {
21
+ kind: "ternary",
22
+ cond: lt(integer, numLit(0, loc), loc),
23
+ then: math("max", [add(length, integer, loc), numLit(0, loc)], loc),
24
+ else_: math("min", [integer, length], loc),
25
+ type: F64,
26
+ loc,
27
+ };
28
+ }
29
+ export function lowerArrayFill(lowerer, receiver, value, writeUndefined, start, end, arrType, loc) {
30
+ const valueType = writeUndefined ? F64 : value.type;
31
+ const key = "indexed:fill:" + typeKey(arrType.elem) + ":" + typeKey(valueType) + ":" + writeUndefined;
32
+ let name = lowerer.arrHofHelpers.get(key);
33
+ if (!name) {
34
+ name = "%arr.fill." + lowerer.arrHofHelpers.size;
35
+ lowerer.arrHofHelpers.set(key, name);
36
+ const a = varRef("a.0", arrType, loc);
37
+ const n = varRef("n.0", F64, loc);
38
+ const i = varRef("i.0", F64, loc);
39
+ const body = writeUndefined
40
+ ? [{ kind: "arraySetUndefined", arr: a, index: i, loc }]
41
+ : [arrayValueStore(lowerer, a, i, varRef("v.0", valueType, loc), arrType.elem, loc)];
42
+ lowerer.liftedFns.push({
43
+ name,
44
+ params: [
45
+ { localId: "a.0", name: "a", type: arrType },
46
+ { localId: "v.0", name: "v", type: valueType },
47
+ { localId: "start.0", name: "start", type: F64 },
48
+ { localId: "end.0", name: "end", type: F64 },
49
+ ],
50
+ returnType: arrType,
51
+ locals: [
52
+ { id: "a.0", name: "a", type: arrType, mutable: true },
53
+ { id: "v.0", name: "v", type: valueType, mutable: false },
54
+ { id: "start.0", name: "start", type: F64, mutable: false },
55
+ { id: "end.0", name: "end", type: F64, mutable: false },
56
+ { id: "n.0", name: "n", type: F64, mutable: false },
57
+ { id: "from.0", name: "from", type: F64, mutable: false },
58
+ { id: "until.0", name: "until", type: F64, mutable: false },
59
+ { id: "i.0", name: "i", type: F64, mutable: true },
60
+ ],
61
+ body: [
62
+ { kind: "varDecl", localId: "n.0", init: lengthOf(a, loc), loc },
63
+ { kind: "varDecl", localId: "from.0", init: relativeIndex(varRef("start.0", F64, loc), n, loc), loc },
64
+ { kind: "varDecl", localId: "until.0", init: relativeIndex(varRef("end.0", F64, loc), n, loc), loc },
65
+ {
66
+ kind: "for",
67
+ init: { kind: "varDecl", localId: "i.0", init: varRef("from.0", F64, loc), loc },
68
+ cond: lt(i, varRef("until.0", F64, loc), loc),
69
+ update: { kind: "assign", localId: "i.0", value: add(i, numLit(1, loc), loc), loc },
70
+ body,
71
+ loc,
72
+ },
73
+ { kind: "return", value: a, loc },
74
+ ],
75
+ loc,
76
+ });
77
+ }
78
+ const valueArg = value && writeUndefined
79
+ ? { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: value, loc }], result: numLit(0, loc), type: F64, loc }
80
+ : value ?? numLit(0, loc);
81
+ return { kind: "call", callee: name, args: [receiver, valueArg, start, end], type: arrType, loc };
82
+ }
83
+ export function lowerArrayCopyWithin(lowerer, receiver, target, start, end, arrType, loc) {
84
+ const key = "indexed:copyWithin:" + typeKey(arrType.elem);
85
+ let name = lowerer.arrHofHelpers.get(key);
86
+ if (!name) {
87
+ name = "%arr.copyWithin." + lowerer.arrHofHelpers.size;
88
+ lowerer.arrHofHelpers.set(key, name);
89
+ const a = varRef("a.0", arrType, loc);
90
+ const n = varRef("n.0", F64, loc);
91
+ const dst = varRef("targetIndex.0", F64, loc);
92
+ const src = varRef("startIndex.0", F64, loc);
93
+ const last = varRef("endIndex.0", F64, loc);
94
+ const remaining = varRef("count.0", F64, loc);
95
+ const step = varRef("direction.0", F64, loc);
96
+ const from = varRef("from.0", F64, loc);
97
+ const to = varRef("to.0", F64, loc);
98
+ const state = varRef("state.0", F64, loc);
99
+ const backwards = {
100
+ kind: "logical", op: "&&", left: lt(src, dst, loc),
101
+ right: lt(dst, add(src, remaining, loc), loc), type: BOOL, loc,
102
+ };
103
+ const offset = {
104
+ kind: "ternary", cond: lt(step, numLit(0, loc), loc),
105
+ then: sub(remaining, numLit(1, loc), loc), else_: numLit(0, loc), type: F64, loc,
106
+ };
107
+ lowerer.liftedFns.push({
108
+ name,
109
+ params: [
110
+ { localId: "a.0", name: "a", type: arrType },
111
+ { localId: "target.0", name: "target", type: F64 },
112
+ { localId: "start.0", name: "start", type: F64 },
113
+ { localId: "end.0", name: "end", type: F64 },
114
+ ],
115
+ returnType: arrType,
116
+ locals: [
117
+ { id: "a.0", name: "a", type: arrType, mutable: true },
118
+ { id: "target.0", name: "target", type: F64, mutable: false },
119
+ { id: "start.0", name: "start", type: F64, mutable: false },
120
+ { id: "end.0", name: "end", type: F64, mutable: false },
121
+ { id: "n.0", name: "n", type: F64, mutable: false },
122
+ { id: "targetIndex.0", name: "targetIndex", type: F64, mutable: false },
123
+ { id: "startIndex.0", name: "startIndex", type: F64, mutable: false },
124
+ { id: "endIndex.0", name: "endIndex", type: F64, mutable: false },
125
+ { id: "count.0", name: "count", type: F64, mutable: true },
126
+ { id: "direction.0", name: "direction", type: F64, mutable: false },
127
+ { id: "from.0", name: "from", type: F64, mutable: true },
128
+ { id: "to.0", name: "to", type: F64, mutable: true },
129
+ { id: "state.0", name: "state", type: F64, mutable: false },
130
+ { id: "value.0", name: "value", type: arrType.elem, mutable: false },
131
+ ],
132
+ body: [
133
+ { kind: "varDecl", localId: "n.0", init: lengthOf(a, loc), loc },
134
+ { kind: "varDecl", localId: "targetIndex.0", init: relativeIndex(varRef("target.0", F64, loc), n, loc), loc },
135
+ { kind: "varDecl", localId: "startIndex.0", init: relativeIndex(varRef("start.0", F64, loc), n, loc), loc },
136
+ { kind: "varDecl", localId: "endIndex.0", init: relativeIndex(varRef("end.0", F64, loc), n, loc), loc },
137
+ {
138
+ kind: "varDecl", localId: "count.0",
139
+ init: {
140
+ kind: "ternary", cond: eq(src, dst, loc), then: numLit(0, loc),
141
+ else_: math("min", [math("max", [sub(last, src, loc), numLit(0, loc)], loc), sub(n, dst, loc)], loc),
142
+ type: F64, loc,
143
+ }, loc,
144
+ },
145
+ { kind: "varDecl", localId: "direction.0", init: { kind: "ternary", cond: backwards, then: numLit(-1, loc), else_: numLit(1, loc), type: F64, loc }, loc },
146
+ { kind: "varDecl", localId: "from.0", init: add(src, offset, loc), loc },
147
+ { kind: "varDecl", localId: "to.0", init: add(dst, offset, loc), loc },
148
+ {
149
+ kind: "while", cond: lt(numLit(0, loc), remaining, loc),
150
+ body: [
151
+ { kind: "varDecl", localId: "state.0", init: { kind: "arrayState", arr: a, index: from, type: F64, loc }, loc },
152
+ {
153
+ kind: "if", cond: eq(state, numLit(0, loc), loc),
154
+ then: [{ kind: "arrayDelete", arr: a, index: to, loc }],
155
+ else_: [{
156
+ kind: "if", cond: eq(state, numLit(2, loc), loc),
157
+ then: [{ kind: "arraySetUndefined", arr: a, index: to, loc }],
158
+ else_: [
159
+ { kind: "varDecl", localId: "value.0", init: { kind: "arrayGet", arr: a, index: from, type: arrType.elem, loc }, loc },
160
+ { kind: "arraySet", arr: a, index: to, value: varRef("value.0", arrType.elem, loc), loc },
161
+ ], loc,
162
+ }], loc,
163
+ },
164
+ { kind: "assign", localId: "from.0", value: add(from, step, loc), loc },
165
+ { kind: "assign", localId: "to.0", value: add(to, step, loc), loc },
166
+ { kind: "assign", localId: "count.0", value: sub(remaining, numLit(1, loc), loc), loc },
167
+ ], loc,
168
+ },
169
+ { kind: "return", value: a, loc },
170
+ ],
171
+ loc,
172
+ });
173
+ }
174
+ return { kind: "call", callee: name, args: [receiver, target, start, end], type: arrType, loc };
175
+ }
176
+ //# sourceMappingURL=array-indexed-mutation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array-indexed-mutation.js","sourceRoot":"","sources":["../../../src/frontend/lowering/array-indexed-mutation.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,13 @@
1
1
  import * as ts from "../../ts7/adapter.js";
2
2
  import { IrExpr } from "../../../ir/ir.js";
3
3
  import type { Lowerer } from "../lowerer.js";
4
+ /** Split evaluates its arguments before converting the receiver, limit, and
5
+ * separator, in that order. An undefined separator returns the whole string
6
+ * unless ToUint32(limit) is zero; the string-separator intrinsic handles the
7
+ * remaining split loop. */
8
+ export declare function lowerStringSplitCall(lowerer: Lowerer, call: ts.CallExpression, receiver: IrExpr, receiverNode: ts.Node, argumentNodes: readonly ts.Expression[]): IrExpr;
9
+ /** Relative string indexing and code-point decoding over the UTF-16 intrinsics. */
10
+ export declare function lowerStringIndexCall(lowerer: Lowerer, call: ts.CallExpression, method: "at" | "codePointAt", receiver: IrExpr, receiverNode: ts.Node, argumentNodes: readonly ts.Expression[]): IrExpr;
4
11
  /** Pad arguments are evaluated before receiver/length coercion, while fill
5
12
  * conversion runs only if padding is needed. One helper keeps that order for
6
13
  * member calls and direct String.prototype calls alike. */
@@ -1,15 +1,107 @@
1
1
  import * as ts from "../../ts7/adapter.js";
2
- import { BOOL, F64, STRING, arrayOf, isUnitType, typeEquals, typeKey } from "../../../ir/ir.js";
2
+ import { BOOL, DYN, F64, STRING, UNDEFINED_T, arrayOf, isUnitType, typeEquals, typeKey } from "../../../ir/ir.js";
3
3
  import { numLit, strLit, varRef } from "../../../ir/build.js";
4
4
  import { locOf } from "../../program.js";
5
5
  import { nodeThrowExpr, own } from "../lowerer.js";
6
6
  import { isRequireMainFilename } from "../expressions/optional-chains.js";
7
- import { STR_METHODS } from "../surfaces.js";
7
+ import { STRING_INDEX_METHODS, STR_METHODS } from "../surfaces.js";
8
8
  import { coerceStringSearchValue, defaultAfterUndefined, lowerOptionalArgument, lowerPositionArgument, lowerStaticallyUndefinedArgument, lowerStringSearchArgument, positionNumber } from "../optional-arguments.js";
9
9
  function lowerSplitLimitArg(lowerer, node, loc) {
10
10
  const defaultValue = { kind: "numLit", value: 4294967295, type: F64, loc };
11
11
  return node ? lowerOptionalArgument(lowerer, node, F64, defaultValue) : defaultValue;
12
12
  }
13
+ /** Split evaluates its arguments before converting the receiver, limit, and
14
+ * separator, in that order. An undefined separator returns the whole string
15
+ * unless ToUint32(limit) is zero; the string-separator intrinsic handles the
16
+ * remaining split loop. */
17
+ export function lowerStringSplitCall(lowerer, call, receiver, receiverNode, argumentNodes) {
18
+ const loc = locOf(call);
19
+ if (argumentNodes.length > 2 || argumentNodes.some(ts.isSpreadElement)) {
20
+ return lowerer.noLowering(`.split with ${argumentNodes.length} arguments`, call);
21
+ }
22
+ const separatorNode = argumentNodes[0];
23
+ const undefinedSeparator = separatorNode ? lowerStaticallyUndefinedArgument(lowerer, separatorNode) : null;
24
+ const absent = !separatorNode || undefinedSeparator !== null;
25
+ let separator = absent
26
+ ? undefinedSeparator
27
+ ? defaultAfterUndefined(undefinedSeparator, strLit("undefined", loc))
28
+ : strLit("undefined", loc)
29
+ : lowerer.lowerExpr(separatorNode);
30
+ if (separator.type.kind === "nullT")
31
+ separator = defaultAfterUndefined(separator, strLit("null", loc));
32
+ const scalar = separator.type.kind === "string" || separator.type.kind === "f64" ||
33
+ separator.type.kind === "bool" || separator.type.kind === "bigint" ||
34
+ (separator.type.kind === "union" && (lowerer.unions.get(separator.type.unionId)?.arms.every((arm) => arm.kind === "string" || arm.kind === "f64" || arm.kind === "bool" ||
35
+ arm.kind === "bigint" || arm.kind === "nullT" || arm.kind === "undefinedT") ?? false));
36
+ if (!scalar) {
37
+ lowerer.unsupported("SC1090", separatorNode ?? call, `'.split()' on a '${lowerer.fmt(separator.type)}' separator (pass a string, or a regex literal)`);
38
+ }
39
+ const defaultLimit = numLit(4294967295, loc);
40
+ const suppliedLimit = lowerPositionArgument(lowerer, argumentNodes[1], defaultLimit);
41
+ const limit = suppliedLimit.type.kind === "record" && argumentNodes[1]
42
+ ? lowerer.coerceInto(argumentNodes[1], suppliedLimit, DYN) : suppliedLimit;
43
+ const resultType = arrayOf(STRING);
44
+ if (receiver.type.kind === "string" && separator.type.kind === "string" && limit.type.kind === "f64" && !absent) {
45
+ return { kind: "strIntrinsic", method: "split", receiver, args: [separator, limit], type: resultType, loc };
46
+ }
47
+ const key = `str.split:${receiver.type.kind === "union" ? typeKey(receiver.type) : receiver.type.kind}:${typeKey(separator.type)}:${typeKey(limit.type)}:${absent}`;
48
+ let helper = lowerer.widthHelpers.get(key);
49
+ if (!helper) {
50
+ helper = `%str.split.${lowerer.widthHelpers.size}`;
51
+ const values = [receiver, separator, limit];
52
+ const params = values.map((value, index) => ({ localId: `arg.${index}`, name: `arg${index}`, type: value.type }));
53
+ const rawReceiver = varRef("arg.0", receiver.type, loc);
54
+ const rawSeparator = varRef("arg.1", separator.type, loc);
55
+ const rawLimit = varRef("arg.2", limit.type, loc);
56
+ const stringReceiver = varRef("receiver.0", STRING, loc);
57
+ const numericLimit = varRef("limit.0", F64, loc);
58
+ const stringSeparator = varRef("separator.0", STRING, loc);
59
+ const undefinedTag = separator.type.kind === "union"
60
+ ? lowerer.unions.get(separator.type.unionId).arms.findIndex((arm) => arm.kind === "undefinedT") : -1;
61
+ const separatorIsUndefined = absent
62
+ ? { kind: "boolLit", value: true, type: BOOL, loc }
63
+ : undefinedTag >= 0 && separator.type.kind === "union"
64
+ ? { kind: "unionIsTag", unionId: separator.type.unionId, tag: undefinedTag, value: rawSeparator, negated: false, type: BOOL, loc }
65
+ : { kind: "boolLit", value: false, type: BOOL, loc };
66
+ const split = {
67
+ kind: "strIntrinsic", method: "split", receiver: stringReceiver,
68
+ args: [stringSeparator, numericLimit], type: resultType, loc,
69
+ };
70
+ const result = {
71
+ kind: "ternary",
72
+ cond: {
73
+ kind: "bin", op: "===",
74
+ left: { kind: "bin", op: ">>>", left: numericLimit, right: numLit(0, loc), type: F64, loc },
75
+ right: numLit(0, loc), type: BOOL, loc,
76
+ },
77
+ then: { kind: "arrayLit", elems: [], type: resultType, loc },
78
+ else_: {
79
+ kind: "ternary", cond: separatorIsUndefined,
80
+ then: { kind: "arrayLit", elems: [stringReceiver], type: resultType, loc },
81
+ else_: split, type: resultType, loc,
82
+ },
83
+ type: resultType, loc,
84
+ };
85
+ lowerer.widthHelpers.set(key, helper);
86
+ lowerer.liftedFns.push({
87
+ name: helper, params, returnType: resultType,
88
+ locals: [
89
+ ...params.map(param => ({ id: param.localId, name: param.name, type: param.type, mutable: false })),
90
+ { id: "receiver.0", name: "receiver", type: STRING, mutable: false },
91
+ { id: "limit.0", name: "limit", type: F64, mutable: false },
92
+ { id: "separator.0", name: "separator", type: STRING, mutable: false },
93
+ ],
94
+ body: [
95
+ { kind: "varDecl", localId: "receiver.0", init: lowerer.ensureString(rawReceiver, receiverNode), loc },
96
+ { kind: "varDecl", localId: "limit.0", init: positionNumber(lowerer, rawLimit, defaultLimit, argumentNodes[1] ?? call, "string split limit"), loc },
97
+ { kind: "varDecl", localId: "separator.0", init: lowerer.ensureString(rawSeparator, separatorNode ?? call), loc },
98
+ { kind: "return", value: result, loc },
99
+ ],
100
+ loc,
101
+ });
102
+ }
103
+ return { kind: "call", callee: helper, args: [receiver, separator, limit], type: resultType, loc };
104
+ }
13
105
  function lowerRegexSubject(lowerer, node, loc) {
14
106
  const absent = { kind: "strLit", value: "undefined", type: STRING, loc };
15
107
  if (!node)
@@ -35,6 +127,92 @@ function lowerMethodReceiver(lowerer, node, expected, member) {
35
127
  return lowered;
36
128
  return lowerer.coerceInto(node, lowered, expected);
37
129
  }
130
+ /** Relative string indexing and code-point decoding over the UTF-16 intrinsics. */
131
+ export function lowerStringIndexCall(lowerer, call, method, receiver, receiverNode, argumentNodes) {
132
+ const loc = locOf(call);
133
+ if (argumentNodes.length > 1 || argumentNodes.some(ts.isSpreadElement)) {
134
+ return lowerer.noLowering(`String.prototype.${method} with ${argumentNodes.length} arguments`, call);
135
+ }
136
+ const indexNode = argumentNodes[0];
137
+ let index = lowerPositionArgument(lowerer, indexNode, numLit(0, loc));
138
+ if (indexNode && (index.type.kind === "record" || index.type.kind === "array" || index.type.kind === "func")) {
139
+ index = lowerer.coerceInto(indexNode, index, DYN);
140
+ }
141
+ const valueType = method === "at" ? STRING : F64;
142
+ const resultType = lowerer.withUndefinedArmOf(valueType);
143
+ if (!resultType || resultType.kind !== "union")
144
+ return lowerer.noLowering(`String.prototype.${method} result`, call);
145
+ const undefinedTag = lowerer.armTag(resultType.unionId, UNDEFINED_T);
146
+ const valueTag = lowerer.armTag(resultType.unionId, valueType);
147
+ const key = `str.index:${method}:${typeKey(receiver.type)}:${typeKey(index.type)}`;
148
+ let helper = lowerer.widthHelpers.get(key);
149
+ if (!helper) {
150
+ helper = `%str.index.${lowerer.widthHelpers.size}`;
151
+ lowerer.widthHelpers.set(key, helper);
152
+ const rawReceiver = varRef("arg.0", receiver.type, loc);
153
+ const rawIndex = varRef("arg.1", index.type, loc);
154
+ const stringReceiver = varRef("receiver.0", STRING, loc);
155
+ const length = varRef("length.0", F64, loc);
156
+ const position = varRef("position.0", F64, loc);
157
+ const first = varRef("first.0", F64, loc);
158
+ const second = varRef("second.0", F64, loc);
159
+ const bin = (op, left, right) => ({ kind: "bin", op, left, right, type: op === "<" || op === ">=" || op === ">" ? BOOL : F64, loc });
160
+ const either = (left, right) => ({ kind: "logical", op: "||", left, right, type: BOOL, loc });
161
+ const wrap = (value) => ({ kind: "unionWrap", unionId: resultType.unionId, tag: valueTag, value, type: resultType, loc });
162
+ const miss = {
163
+ kind: "unionWrap", unionId: resultType.unionId, tag: undefinedTag,
164
+ value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc }, type: resultType, loc,
165
+ };
166
+ const numeric = positionNumber(lowerer, rawIndex, numLit(0, loc), indexNode ?? call, "string index");
167
+ const numericValue = varRef("numeric.0", F64, loc);
168
+ const body = [
169
+ { kind: "varDecl", localId: "receiver.0", init: lowerer.ensureString(rawReceiver, receiverNode), loc },
170
+ { kind: "varDecl", localId: "length.0", init: { kind: "strIntrinsic", method: "length", receiver: stringReceiver, args: [], type: F64, loc }, loc },
171
+ { kind: "varDecl", localId: "numeric.0", init: numeric, loc },
172
+ { kind: "varDecl", localId: "position.0", init: {
173
+ kind: "ternary", cond: { kind: "libCall", fn: "num.isNaN", args: [numericValue], type: BOOL, loc },
174
+ then: numLit(0, loc), else_: { kind: "libCall", fn: "math.trunc", args: [numericValue], type: F64, loc }, type: F64, loc,
175
+ }, loc },
176
+ ];
177
+ if (method === "at") {
178
+ body.push({ kind: "if", cond: bin("<", position, numLit(0, loc)),
179
+ then: [{ kind: "assign", localId: "position.0", value: bin("+", position, length), loc }], else_: null, loc });
180
+ }
181
+ body.push({ kind: "if", cond: either(bin("<", position, numLit(0, loc)), bin(">=", position, length)),
182
+ then: [{ kind: "return", value: miss, loc }], else_: null, loc });
183
+ if (method === "at") {
184
+ body.push({ kind: "return", value: wrap({ kind: "strIntrinsic", method: "charAt", receiver: stringReceiver, args: [position], type: STRING, loc }), loc });
185
+ }
186
+ else {
187
+ body.push({ kind: "varDecl", localId: "first.0", init: { kind: "strIntrinsic", method: "charCodeAt", receiver: stringReceiver, args: [position], type: F64, loc }, loc });
188
+ body.push({ kind: "if", cond: either(either(bin("<", first, numLit(0xd800, loc)), bin(">", first, numLit(0xdbff, loc))), bin(">=", bin("+", position, numLit(1, loc)), length)),
189
+ then: [{ kind: "return", value: wrap(first), loc }], else_: null, loc });
190
+ body.push({ kind: "varDecl", localId: "second.0", init: { kind: "strIntrinsic", method: "charCodeAt", receiver: stringReceiver, args: [bin("+", position, numLit(1, loc))], type: F64, loc }, loc });
191
+ body.push({ kind: "if", cond: either(bin("<", second, numLit(0xdc00, loc)), bin(">", second, numLit(0xdfff, loc))),
192
+ then: [{ kind: "return", value: wrap(first), loc }], else_: null, loc });
193
+ body.push({ kind: "return", value: wrap(bin("+", bin("+", bin("*", bin("-", first, numLit(0xd800, loc)), numLit(1024, loc)), bin("-", second, numLit(0xdc00, loc))), numLit(0x10000, loc))), loc });
194
+ }
195
+ lowerer.liftedFns.push({
196
+ name: helper,
197
+ params: [{ localId: "arg.0", name: "receiver", type: receiver.type }, { localId: "arg.1", name: "index", type: index.type }],
198
+ returnType: resultType,
199
+ locals: [
200
+ { id: "arg.0", name: "receiver", type: receiver.type, mutable: false },
201
+ { id: "arg.1", name: "index", type: index.type, mutable: false },
202
+ { id: "receiver.0", name: "stringReceiver", type: STRING, mutable: false },
203
+ { id: "length.0", name: "length", type: F64, mutable: false },
204
+ { id: "numeric.0", name: "numeric", type: F64, mutable: false },
205
+ { id: "position.0", name: "position", type: F64, mutable: method === "at" },
206
+ ...(method === "codePointAt" ? [
207
+ { id: "first.0", name: "first", type: F64, mutable: false },
208
+ { id: "second.0", name: "second", type: F64, mutable: false },
209
+ ] : []),
210
+ ],
211
+ body, loc,
212
+ });
213
+ }
214
+ return { kind: "call", callee: helper, args: [receiver, index], type: resultType, loc };
215
+ }
38
216
  function paddingFillString(lowerer, value, node) {
39
217
  const loc = value.loc;
40
218
  if (value.type.kind === "undefinedT" || value.type.kind === "void")
@@ -339,7 +517,8 @@ export function lowerStringMethodCall(lowerer, call, access, dynReceiver, argume
339
517
  if (dynReceiver === undefined && access.name.text === "localeCompare")
340
518
  return lowerLocaleCompareCall(lowerer, call, access);
341
519
  const entry = own(STR_METHODS, access.name.text);
342
- if (!entry)
520
+ const indexMethod = STRING_INDEX_METHODS.has(access.name.text) ? access.name.text : null;
521
+ if (!entry && !indexMethod)
343
522
  return null;
344
523
  // A validated dyn receiver (`pkg.name.replace(...)` on a JSON.parse
345
524
  // value) arrives pre-extracted through `dynReceiver`; its checker type
@@ -362,13 +541,19 @@ export function lowerStringMethodCall(lowerer, call, access, dynReceiver, argume
362
541
  }
363
542
  // The lib declares optional parameters beyond some lowered forms; fence
364
543
  // those arities instead of passing arguments the runtime doesn't take.
365
- if (argumentNodes.length < entry.minArgs || argumentNodes.length > entry.maxArgs) {
544
+ if (argumentNodes.length < (entry?.minArgs ?? 0) || argumentNodes.length > (entry?.maxArgs ?? 1)) {
366
545
  lowerer.noLowering(`.${access.name.text} with ${argumentNodes.length} argument${argumentNodes.length === 1 ? "" : "s"} on strings`, call);
367
546
  }
368
547
  const receiver = dynReceiver
369
548
  ? dynReceiver()
370
549
  : lowerMethodReceiver(lowerer, access.expression, STRING, access.name.text);
371
550
  const loc = locOf(call);
551
+ if (indexMethod)
552
+ return lowerStringIndexCall(lowerer, call, indexMethod, receiver, access.expression, argumentNodes);
553
+ if (!entry)
554
+ return null;
555
+ if (entry.method === "split")
556
+ return lowerStringSplitCall(lowerer, call, receiver, access.expression, argumentNodes);
372
557
  if (entry.method === "padStart" || entry.method === "padEnd") {
373
558
  return lowerStringPaddingCall(lowerer, call, entry.method, receiver, access.expression, argumentNodes);
374
559
  }
@@ -467,15 +652,7 @@ export function lowerStringMethodCall(lowerer, call, access, dynReceiver, argume
467
652
  }
468
653
  return { kind: "call", callee: helper, args: [receiver, ...args], type: entry.result, loc };
469
654
  }
470
- const args = entry.method === "split"
471
- ? [lowerer.lowerExpr(argumentNodes[0]), lowerSplitLimitArg(lowerer, argumentNodes[1], locOf(call))]
472
- : argumentNodes.map((a) => lowerer.lowerExpr(a));
473
- // split's separator must BE a string here (a regex argument was
474
- // claimed by lowerRegexMethodCall before this path) — the lib's
475
- // `string | RegExp` union has no lowering as a VALUE.
476
- if (entry.method === "split" && args[0].type.kind !== "string") {
477
- lowerer.unsupported("SC1090", argumentNodes[0], `'.split()' on a '${lowerer.fmt(args[0].type)}' separator (pass a string, or a regex literal)`);
478
- }
655
+ const args = argumentNodes.map((a) => lowerer.lowerExpr(a));
479
656
  return {
480
657
  kind: "strIntrinsic",
481
658
  method: entry.method,