gofront 1.7.0 → 1.9.0

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 (194) hide show
  1. package/README.md +14 -14
  2. package/package.json +10 -38
  3. package/src/backend/js/expressions.js +2060 -389
  4. package/src/backend/js/index.js +586 -174
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +936 -1644
  7. package/src/backend/js/statements.js +1349 -132
  8. package/src/backend/js/stdlib/index.js +51 -94
  9. package/src/backend/js/templ.js +67 -118
  10. package/src/backend/js/type-info.js +436 -0
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +80 -0
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +753 -872
  15. package/src/backend/wasm/emit-builtins.js +914 -237
  16. package/src/backend/wasm/emit-exprs.js +1456 -195
  17. package/src/backend/wasm/emit-maps.js +78 -380
  18. package/src/backend/wasm/emit-stmts.js +1659 -214
  19. package/src/backend/wasm/emit.js +614 -88
  20. package/src/backend/wasm/encode.js +43 -13
  21. package/src/backend/wasm/globals.js +491 -0
  22. package/src/backend/wasm/glue.js +2 -4
  23. package/src/backend/wasm/index.js +406 -3195
  24. package/src/backend/wasm/method-expr.js +392 -0
  25. package/src/backend/wasm/module-emitter.js +1615 -0
  26. package/src/backend/wasm/monomorph.js +164 -9
  27. package/src/backend/wasm/natives.js +596 -0
  28. package/src/backend/wasm/prescan.js +249 -0
  29. package/src/backend/wasm/prune-funcs.js +89 -0
  30. package/src/backend/wasm/stdlib/index.js +2 -37
  31. package/src/backend/wasm/stdlib/simd.js +293 -28
  32. package/src/backend/wasm/types.js +260 -27
  33. package/src/backend/wasm/variadic.js +93 -0
  34. package/src/backend/wasm/wat.js +47 -20
  35. package/src/{cli-core.js → cli/cli-core.js} +241 -11
  36. package/src/{test-runner.js → cli/test-runner.js} +188 -122
  37. package/src/{vendor.js → cli/vendor.js} +3 -4
  38. package/src/compiler.js +202 -386
  39. package/src/index.js +15 -169
  40. package/src/{lexer.js → lexer/lexer.js} +203 -62
  41. package/src/{templ-lexer.js → lexer/templ-lexer.js} +61 -18
  42. package/src/{tokens.js → lexer/tokens.js} +2 -0
  43. package/src/link/sourcemap.js +97 -0
  44. package/src/link/stdlib.js +737 -0
  45. package/src/link/type-names.js +148 -0
  46. package/src/link/wasm.js +318 -0
  47. package/src/lower/bounds.js +547 -0
  48. package/src/lower/boxing.js +1 -1
  49. package/src/lower/captures.js +267 -64
  50. package/src/lower/embedding.js +32 -3
  51. package/src/lower/errors-as.js +196 -0
  52. package/src/lower/fmt-formatters.js +905 -0
  53. package/src/lower/functions.js +2 -0
  54. package/src/lower/gen-types.js +274 -0
  55. package/src/lower/index.js +33 -19
  56. package/src/lower/json-codecs.js +1379 -0
  57. package/src/lower/ownership.js +47 -8
  58. package/src/lower/range.js +86 -1
  59. package/src/lower/reachability.js +150 -0
  60. package/src/lower/walk.js +12 -0
  61. package/src/parser/declarations.js +83 -15
  62. package/src/parser/expressions.js +110 -18
  63. package/src/parser/index.js +2 -1
  64. package/src/parser/statements.js +38 -22
  65. package/src/{templ-parser.js → parser/templ.js} +179 -17
  66. package/src/parser/types.js +70 -9
  67. package/src/resolver.js +21 -1
  68. package/src/typechecker/assignability.js +291 -19
  69. package/src/typechecker/const-fold.js +399 -0
  70. package/src/typechecker/constants.js +282 -0
  71. package/src/typechecker/expressions.js +1220 -183
  72. package/src/typechecker/index.js +659 -92
  73. package/src/typechecker/init-order.js +426 -0
  74. package/src/typechecker/operand-text.js +40 -0
  75. package/src/typechecker/resolve.js +613 -62
  76. package/src/typechecker/statements.js +212 -20
  77. package/src/typechecker/stdlib/excluded.js +902 -0
  78. package/src/typechecker/stdlib/index.js +38 -0
  79. package/src/typechecker/stdlib/simd.js +65 -15
  80. package/src/typechecker/termination.js +11 -2
  81. package/src/typechecker/types.js +268 -514
  82. package/stdlib/bytes/buffer.go +479 -0
  83. package/stdlib/bytes/bytes.go +1010 -0
  84. package/stdlib/bytes/reader.go +161 -0
  85. package/stdlib/cmp/cmp.go +65 -0
  86. package/stdlib/context/context.go +115 -0
  87. package/stdlib/crypto/rand/rand.go +34 -0
  88. package/stdlib/crypto/sha256/sha256.go +249 -0
  89. package/stdlib/encoding/base64/base64.go +331 -0
  90. package/stdlib/encoding/binary/binary.go +332 -0
  91. package/stdlib/encoding/hex/hex.go +140 -0
  92. package/stdlib/encoding/json/errors.go +31 -0
  93. package/stdlib/encoding/json/indent.go +71 -0
  94. package/stdlib/encoding/json/json.go +62 -0
  95. package/stdlib/encoding/json/number.go +12 -0
  96. package/stdlib/encoding/json/stream.go +173 -0
  97. package/stdlib/errors/errors.go +174 -0
  98. package/stdlib/fmt/errors.go +110 -0
  99. package/stdlib/fmt/format.go +732 -0
  100. package/stdlib/fmt/print.go +1232 -0
  101. package/stdlib/gom/gom.go +293 -0
  102. package/stdlib/hash/hash.go +53 -0
  103. package/stdlib/html/html.go +251 -0
  104. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  105. package/stdlib/internal/jsonrt/dec.go +871 -0
  106. package/stdlib/internal/jsonrt/enc.go +516 -0
  107. package/stdlib/internal/jsonrt/indent.go +135 -0
  108. package/stdlib/internal/jsonrt/number.go +27 -0
  109. package/stdlib/internal/jsonrt/reader.go +73 -0
  110. package/stdlib/internal/jsonrt/scanner.go +658 -0
  111. package/stdlib/io/io.go +502 -0
  112. package/stdlib/iter/iter.go +18 -0
  113. package/stdlib/maps/maps.go +131 -0
  114. package/stdlib/math/bits/bits.go +507 -0
  115. package/stdlib/math/extra.go +272 -0
  116. package/stdlib/math/math.go +439 -0
  117. package/stdlib/math/rand/rand.go +297 -0
  118. package/stdlib/os/os.go +93 -0
  119. package/stdlib/path/filepath/filepath.go +47 -0
  120. package/stdlib/path/path.go +394 -0
  121. package/stdlib/regexp/regexp.go +231 -0
  122. package/stdlib/slices/slices.go +526 -0
  123. package/stdlib/slices/sort.go +209 -0
  124. package/stdlib/slices/zsort_cmp.go +480 -0
  125. package/stdlib/slices/zsort_ordered.go +482 -0
  126. package/stdlib/sort/sort.go +500 -0
  127. package/stdlib/sort/zsort_func.go +480 -0
  128. package/stdlib/sort/zsort_iface.go +480 -0
  129. package/stdlib/strconv/float.go +1699 -0
  130. package/stdlib/strconv/isprint.go +752 -0
  131. package/stdlib/strconv/quote.go +526 -0
  132. package/stdlib/strconv/strconv.go +616 -0
  133. package/stdlib/strings/builder.go +95 -0
  134. package/stdlib/strings/reader.go +163 -0
  135. package/stdlib/strings/replacer.go +102 -0
  136. package/stdlib/strings/strings.go +807 -0
  137. package/stdlib/sync/sync.go +268 -0
  138. package/stdlib/testing/async_js.go +61 -0
  139. package/stdlib/testing/benchmark.go +297 -0
  140. package/stdlib/testing/testing.go +523 -0
  141. package/stdlib/time/duration.go +233 -0
  142. package/stdlib/time/format.go +745 -0
  143. package/stdlib/time/parse.go +790 -0
  144. package/stdlib/time/sleep_js.go +63 -0
  145. package/stdlib/time/time.go +834 -0
  146. package/stdlib/unicode/unicode.go +250 -0
  147. package/stdlib/unicode/utf8/utf8.go +464 -0
  148. package/src/backend/js/stdlib/base64.js +0 -12
  149. package/src/backend/js/stdlib/binary.js +0 -102
  150. package/src/backend/js/stdlib/bits.js +0 -46
  151. package/src/backend/js/stdlib/builder.js +0 -63
  152. package/src/backend/js/stdlib/bytes.js +0 -122
  153. package/src/backend/js/stdlib/errors.js +0 -44
  154. package/src/backend/js/stdlib/fmt.js +0 -178
  155. package/src/backend/js/stdlib/gom.js +0 -155
  156. package/src/backend/js/stdlib/hex.js +0 -17
  157. package/src/backend/js/stdlib/html.js +0 -20
  158. package/src/backend/js/stdlib/io.js +0 -137
  159. package/src/backend/js/stdlib/json.js +0 -972
  160. package/src/backend/js/stdlib/maps.js +0 -45
  161. package/src/backend/js/stdlib/math.js +0 -69
  162. package/src/backend/js/stdlib/os.js +0 -13
  163. package/src/backend/js/stdlib/path.js +0 -48
  164. package/src/backend/js/stdlib/rand.js +0 -32
  165. package/src/backend/js/stdlib/regexp.js +0 -54
  166. package/src/backend/js/stdlib/sha256.js +0 -12
  167. package/src/backend/js/stdlib/shared.js +0 -17
  168. package/src/backend/js/stdlib/simd.js +0 -24
  169. package/src/backend/js/stdlib/slices.js +0 -77
  170. package/src/backend/js/stdlib/sort.js +0 -30
  171. package/src/backend/js/stdlib/strconv.js +0 -74
  172. package/src/backend/js/stdlib/strings.js +0 -222
  173. package/src/backend/js/stdlib/sync.js +0 -13
  174. package/src/backend/js/stdlib/testing.js +0 -34
  175. package/src/backend/js/stdlib/time.js +0 -128
  176. package/src/backend/js/stdlib/unicode.js +0 -25
  177. package/src/backend/js/stdlib/utf8.js +0 -26
  178. package/src/backend/wasm/const-fold.js +0 -205
  179. package/src/backend/wasm/emit-stdlib.js +0 -13
  180. package/src/backend/wasm/stdlib/bytes.js +0 -5039
  181. package/src/backend/wasm/stdlib/core.js +0 -8903
  182. package/src/backend/wasm/stdlib/io.js +0 -2161
  183. package/src/backend/wasm/stdlib/packages.js +0 -2400
  184. package/src/backend/wasm/stdlib/pure.js +0 -720
  185. package/src/backend/wasm/stdlib/time.js +0 -1200
  186. package/src/typechecker/stdlib/core.js +0 -801
  187. package/src/typechecker/stdlib/extended.js +0 -914
  188. package/src/typechecker/stdlib.js +0 -22
  189. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  190. /package/src/{colors.js → cli/colors.js} +0 -0
  191. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  192. /package/src/{minifier.js → cli/minifier.js} +0 -0
  193. /package/src/{project-config.js → cli/project-config.js} +0 -0
  194. /package/src/{pwa.js → cli/pwa.js} +0 -0
