@scriptc/compiler 0.0.15 → 0.0.17

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 (37) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +5 -5
  2. package/dist/backend/cc.d.ts +4 -2
  3. package/dist/backend/cc.js +24 -7
  4. package/dist/backend/cc.js.map +1 -1
  5. package/dist/backend/emission/emit-exprs.js +5 -3
  6. package/dist/backend/emission/emit-exprs.js.map +1 -1
  7. package/dist/backend/llvm/emitter.js +1 -0
  8. package/dist/backend/llvm/emitter.js.map +1 -1
  9. package/dist/coverage/surface-manifest.js +27 -9
  10. package/dist/coverage/surface-manifest.js.map +1 -1
  11. package/dist/frontend/lowering/lower-builtins.js +6 -6
  12. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  13. package/dist/frontend/lowering/lower-calls.d.ts +4 -4
  14. package/dist/frontend/lowering/lower-calls.js +36 -11
  15. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  16. package/dist/frontend/lowering/lower-island.d.ts +2 -2
  17. package/dist/frontend/lowering/lower-island.js +2 -2
  18. package/dist/frontend/lowering/surfaces.d.ts +8 -0
  19. package/dist/frontend/lowering/surfaces.js +6 -0
  20. package/dist/frontend/lowering/surfaces.js.map +1 -1
  21. package/dist/frontend/shared.d.ts +4 -0
  22. package/dist/frontend/shared.js +9 -3
  23. package/dist/frontend/shared.js.map +1 -1
  24. package/dist/frontend/ts7/program.js +5 -4
  25. package/dist/frontend/ts7/program.js.map +1 -1
  26. package/dist/index.d.ts +7 -0
  27. package/dist/index.js +2 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/ir/nodes.d.ts +13 -16
  30. package/dist/ir/nodes.js +1 -0
  31. package/dist/ir/nodes.js.map +1 -1
  32. package/dist/ir/validate.js +1 -0
  33. package/dist/ir/validate.js.map +1 -1
  34. package/dist/library/fence-eval.js +9 -1
  35. package/dist/library/fence-eval.js.map +1 -1
  36. package/package.json +2 -2
  37. package/surface-manifest.json +3 -3