@@ -1,12 +0,0 @@
1
- // src/backend/js/stdlib/base64.js
2
- // CodeGen for Go encoding/base64 package.
3
-
4
- export const base64Methods = {
5
- _genBase64(fn, a) {
6
- this.useHelper("base64");
7
- this.useHelper("error");
8
- const args = a();
9
- if (fn === "NewEncoding") return `__base64_make(${args[0]}, "=")`;
10
- return undefined;
11
- },
12
- };
@@ -1,102 +0,0 @@
1
- // src/backend/js/stdlib/binary.js
2
- // CodeGen for Go encoding/binary package.
3
-
4
- function sizeOfGoType(gt) {
5
- if (!gt) return -1;
6
- if (gt.kind === "basic") {
7
- switch (gt.name) {
8
- case "bool":
9
- case "int8":
10
- case "uint8":
11
- case "byte":
12
- return 1;
13
- case "int16":
14
- case "uint16":
15
- return 2;
16
- case "int32":
17
- case "uint32":
18
- case "float32":
19
- case "rune":
20
- return 4;
21
- case "int64":
22
- case "uint64":
23
- case "float64":
24
- case "int":
25
- case "uint":
26
- case "uintptr":
27
- return 8;
28
- default:
29
- return -1;
30
- }
31
- }
32
- if (gt.kind === "array" || gt.kind === "ArrayType") {
33
- const es = sizeOfGoType(gt.elem);
34
- const len = gt.len ?? gt.size ?? 0;
35
- return es > 0 ? es * len : -1;
36
- }
37
- if (
38
- gt.kind === "pointer" ||
39
- gt.kind === "PointerType" ||
40
- gt.kind === "StarExpr"
41
- ) {
42
- return sizeOfGoType(gt.base ?? gt.expr ?? gt.operand);
43
- }
44
- if (gt.kind === "struct" || gt.kind === "StructType") {
45
- let total = 0;
46
- if (gt.fields instanceof Map) {
47
- for (const fType of gt.fields.values()) {
48
- const s = sizeOfGoType(fType);
49
- if (s < 0) return -1;
50
- total += s;
51
- }
52
- return total;
53
- }
54
- }
55
- return -1;
56
- }
57
-
58
- export const binaryMethods = {
59
- _genBinary(fn, a, expr) {
60
- this.useHelper("binary");
61
- this.useHelper("error");
62
- const args = a();
63
- if (fn === "Read") {
64
- const targetType = expr?.args?.[2]?._type;
65
- const baseType = targetType?.base ?? targetType;
66
- const resolved =
67
- baseType?.kind === "named"
68
- ? (baseType.underlying ?? baseType)
69
- : baseType;
70
- const sz = sizeOfGoType(resolved);
71
- const typeTag =
72
- resolved?.name ??
73
- (resolved?.kind === "basic" ? resolved.name : (baseType?.name ?? ""));
74
- return `__binary_read(${args[0]}, ${args[1]}, ${args[2]}${sz > 0 ? `, ${sz}` : ", 0"}, "${typeTag}")`;
75
- }
76
- if (fn === "Write") {
77
- const targetType = expr?.args?.[2]?._type;
78
- const baseType = targetType?.base ?? targetType;
79
- const resolved =
80
- baseType?.kind === "named"
81
- ? (baseType.underlying ?? baseType)
82
- : baseType;
83
- const sz = sizeOfGoType(resolved);
84
- const typeTag =
85
- resolved?.name ??
86
- (resolved?.kind === "basic" ? resolved.name : (baseType?.name ?? ""));
87
- return `__binary_write(${args[0]}, ${args[1]}, ${args[2]}${sz > 0 ? `, ${sz}` : ", 0"}, "${typeTag}")`;
88
- }
89
- if (fn === "Size") {
90
- const sz = sizeOfGoType(expr?.args?.[0]?._type);
91
- if (sz >= 0) return `${sz}`;
92
- return `__binary_size(${args[0]})`;
93
- }
94
- if (fn === "AppendUint16")
95
- return `__binary_le.AppendUint16(${args[0]}, ${args[1]})`;
96
- if (fn === "AppendUint32")
97
- return `__binary_le.AppendUint32(${args[0]}, ${args[1]})`;
98
- if (fn === "AppendUint64")
99
- return `__binary_le.AppendUint64(${args[0]}, ${args[1]})`;
100
- return undefined;
101
- },
102
- };
@@ -1,46 +0,0 @@
1
- // src/backend/js/stdlib/bits.js
2
- // CodeGen for Go `math/bits` package.
3
-
4
- /** @typedef {import('../index.js').CodeGen} CodeGen */
5
-
6
- const BITS_MAP = {
7
- LeadingZeros32: ([x]) => `Math.clz32((${x}) >>> 0)`,
8
- TrailingZeros32: ([x]) =>
9
- `((() => { const v = (${x}) >>> 0; return v === 0 ? 32 : 31 - Math.clz32(v & -v); })())`,
10
- OnesCount32: ([x]) =>
11
- `((() => { let v = (${x}) >>> 0; v = v - ((v >>> 1) & 0x55555555); v = (v & 0x33333333) + ((v >>> 2) & 0x33333333); return (Math.imul((v + (v >>> 4)) & 0x0f0f0f0f, 0x01010101)) >>> 24; })())`,
12
- RotateLeft32: ([x, k]) =>
13
- `((() => { const s = (${k}) & 31; const v = (${x}) >>> 0; return ((v << s) | (v >>> ((32 - s) & 31))) >>> 0; })())`,
14
-
15
- LeadingZeros64: ([x]) =>
16
- `((() => { const v = BigInt.asUintN(64, BigInt(${x})); if (v === 0n) return 64; const hi = Number(v >> 32n); return hi !== 0 ? Math.clz32(hi) : 32 + Math.clz32(Number(v & 0xffffffffn)); })())`,
17
- TrailingZeros64: ([x]) =>
18
- `((() => { const v = BigInt.asUintN(64, BigInt(${x})); if (v === 0n) return 64; const lo = Number(v & 0xffffffffn); if (lo !== 0) return 31 - Math.clz32(lo & -lo); const hi = Number((v >> 32n) & 0xffffffffn); return 32 + (31 - Math.clz32(hi & -hi)); })())`,
19
- OnesCount64: ([x]) =>
20
- `((() => { let v = BigInt.asUintN(64, BigInt(${x})); let c = 0; while (v > 0n) { if (v & 1n) c++; v >>= 1n; } return c; })())`,
21
- RotateLeft64: ([x, k]) =>
22
- `((() => { const s = BigInt(${k}) & 63n; const v = BigInt.asUintN(64, BigInt(${x})); return Number(BigInt.asUintN(64, (v << s) | (v >> ((64n - s) & 63n)))); })())`,
23
-
24
- Len32: ([x]) => `((v => 32 - Math.clz32(v >>> 0))(${x}))`,
25
- Len64: ([x]) =>
26
- `((() => { const v = BigInt.asUintN(64, BigInt(${x})); if (v === 0n) return 0; const hi = Number(v >> 32n); return hi !== 0 ? 64 - Math.clz32(hi) : 32 - Math.clz32(Number(v & 0xffffffffn)); })())`,
27
- ReverseBytes16: ([x]) =>
28
- `((v => ((v & 0xff) << 8) | ((v >>> 8) & 0xff))((${x}) & 0xffff))`,
29
- ReverseBytes32: ([x]) =>
30
- `((v => (((v & 0xff) << 24) | ((v & 0xff00) << 8) | ((v >>> 8) & 0xff00) | ((v >>> 24) & 0xff)) >>> 0)((${x}) >>> 0))`,
31
- ReverseBytes64: ([x]) =>
32
- `((() => { const v = BigInt.asUintN(64, BigInt(${x})); let r = 0n; for (let i = 0n; i < 8n; i++) r = (r << 8n) | ((v >> (i * 8n)) & 0xffn); return Number(r); })())`,
33
- Reverse32: ([x]) =>
34
- `((() => { let v = (${x}) >>> 0; v = ((v >>> 1) & 0x55555555) | ((v & 0x55555555) << 1); v = ((v >>> 2) & 0x33333333) | ((v & 0x33333333) << 2); v = ((v >>> 4) & 0x0f0f0f0f) | ((v & 0x0f0f0f0f) << 4); v = ((v >>> 8) & 0x00ff00ff) | ((v & 0x00ff00ff) << 8); return ((v >>> 16) | (v << 16)) >>> 0; })())`,
35
- Reverse64: ([x]) =>
36
- `((() => { const rev32 = (v) => { v = ((v >>> 1) & 0x55555555) | ((v & 0x55555555) << 1); v = ((v >>> 2) & 0x33333333) | ((v & 0x33333333) << 2); v = ((v >>> 4) & 0x0f0f0f0f) | ((v & 0x0f0f0f0f) << 4); v = ((v >>> 8) & 0x00ff00ff) | ((v & 0x00ff00ff) << 8); return ((v >>> 16) | (v << 16)) >>> 0; }; const v = BigInt.asUintN(64, BigInt(${x})); const lo = Number(v & 0xffffffffn); const hi = Number((v >> 32n) & 0xffffffffn); return Number((BigInt(rev32(lo)) << 32n) | BigInt(rev32(hi))); })())`,
37
- };
38
-
39
- /** @type {ThisType<CodeGen>} */
40
- export const bitsMethods = {
41
- _genBits(fn, a) {
42
- const args = a();
43
- const gen = BITS_MAP[fn];
44
- return gen ? gen(args) : undefined;
45
- },
46
- };
@@ -1,63 +0,0 @@
1
- // CodeGen for `strings.Builder` and `bytes.Buffer` method calls.
2
-
3
- /** @typedef {import('../index.js').CodeGen} CodeGen */
4
-
5
- const BUILDER_STR = {
6
- WriteString: (b, a) =>
7
- `((__s) => { ${b}._buf += __s; return [new TextEncoder().encode(__s).length, null]; })(${a[0]})`,
8
- WriteByte: (b, a) => `(${b}._buf += String.fromCodePoint(${a[0]}), null)`,
9
- WriteRune: (b, a) =>
10
- `((cp) => { const r = (cp < 0 || cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff)) ? 0xfffd : cp; const s = String.fromCodePoint(r); ${b}._buf += s; return [new TextEncoder().encode(s).length, null]; })(${a[0]})`,
11
- Write: (b, a) =>
12
- `(${b}._buf += new TextDecoder().decode(new Uint8Array(${a[0]})), [${a[0]}.length, null])`,
13
- String: (b) => `${b}._buf`,
14
- Reset: (b) => `(${b}._buf = "")`,
15
- Len: (b) => `new TextEncoder().encode(${b}._buf).length`,
16
- Cap: (b) =>
17
- `Math.max(${b}._cap ?? 0, new TextEncoder().encode(${b}._buf).length)`,
18
- Grow: (b, a) =>
19
- `((n) => { if (n < 0) throw new Error("strings.Builder.Grow: negative count"); ${b}._cap = Math.max(${b}._cap ?? 0, new TextEncoder().encode(${b}._buf).length) + n; })(${a[0]})`,
20
- };
21
- const BUILDER_BYTES = {
22
- WriteString: (b, a) =>
23
- `((buf, s) => { const bytes = new TextEncoder().encode(s); for (let i = 0; i < bytes.length; i++) buf._buf.push(bytes[i]); return [bytes.length, null]; })(${b}, ${a[0]})`,
24
- WriteByte: (b, a) => `(${b}._buf.push(${a[0]}), null)`,
25
- WriteRune: (b, a) =>
26
- `((buf, cp) => { const r = (cp < 0 || cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff)) ? 0xfffd : cp; const bytes = new TextEncoder().encode(String.fromCodePoint(r)); for (let i = 0; i < bytes.length; i++) buf._buf.push(bytes[i]); return [bytes.length, null]; })(${b}, ${a[0]})`,
27
- Write: (b, a) =>
28
- `((buf, d) => { for (let i = 0; i < d.length; i++) buf._buf.push(d[i]); return [d.length, null]; })(${b}, ${a[0]})`,
29
- String: (b) => `new TextDecoder().decode(new Uint8Array(${b}._buf))`,
30
- Reset: (b) => `(${b}._buf = [])`,
31
- Read: (b, a) =>
32
- `((buf, p) => { if (buf._buf.length === 0) return [0, __io_eof]; const n = Math.min(p.length, buf._buf.length); for (let i = 0; i < n; i++) p[i] = buf._buf.shift(); return [n, null]; })(${b}, ${a[0]})`,
33
- };
34
- const BUILDER_COMMON = {
35
- Bytes: (b) => `new Uint8Array(${b}._buf)`,
36
- Len: (b) => `${b}._buf.length`,
37
- Cap: (b) => `Math.max(${b}._cap ?? 0, ${b}._buf.length)`,
38
- Grow: (b, a) =>
39
- `((n) => { if (n < 0) throw new Error("bytes.Buffer.Grow: negative count"); ${b}._cap = Math.max(${b}._cap ?? 0, ${b}._buf.length) + n; })(${a[0]})`,
40
- };
41
-
42
- /** @type {ThisType<CodeGen>} */
43
- export const builderMethods = {
44
- _genBuilderCall(typeName, method, expr) {
45
- const recv = expr.func.expr;
46
- const base = this._unboxWriter(this.genExpr(recv));
47
- const args = expr.args.map((a) => this.genExpr(a));
48
- if (method === "Read") {
49
- this.useHelper("ioEOF");
50
- this.useHelper("error");
51
- }
52
- const isStr = typeName === "strings.Builder";
53
- const table = isStr ? BUILDER_STR : BUILDER_BYTES;
54
- const gen = table[method] ?? BUILDER_COMMON[method];
55
- return gen ? gen(base, args) : undefined;
56
- },
57
-
58
- // Accepts a Builder/Buffer or a pointer box around one; evaluates `js` once.
59
- _unboxWriter(js) {
60
- if (/^[\w$.]+$/.test(js)) return `(${js}?.value ?? ${js})`;
61
- return `((__w) => __w?.value ?? __w)(${js})`;
62
- },
63
- };
@@ -1,122 +0,0 @@
1
- // CodeGen for Go `bytes` package.
2
-
3
- /** @typedef {import('../index.js').CodeGen} CodeGen */
4
-
5
- const __bs = `(b => typeof TextDecoder !== "undefined" ? new TextDecoder().decode(b instanceof Uint8Array ? b : new Uint8Array(b)) : String.fromCharCode.apply(null, b))`;
6
- const __sb = `(s => typeof TextEncoder !== "undefined" ? new TextEncoder().encode(s) : new Uint8Array([...s].map(c => c.charCodeAt(0))))`;
7
-
8
- const BYTES_DISPATCH = {
9
- Contains: (a) => `${__bs}(${a[0]}).includes(${__bs}(${a[1]}))`,
10
- HasPrefix: (a) =>
11
- `((b, p) => { for (let i = 0; i < p.length; i++) if (b[i] !== p[i]) return false; return b.length >= p.length; })(${a[0]}, ${a[1]})`,
12
- HasSuffix: (a) =>
13
- `((b, s) => { const off = b.length - s.length; if (off < 0) return false; for (let i = 0; i < s.length; i++) if (b[off + i] !== s[i]) return false; return true; })(${a[0]}, ${a[1]})`,
14
- Index: (a) => `${__bs}(${a[0]}).indexOf(${__bs}(${a[1]}))`,
15
- Count: (a) =>
16
- `((b, sep) => sep.length === 0 ? b.length + 1 : ${__bs}(b).split(${__bs}(sep)).length - 1)(${a[0]}, ${a[1]})`,
17
- Repeat: (a) => `${__sb}(${__bs}(${a[0]}).repeat(${a[1]}))`,
18
- Replace: (a) =>
19
- `((b, o, n, cnt) => { let str = ${__bs}(b), os = ${__bs}(o), nw = ${__bs}(n); if (cnt < 0) return ${__sb}(str.replaceAll(os, () => nw)); let r = ""; let i = 0; for (; cnt > 0; cnt--) { const j = str.indexOf(os, i); if (j < 0) break; r += str.slice(i, j) + nw; i = j + os.length; if (os.length === 0) { if (i >= str.length) break; r += str[i]; i++; } } return ${__sb}(r + str.slice(i)); })(${a[0]}, ${a[1]}, ${a[2]}, ${a[3]})`,
20
- ToUpper: (a) =>
21
- `new TextEncoder().encode(new TextDecoder().decode(new Uint8Array(${a[0]})).toUpperCase())`,
22
- ToLower: (a) =>
23
- `new TextEncoder().encode(new TextDecoder().decode(new Uint8Array(${a[0]})).toLowerCase())`,
24
- ToTitle: (a) =>
25
- `new TextEncoder().encode(new TextDecoder().decode(new Uint8Array(${a[0]})).toUpperCase())`,
26
- TrimSpace: (a) =>
27
- `new TextEncoder().encode(new TextDecoder().decode(new Uint8Array(${a[0]})).trim())`,
28
- Trim: (a) =>
29
- `((b, c) => { const s = new TextDecoder().decode(new Uint8Array(b)); const cs = new Set(Array.from(c)); const chars = Array.from(s); let l = 0, r = chars.length; while (l < r && cs.has(chars[l])) l++; while (r > l && cs.has(chars[r - 1])) r--; return new TextEncoder().encode(chars.slice(l, r).join("")); })(${a[0]}, ${a[1]})`,
30
- Equal: (a) =>
31
- `((a, b) => { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false; return true; })(${a[0]}, ${a[1]})`,
32
- Split: (a) => `${__bs}(${a[0]}).split(${__bs}(${a[1]})).map(p => ${__sb}(p))`,
33
- Join: (a) => `${__sb}(${a[0]}.map(p => ${__bs}(p)).join(${__bs}(${a[1]})))`,
34
- ReplaceAll: (a) =>
35
- `((b, o, n) => { const r = []; let i = 0; while (i <= b.length - o.length) { if (o.length > 0 && o.every((v, j) => b[i + j] === v)) { r.push(...n); i += o.length; } else { r.push(b[i++]); } } for (; i < b.length; i++) r.push(b[i]); return new Uint8Array(r); })(${a[0]}, ${a[1]}, ${a[2]})`,
36
- TrimPrefix: (a) =>
37
- `((b, p) => p.every((v, i) => b[i] === v) ? b.slice(p.length) : b.slice())(${a[0]}, ${a[1]})`,
38
- TrimSuffix: (a) =>
39
- `((b, s) => s.length && s.every((v, i) => b[b.length - s.length + i] === v) ? b.slice(0, -s.length) : b.slice())(${a[0]}, ${a[1]})`,
40
- TrimLeft: (a) =>
41
- `((b, c) => { const s = new TextDecoder().decode(new Uint8Array(b)); const cs = new Set(Array.from(c)); const chars = Array.from(s); let l = 0, r = chars.length; while (l < r && cs.has(chars[l])) l++; return new TextEncoder().encode(chars.slice(l, r).join("")); })(${a[0]}, ${a[1]})`,
42
- TrimRight: (a) =>
43
- `((b, c) => { const s = new TextDecoder().decode(new Uint8Array(b)); const cs = new Set(Array.from(c)); const chars = Array.from(s); let l = 0, r = chars.length; while (r > l && cs.has(chars[r - 1])) r--; return new TextEncoder().encode(chars.slice(l, r).join("")); })(${a[0]}, ${a[1]})`,
44
- TrimFunc: (a) =>
45
- `((b, f) => { const s = new TextDecoder().decode(new Uint8Array(b)); const chars = Array.from(s); let l = 0, r = chars.length; while (l < r && f(chars[l].codePointAt(0))) l++; while (r > l && f(chars[r - 1].codePointAt(0))) r--; return new TextEncoder().encode(chars.slice(l, r).join("")); })(${a[0]}, ${a[1]})`,
46
- IndexByte: (a) => `(${a[0]}).indexOf(${a[1]})`,
47
- LastIndex: (a) =>
48
- `((b, s) => { for (let i = b.length - s.length; i >= 0; i--) if (s.every((v, j) => b[i + j] === v)) return i; return -1; })(${a[0]}, ${a[1]})`,
49
- LastIndexByte: (a) => `(${a[0]}).lastIndexOf(${a[1]})`,
50
- Fields: (a) =>
51
- `((b) => { const s = new TextDecoder().decode(new Uint8Array(b ?? [])).trim(); return s === '' ? [] : s.split(/\\s+/).map(w => new TextEncoder().encode(w)); })(${a[0]})`,
52
- FieldsFunc: (a) =>
53
- `((b, fn) => { const s = new TextDecoder().decode(new Uint8Array(b ?? [])); const res = []; let cur = ""; for (const ch of s) { const cp = ch.codePointAt(0); if (fn(cp)) { if (cur.length > 0) { res.push(new TextEncoder().encode(cur)); cur = ""; } } else { cur += ch; } } if (cur.length > 0) res.push(new TextEncoder().encode(cur)); return res; })(${a[0]}, ${a[1]})`,
54
- Clone: (a) =>
55
- `(${a[0]} ? (${a[0]}.slice ? ${a[0]}.slice() : Array.from(${a[0]})) : null)`,
56
- Cut: (a) =>
57
- `((b, sep) => { for (let i = 0; i <= b.length - sep.length; i++) if (sep.every((v, j) => b[i + j] === v)) return [b.slice(0, i), b.slice(i + sep.length), true]; return [b.slice(), new Uint8Array(0), false]; })(${a[0]}, ${a[1]})`,
58
- ContainsAny: (a) =>
59
- `((b, chars) => { const s = new TextDecoder().decode(new Uint8Array(b)); for (const c of chars) if (s.includes(c)) return true; return false; })(${a[0]}, ${a[1]})`,
60
- ContainsRune: (a) =>
61
- `((b, r) => { const s = new TextDecoder().decode(new Uint8Array(b)); return s.includes(String.fromCodePoint(r < 0 || r > 0x10ffff || (r >= 0xd800 && r <= 0xdfff) ? 0xfffd : r)); })(${a[0]}, ${a[1]})`,
62
- Map: (a) =>
63
- `((f, b) => { const s = new TextDecoder().decode(new Uint8Array(b)); let res = ""; for (const c of s) { const r = f(c.codePointAt(0)); if (r >= 0) res += String.fromCodePoint(r); } return new TextEncoder().encode(res); })(${a[0]}, ${a[1]})`,
64
- SplitN: (a) =>
65
- `((b, sep, n) => {
66
- if (n === 0) return null;
67
- if (sep.length === 0) {
68
- if (n < 0 || b.length <= n) {
69
- const r = [];
70
- for (let k = 0; k < b.length; k++) r.push(b.slice(k, k + 1));
71
- return r;
72
- }
73
- const r = [];
74
- for (let k = 0; k < n - 1; k++) r.push(b.slice(k, k + 1));
75
- r.push(b.slice(n - 1));
76
- return r;
77
- }
78
- const findNext = (start) => {
79
- for (let k = start; k <= b.length - sep.length; k++) {
80
- let match = true;
81
- for (let l = 0; l < sep.length; l++) {
82
- if (b[k + l] !== sep[l]) { match = false; break; }
83
- }
84
- if (match) return k;
85
- }
86
- return -1;
87
- };
88
- if (n < 0) {
89
- const r = [];
90
- let i = 0;
91
- while (i <= b.length) {
92
- const j = findNext(i);
93
- if (j < 0) break;
94
- r.push(b.slice(i, j));
95
- i = j + sep.length;
96
- }
97
- r.push(b.slice(i));
98
- return r;
99
- }
100
- const r = [];
101
- let i = 0;
102
- for (let c = 1; c < n; c++) {
103
- const j = findNext(i);
104
- if (j < 0) break;
105
- r.push(b.slice(i, j));
106
- i = j + sep.length;
107
- }
108
- r.push(b.slice(i));
109
- return r;
110
- })(${a[0]}, ${a[1]}, ${a[2]})`,
111
- NewReader: (a) =>
112
- `((b) => ({ _src: b, _pos: 0, Read(p) { if (this._pos >= this._src.length) return [0, __io_eof]; const n = Math.min(p.length, this._src.length - this._pos); for (let i = 0; i < n; i++) p[i] = this._src[this._pos + i]; this._pos += n; return [n, null]; }, Len() { return Math.max(0, this._src.length - this._pos); }, Reset(b2) { this._src = b2; this._pos = 0; } }))(${a[0]})`,
113
- };
114
-
115
- /** @type {ThisType<CodeGen>} */
116
- export const bytesMethods = {
117
- _genBytes(fn, a) {
118
- if (fn === "NewReader") this.useHelper("ioEOF");
119
- const gen = BYTES_DISPATCH[fn];
120
- return gen ? gen(a()) : undefined;
121
- },
122
- };
@@ -1,44 +0,0 @@
1
- // CodeGen for Go `errors` package.
2
-
3
- /** @typedef {import('../index.js').CodeGen} CodeGen */
4
-
5
- /** @type {ThisType<CodeGen>} */
6
- export const errorsMethods = {
7
- _genErrors(fn, a, expr) {
8
- const args = a();
9
- if (fn === "New") {
10
- this.useHelper("error");
11
- return `__error(${args[0]})`;
12
- }
13
- if (fn === "Is") {
14
- this.useHelper("errorIs");
15
- return `__errorIs(${args[0]}, ${args[1]})`;
16
- }
17
- if (fn === "Unwrap") return `(${args[0]}?._cause ?? null)`;
18
- if (fn === "As") {
19
- this.useHelper("errorAs");
20
- const targetGoType = expr?.args?.[1]?._type;
21
- const baseGoType = targetGoType?.base ?? targetGoType;
22
- const concreteGoType = baseGoType?.base ?? baseGoType;
23
- const typeName = concreteGoType?.name;
24
- if (concreteGoType?.kind === "interface" || typeName === "error") {
25
- return `__errorAs(${args[0]}, ${args[1]}, (x) => x !== null && (typeof x === "object" ? typeof x.Error === "function" : true))`;
26
- }
27
- // Named non-struct error types sit in interfaces as boxes; store the raw value.
28
- const namedBox = this._namedBoxInfo(concreteGoType);
29
- if (namedBox) {
30
- return `__errorAs(${args[0]}, ${args[1]}, (x) => x instanceof ${namedBox.cls}, (x) => x.__gfUnbox())`;
31
- }
32
- if (typeName) {
33
- return `__errorAs(${args[0]}, ${args[1]}, (x) => (typeof ${typeName} === "function" && x instanceof ${typeName}) || x?.constructor?.name === "${typeName}" || x?.__struct === "${typeName}")`;
34
- }
35
- return `__errorAs(${args[0]}, ${args[1]})`;
36
- }
37
- if (fn === "Join") {
38
- this.useHelper("error");
39
- this.useHelper("errorJoin");
40
- return `__errorJoin(${args.join(", ")})`;
41
- }
42
- return undefined;
43
- },
44
- };
@@ -1,178 +0,0 @@
1
- // CodeGen for Go `fmt` package — installed onto CodeGen.prototype via stdlibGenMethods.
2
-
3
- /** @typedef {import('../index.js').CodeGen} CodeGen */
4
-
5
- const _SSCAN_LOOP =
6
- `let n = 0, err = null; for (let i = 0; i < ptrs.length && i < tokens.length; i++) { ` +
7
- `const item = tokens[i]; const t = typeof item === "object" && item !== null ? item.t : item; const verb = item?.verb; const p = ptrs[i]; ` +
8
- `if (verb === "%c") { p.value = t.codePointAt ? t.codePointAt(0) : t; } ` +
9
- `else if (verb === "%x" || verb === "%X") { const clean = t.replace(/^0[xX]/, ""); const v = parseInt(clean, 16); if (isNaN(v)) { err = __error("expected hex number"); break; } p.value = typeof p.value === "bigint" ? BigInt("0x" + clean) : v; } ` +
10
- `else if (verb === "%o") { const clean = t.replace(/^0[oO]?/, ""); const v = parseInt(clean, 8); if (isNaN(v)) { err = __error("expected octal number"); break; } p.value = typeof p.value === "bigint" ? BigInt("0o" + clean) : v; } ` +
11
- `else if (verb === "%b") { const clean = t.replace(/^0[bB]/, ""); const v = parseInt(clean, 2); if (isNaN(v)) { err = __error("expected binary number"); break; } p.value = typeof p.value === "bigint" ? BigInt("0b" + clean) : v; } ` +
12
- `else if (typeof p.value === "number") { const v = Number(t); if (Number.isNaN(v) || !/^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/.test(t)) { err = __error("expected number"); break; } p.value = v; } ` +
13
- `else if (typeof p.value === "bigint") { try { if (!/^[+-]?\\d+$/.test(t)) throw 1; p.value = BigInt(t); } catch { err = __error("expected integer"); break; } } ` +
14
- `else if (typeof p.value === "boolean") { const tl = String(t).toLowerCase(); if (tl === "true" || tl === "1" || tl === "t") p.value = true; else if (tl === "false" || tl === "0" || tl === "f") p.value = false; else { err = __error("expected boolean"); break; } } ` +
15
- `else p.value = t; n++; }`;
16
-
17
- /** @type {ThisType<CodeGen>} */
18
- export const fmtMethods = {
19
- _fmtArgJs(e) {
20
- const js = this.genExpr(e);
21
- const base =
22
- e?._type?.kind === "named" ? (e._type.underlying ?? e._type) : e?._type;
23
- return base?.kind === "slice" ? `(${js} ?? [])` : js;
24
- },
25
-
26
- _genFmt(fn, _a, expr) {
27
- const fmtArgs = expr.args
28
- .map((e, idx) => (idx === 0 ? this.genExpr(e) : this._fmtArgJs(e)))
29
- .join(", ");
30
- switch (fn) {
31
- case "Sprintf":
32
- this.useHelper("sprintf");
33
- return `__sprintf(${fmtArgs})`;
34
- case "Errorf": {
35
- this.useHelper("sprintf");
36
- this.useHelper("error");
37
- const fmtStr = expr.args[0];
38
- if (fmtStr?.kind === "BasicLit" && fmtStr.value?.includes("%w")) {
39
- const lastArg = this.genExpr(expr.args[expr.args.length - 1]);
40
- return `__error(__sprintf(${fmtArgs}), ${lastArg})`;
41
- }
42
- return `__error(__sprintf(${fmtArgs}))`;
43
- }
44
- case "Printf":
45
- this.useHelper("sprintf");
46
- return this._genStdoutWrite(`__sprintf(${fmtArgs})`);
47
- case "Print":
48
- this.useHelper("sprintf");
49
- return this._genStdoutWrite(this._genPrintOperands(expr, "", ""));
50
- case "Println":
51
- this.useHelper("sprintf");
52
- // console.log supplies the trailing newline.
53
- return `console.log(${this._genPrintOperands(expr, " ", "")})`;
54
- case "Fprintf":
55
- case "Fprintln":
56
- case "Fprint":
57
- return this._genFmtFprint(fn, expr);
58
- case "Sscan": {
59
- this.useHelper("error");
60
- const strArg = this.genExpr(expr.args[0]);
61
- const restArgs = expr.args
62
- .slice(1)
63
- .map((e) => this.genExpr(e))
64
- .join(", ");
65
- return `((str, ...ptrs) => { const tokens = str.trim().split(/\\s+/).filter(Boolean); ${_SSCAN_LOOP} return [n, err ? err : (n < ptrs.length ? __error("unexpected EOF") : null)]; })(${strArg}, ${restArgs})`;
66
- }
67
- case "Sscanln": {
68
- this.useHelper("error");
69
- const strArg = this.genExpr(expr.args[0]);
70
- const restArgs = expr.args
71
- .slice(1)
72
- .map((e) => this.genExpr(e))
73
- .join(", ");
74
- return `((str, ...ptrs) => { const tokens = str.split("\\n")[0].trim().split(/\\s+/).filter(Boolean); ${_SSCAN_LOOP} return [n, err ? err : (n < ptrs.length ? __error("unexpected EOF") : null)]; })(${strArg}, ${restArgs})`;
75
- }
76
- case "Sscanf": {
77
- this.useHelper("error");
78
- const strArg = this.genExpr(expr.args[0]);
79
- const fmtArg = this.genExpr(expr.args[1]);
80
- const restArgs = expr.args
81
- .slice(2)
82
- .map((e) => this.genExpr(e))
83
- .join(", ");
84
- return (
85
- `((str, fmt, ...ptrs) => { ` +
86
- `const s = String(str); const f = String(fmt); ` +
87
- `let si = 0, fi = 0; const tokens = []; let parseErr = null; ` +
88
- `while (fi < f.length) { ` +
89
- `if (/\\s/.test(f[fi])) { ` +
90
- `while (fi < f.length && /\\s/.test(f[fi])) fi++; ` +
91
- `while (si < s.length && /\\s/.test(s[si])) si++; ` +
92
- `continue; ` +
93
- `} ` +
94
- `if (f[fi] === "%") { ` +
95
- `if (fi + 1 < f.length && f[fi + 1] === "%") { ` +
96
- `if (s[si] !== "%") { parseErr = __error("input does not match format"); break; } ` +
97
- `si++; fi += 2; continue; ` +
98
- `} ` +
99
- `const vm = f.slice(fi).match(/^%[vdsfqtxXbcoeEfFgG]/); ` +
100
- `if (vm) { ` +
101
- `const verb = vm[0]; fi += verb.length; ` +
102
- `if (verb !== "%c") { while (si < s.length && /\\s/.test(s[si])) si++; } ` +
103
- `if (si >= s.length) break; ` +
104
- `let tokRe = /^\\S+/; ` +
105
- `if (verb === "%d" || verb === "%i") tokRe = /^[+-]?\\d+/; ` +
106
- `else if (verb === "%o") tokRe = /^[+-]?(?:0[oO])?[0-7]+/; ` +
107
- `else if (verb === "%b") tokRe = /^[+-]?(?:0[bB])?[01]+/; ` +
108
- `else if (verb === "%f" || verb === "%F" || verb === "%e" || verb === "%E" || verb === "%g" || verb === "%G") tokRe = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?/; ` +
109
- `else if (verb === "%t") tokRe = /^(?:true|false|1|0|t|f|T|F|TRUE|FALSE)/; ` +
110
- `else if (verb === "%x" || verb === "%X") tokRe = /^[+-]?(?:0x)?[0-9a-fA-F]+/; ` +
111
- `else if (verb === "%c") tokRe = /^[\\s\\S]/; ` +
112
- `const m = s.slice(si).match(tokRe); ` +
113
- `if (!m) { parseErr = __error("input does not match format"); break; } ` +
114
- `tokens.push({ t: m[0], verb }); si += m[0].length; continue; ` +
115
- `} ` +
116
- `} ` +
117
- `if (si >= s.length) break; ` +
118
- `if (s[si] !== f[fi]) { parseErr = __error("input does not match format"); break; } ` +
119
- `si++; fi++; ` +
120
- `} ` +
121
- `${_SSCAN_LOOP} ` +
122
- `return [n, parseErr || err || (n < ptrs.length ? __error("unexpected EOF") : null)]; ` +
123
- `})(${strArg}, ${fmtArg}, ${restArgs})`
124
- );
125
- }
126
- default:
127
- return undefined;
128
- }
129
- },
130
-
131
- _genFmtFprint(fn, expr) {
132
- this.useHelper("sprintf");
133
- const writerArg = expr.args[0];
134
- const rest = expr.args.slice(1);
135
- const restJs = rest.map((e) => this._fmtArgJs(e)).join(", ");
136
- const writerType = writerArg._type;
137
- const targetTypeName =
138
- writerType?.name ??
139
- (writerType?.kind === "pointer" ? writerType.base?.name : null);
140
- const sprintfCall = this._buildFprintSprintfCall(fn, rest.length, restJs);
141
- if (targetTypeName === "strings.Builder") {
142
- const w = this.genExpr(writerArg);
143
- const base = this._unboxWriter(w);
144
- return `((__b, __s) => { __b._buf += __s; return [__s.length, null]; })(${base}, ${sprintfCall})`;
145
- }
146
- if (targetTypeName === "bytes.Buffer") {
147
- const w = this.genExpr(writerArg);
148
- const base = this._unboxWriter(w);
149
- return `((__b, __s) => { const __bytes = new TextEncoder().encode(__s); for (let i = 0; i < __bytes.length; i++) __b._buf.push(__bytes[i]); return [__bytes.length, null]; })(${base}, ${sprintfCall})`;
150
- }
151
- // Generic io.Writer fallback — call .WriteString if available
152
- const w = this.genExpr(writerArg);
153
- return `((__w, __s) => typeof __w.WriteString === "function" ? __w.WriteString(__s) : __w.Write(new TextEncoder().encode(__s)))(${w}, ${sprintfCall})`;
154
- },
155
-
156
- _genStdoutWrite(strJs) {
157
- return `((__s) => (typeof process !== "undefined" && process?.stdout?.write ? process.stdout.write(__s) : console.log(__s)))(${strJs})`;
158
- },
159
-
160
- // Formats Print/Println operands with %v so the first operand is never
161
- // mistaken for a format string.
162
- _genPrintOperands(expr, sep, suffix) {
163
- const argc = expr.args.length;
164
- if (argc === 0) return JSON.stringify(suffix);
165
- const fmt = Array(argc).fill("%v").join(sep) + suffix;
166
- const args = expr.args.map((e) => this._fmtArgJs(e)).join(", ");
167
- return `__sprintf(${JSON.stringify(fmt)}, ${args})`;
168
- },
169
-
170
- _buildFprintSprintfCall(fn, argc, restJs) {
171
- if (fn === "Fprintf") return `__sprintf(${restJs})`;
172
- if (argc === 0) return fn === "Fprintln" ? '"\\n"' : '""';
173
- const sep = fn === "Fprintln" ? " " : "";
174
- const suffix = fn === "Fprintln" ? "\\n" : "";
175
- const fmt = Array(argc).fill("%v").join(sep) + suffix;
176
- return `__sprintf("${fmt}", ${restJs})`;
177
- },
178
- };