@@ -458,10 +458,10 @@ export declare function lowerDefaultToStringCall(L: Lowerer, call: ts.CallExpres
458
458
  * member spellings (`x.hasOwnProperty(...)` and `x['hasOwnProperty'](...)`
459
459
  * — JS resolves the two identically, so the element spelling routes here
460
460
  * from lowerCall's element-access hook):
461
- * - `n.toExponential()` / `n.toFixed()` with the fraction digits
462
- * OMITTED — the static runtime formatters (num.toExponential's
463
- * shortest-mantissa form, num.toFixed0's ties-up integer). The
464
- * explicit-digits forms keep their island/fence story.
461
+ * - `n.toExponential()` and both `n.toFixed()` forms — the static
462
+ * runtime formatters (num.toExponential's shortest-mantissa form,
463
+ * num.toFixed0's ties-up integer fast path, and num.toFixed's exact
464
+ * binary-value rounding for an explicit fractionDigits).
465
465
  * - `hasOwnProperty(lit)` on number/boolean receivers — the boxes own
466
466
  * NOTHING, so any key answers false (a compile-time constant; the
467
467
  * receiver must be effect-free since the constant elides it).
@@ -3583,13 +3583,11 @@ export function lowerCall(L, expr) {
3583
3583
  // Object.prototype.toString's default answer on records and
3584
3584
  // override-free program classes — "[object Object]", folded.
3585
3585
  lowerDefaultToStringCall(L, expr, expr.expression) ??
3586
- // The remaining primitive prototype statics — toExponential()/
3587
- // toFixed() digit-free, hasOwnProperty over literal keys. Before
3588
- // the island path (its table claims the explicit-digits forms);
3589
- // optional-chain spellings keep the chain machinery's paths.
3590
- (expr.expression.questionDotToken
3591
- ? null
3592
- : lowerPrimitiveProtoCall(L, expr, expr.expression.expression, expr.expression.name.text, L.checker.getSymbolAtLocation(expr.expression.name))) ??
3586
+ // The remaining primitive prototype statics — toExponential(),
3587
+ // both toFixed() forms, hasOwnProperty over literal keys. Before
3588
+ // the island path. Optional-chain spellings first enter the chain
3589
+ // machinery above, then re-enter here with a narrowed chainRecv.
3590
+ lowerPrimitiveProtoCall(L, expr, expr.expression.expression, expr.expression.name.text, L.checker.getSymbolAtLocation(expr.expression.name)) ??
3593
3591
  // hasOwnProperty on a program class CONSTRUCTOR — own statics are
3594
3592
  // compile-time-known, so a literal key folds to a constant.
3595
3593
  lowerClassHasOwnPropertyCall(L, expr, expr.expression) ??
@@ -4413,10 +4411,10 @@ function pureReceiverNode(node) {
4413
4411
  * member spellings (`x.hasOwnProperty(...)` and `x['hasOwnProperty'](...)`
4414
4412
  * — JS resolves the two identically, so the element spelling routes here
4415
4413
  * from lowerCall's element-access hook):
4416
- * - `n.toExponential()` / `n.toFixed()` with the fraction digits
4417
- * OMITTED — the static runtime formatters (num.toExponential's
4418
- * shortest-mantissa form, num.toFixed0's ties-up integer). The
4419
- * explicit-digits forms keep their island/fence story.
4414
+ * - `n.toExponential()` and both `n.toFixed()` forms — the static
4415
+ * runtime formatters (num.toExponential's shortest-mantissa form,
4416
+ * num.toFixed0's ties-up integer fast path, and num.toFixed's exact
4417
+ * binary-value rounding for an explicit fractionDigits).
4420
4418
  * - `hasOwnProperty(lit)` on number/boolean receivers — the boxes own
4421
4419
  * NOTHING, so any key answers false (a compile-time constant; the
4422
4420
  * receiver must be effect-free since the constant elides it).
@@ -4452,6 +4450,33 @@ export function lowerPrimitiveProtoCall(L, call, recv, name, memberSym) {
4452
4450
  const fn = name === "toExponential" ? "num.toExponential" : "num.toFixed0";
4453
4451
  return { kind: "libCall", fn, args: [operand], type: STRING, loc };
4454
4452
  }
4453
+ if (name === "toFixed" && recvKind === "f64" && call.arguments.length === 1) {
4454
+ const operand = L.lowerExpr(recv);
4455
+ let digits = L.lowerExpr(call.arguments[0]);
4456
+ // The optional parameter also admits undefined. A standalone,
4457
+ // side-effect-free undefined value is exactly the default 0; an
4458
+ // optional number preserves its evaluation and selects 0 at runtime
4459
+ // through the same narrowed nullish IR used by `digits ?? 0`.
4460
+ const zero = { kind: "numLit", value: 0, type: F64, loc: digits.loc };
4461
+ if ((digits.type.kind === "undefinedT" || digits.type.kind === "void") &&
4462
+ droppableStatic(digits)) {
4463
+ digits = zero;
4464
+ }
4465
+ else if (digits.type.kind === "union") {
4466
+ const def = L.unions.get(digits.type.unionId);
4467
+ if (def?.arms.every(isUnitType) && droppableStatic(digits)) {
4468
+ digits = zero;
4469
+ }
4470
+ else if (def?.arms.length === 2 &&
4471
+ def.arms.some((arm) => arm.kind === "f64") &&
4472
+ def.arms.some((arm) => arm.kind === "undefinedT")) {
4473
+ digits = { kind: "nullish", left: digits, right: zero, type: F64, loc: digits.loc };
4474
+ }
4475
+ }
4476
+ if (operand.type.kind !== "f64" || digits.type.kind !== "f64")
4477
+ return null;
4478
+ return { kind: "libCall", fn: "num.toFixed", args: [operand, digits], type: STRING, loc };
4479
+ }
4455
4480
  // Number.prototype.toLocaleString("en-US") — the spec makes it
4456
4481
  // NumberFormat(locale).format(this), so the en-US embedded formatter
4457
4482
  // answers exactly. The unlowered forms fence by NAME: no locale (the