gofront 1.6.1 → 1.8.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.
- package/README.md +45 -49
- package/package.json +12 -8
- package/src/backend/js/expressions.js +1627 -148
- package/src/backend/js/fmt-runtime.js +573 -0
- package/src/backend/js/index.js +508 -102
- package/src/backend/js/runtime.js +1997 -106
- package/src/backend/js/statements.js +931 -87
- package/src/backend/js/stdlib/bits.js +87 -14
- package/src/backend/js/stdlib/builder.js +41 -6
- package/src/backend/js/stdlib/bytes.js +253 -7
- package/src/backend/js/stdlib/errors.js +7 -1
- package/src/backend/js/stdlib/fmt.js +349 -10
- package/src/backend/js/stdlib/index.js +19 -2
- package/src/backend/js/stdlib/json.js +1167 -0
- package/src/backend/js/stdlib/maps.js +0 -8
- package/src/backend/js/stdlib/math.js +17 -1
- package/src/backend/js/stdlib/simd.js +34 -0
- package/src/backend/js/stdlib/slices.js +36 -6
- package/src/backend/js/stdlib/strconv.js +10 -5
- package/src/backend/js/stdlib/strings.js +83 -4
- package/src/backend/js/stdlib/testing.js +7 -0
- package/src/backend/js/stdlib/time.js +79 -55
- package/src/backend/js/stdlib/unicode.js +1 -1
- package/src/backend/js/stdlib/utf8.js +1 -1
- package/src/backend/js/templ.js +38 -76
- package/src/backend/js/type-info.js +272 -0
- package/src/backend/shared/fmt-types.js +188 -0
- package/src/backend/wasm/boundary.js +446 -72
- package/src/backend/wasm/emit-builtins.js +320 -13
- package/src/backend/wasm/emit-exprs.js +1404 -199
- package/src/backend/wasm/emit-maps.js +61 -13
- package/src/backend/wasm/emit-stmts.js +1359 -164
- package/src/backend/wasm/emit.js +518 -74
- package/src/backend/wasm/encode.js +128 -13
- package/src/backend/wasm/globals.js +452 -0
- package/src/backend/wasm/index.js +194 -2489
- package/src/backend/wasm/method-expr.js +381 -0
- package/src/backend/wasm/module-emitter.js +2240 -0
- package/src/backend/wasm/monomorph.js +62 -4
- package/src/backend/wasm/optimize.js +4 -2
- package/src/backend/wasm/prescan.js +397 -0
- package/src/backend/wasm/stdlib/bytes.js +1804 -127
- package/src/backend/wasm/stdlib/core.js +1574 -199
- package/src/backend/wasm/stdlib/index.js +3 -5
- package/src/backend/wasm/stdlib/io.js +1567 -150
- package/src/backend/wasm/stdlib/packages.js +2 -0
- package/src/backend/wasm/stdlib/simd.js +499 -0
- package/src/backend/wasm/stdlib/time.js +1041 -12
- package/src/backend/wasm/types.js +221 -15
- package/src/backend/wasm/variadic.js +93 -0
- package/src/backend/wasm/wat.js +84 -20
- package/src/{cli-core.js → cli/cli-core.js} +236 -10
- package/src/{test-runner.js → cli/test-runner.js} +332 -39
- package/src/{vendor.js → cli/vendor.js} +89 -15
- package/src/compiler.js +107 -269
- package/src/dts-parser.js +71 -14
- package/src/index.js +15 -169
- package/src/{lexer.js → lexer/lexer.js} +102 -55
- package/src/{tokens.js → lexer/tokens.js} +1 -0
- package/src/link/sourcemap.js +97 -0
- package/src/link/stdlib.js +515 -0
- package/src/link/wasm.js +294 -0
- package/src/lower/bounds.js +394 -0
- package/src/lower/boxing.js +1 -6
- package/src/lower/captures.js +176 -32
- package/src/lower/embedding.js +2 -1
- package/src/lower/index.js +26 -18
- package/src/lower/json-codecs.js +1398 -0
- package/src/lower/ownership.js +22 -1
- package/src/lower/range.js +86 -1
- package/src/lower/reachability.js +132 -0
- package/src/parser/declarations.js +58 -13
- package/src/parser/expressions.js +29 -7
- package/src/parser/index.js +2 -1
- package/src/parser/statements.js +37 -22
- package/src/parser/struct-tag.js +144 -0
- package/src/{templ-parser.js → parser/templ.js} +138 -15
- package/src/parser/types.js +130 -13
- package/src/resolver.js +22 -1
- package/src/typechecker/assignability.js +215 -11
- package/src/typechecker/const-fold.js +356 -0
- package/src/typechecker/constants.js +256 -0
- package/src/typechecker/expressions.js +960 -99
- package/src/typechecker/index.js +491 -72
- package/src/typechecker/init-order.js +330 -0
- package/src/typechecker/resolve.js +596 -52
- package/src/typechecker/statements.js +157 -17
- package/src/typechecker/stdlib/core.js +333 -55
- package/src/typechecker/stdlib/excluded.js +898 -0
- package/src/typechecker/stdlib/extended.js +359 -26
- package/src/typechecker/{stdlib.js → stdlib/index.js} +6 -4
- package/src/typechecker/stdlib/simd.js +123 -0
- package/src/typechecker/termination.js +1 -1
- package/src/typechecker/types.js +165 -26
- package/stdlib/bytes/iter.go +192 -0
- package/stdlib/bytes/search.go +240 -0
- package/stdlib/bytes/split.go +218 -0
- package/stdlib/cmp/cmp.go +65 -0
- package/stdlib/encoding/json/errors.go +31 -0
- package/stdlib/encoding/json/indent.go +71 -0
- package/stdlib/encoding/json/number.go +12 -0
- package/stdlib/encoding/json/stream.go +173 -0
- package/stdlib/errors/overlay.go +12 -0
- package/stdlib/hash/hash.go +53 -0
- package/stdlib/internal/jsonrt/dec.go +738 -0
- package/stdlib/internal/jsonrt/enc.go +366 -0
- package/stdlib/internal/jsonrt/indent.go +135 -0
- package/stdlib/internal/jsonrt/number.go +27 -0
- package/stdlib/internal/jsonrt/reader.go +73 -0
- package/stdlib/internal/jsonrt/scanner.go +649 -0
- package/stdlib/io/io.go +346 -0
- package/stdlib/iter/iter.go +18 -0
- package/stdlib/maps/iter.go +65 -0
- package/stdlib/math/extra.go +270 -0
- package/stdlib/slices/extra.go +73 -0
- package/stdlib/slices/iter.go +113 -0
- package/stdlib/sort/sort.go +561 -0
- package/stdlib/strconv/quote.go +341 -0
- package/stdlib/strings/extra.go +35 -0
- package/stdlib/strings/iter.go +122 -0
- package/stdlib/sync/extra.go +105 -0
- package/stdlib/unicode/unicode.go +112 -0
- package/stdlib/unicode/utf8/bytes.go +239 -0
- package/src/backend/wasm/const-fold.js +0 -205
- package/src/backend/wasm/emit-stdlib.js +0 -13
- /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
- /package/src/{colors.js → cli/colors.js} +0 -0
- /package/src/{dev-server.js → cli/dev-server.js} +0 -0
- /package/src/{minifier.js → cli/minifier.js} +0 -0
- /package/src/{project-config.js → cli/project-config.js} +0 -0
- /package/src/{pwa.js → cli/pwa.js} +0 -0
- /package/src/{templ-lexer.js → lexer/templ-lexer.js} +0 -0
|
@@ -3,37 +3,110 @@
|
|
|
3
3
|
|
|
4
4
|
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
5
5
|
|
|
6
|
+
function toBig64(x) {
|
|
7
|
+
const trimmed = String(x).trim();
|
|
8
|
+
if (/^-?(0[xX][0-9a-fA-F]+|0[bB][01]+|0[oO][0-7]+|\d+)n?$/.test(trimmed)) {
|
|
9
|
+
return trimmed.endsWith("n") ? trimmed : `${trimmed}n`;
|
|
10
|
+
}
|
|
11
|
+
return `BigInt(${x})`;
|
|
12
|
+
}
|
|
13
|
+
|
|
6
14
|
const BITS_MAP = {
|
|
15
|
+
Add32: ([x, y, c]) =>
|
|
16
|
+
`((() => { const s = BigInt((${x}) >>> 0) + BigInt((${y}) >>> 0) + BigInt((${c}) >>> 0); return [Number(s & 0xffffffffn), Number(s >> 32n)]; })())`,
|
|
17
|
+
Add64: ([x, y, c]) =>
|
|
18
|
+
`((() => { const s = BigInt.asUintN(64, ${toBig64(x)}) + BigInt.asUintN(64, ${toBig64(y)}) + BigInt.asUintN(64, ${toBig64(c)}); return [Number(BigInt.asUintN(64, s)), Number(s >> 64n)]; })())`,
|
|
19
|
+
Add: (args) => BITS_MAP.Add64(args),
|
|
20
|
+
|
|
21
|
+
Sub32: ([x, y, b]) =>
|
|
22
|
+
`((() => { const diff = BigInt((${x}) >>> 0) - BigInt((${y}) >>> 0) - BigInt((${b}) >>> 0); return [Number(BigInt.asUintN(32, diff)), diff < 0n ? 1 : 0]; })())`,
|
|
23
|
+
Sub64: ([x, y, b]) =>
|
|
24
|
+
`((() => { const diff = BigInt.asUintN(64, ${toBig64(x)}) - BigInt.asUintN(64, ${toBig64(y)}) - BigInt.asUintN(64, ${toBig64(b)}); return [Number(BigInt.asUintN(64, diff)), diff < 0n ? 1 : 0]; })())`,
|
|
25
|
+
Sub: (args) => BITS_MAP.Sub64(args),
|
|
26
|
+
|
|
27
|
+
Mul32: ([x, y]) =>
|
|
28
|
+
`((() => { const p = BigInt((${x}) >>> 0) * BigInt((${y}) >>> 0); return [Number(p >> 32n), Number(p & 0xffffffffn)]; })())`,
|
|
29
|
+
Mul64: ([x, y]) =>
|
|
30
|
+
`((() => { const xB = BigInt.asUintN(64, ${toBig64(x)}); const yB = BigInt.asUintN(64, ${toBig64(y)}); const mask32 = 0xffffffffn; const x0 = xB & mask32, x1 = xB >> 32n; const y0 = yB & mask32, y1 = yB >> 32n; const w0 = x0 * y0; const t = x1 * y0 + (w0 >> 32n); const w1 = (t & mask32) + x0 * y1; const hi = x1 * y1 + (t >> 32n) + (w1 >> 32n); const lo = BigInt.asUintN(64, xB * yB); return [Number(hi), Number(lo)]; })())`,
|
|
31
|
+
Mul: (args) => BITS_MAP.Mul64(args),
|
|
32
|
+
|
|
33
|
+
Div32: ([hi, lo, y]) =>
|
|
34
|
+
`((() => { const yu = (${y}) >>> 0; if (yu === 0) throw new Error("runtime error: integer divide by zero"); const hiu = (${hi}) >>> 0; if (hiu >= yu) throw new Error("runtime error: integer overflow"); const z = (BigInt(hiu) << 32n) | BigInt((${lo}) >>> 0); const yB = BigInt(yu); return [Number(z / yB), Number(z % yB)]; })())`,
|
|
35
|
+
Div64: ([hi, lo, y]) =>
|
|
36
|
+
`((() => { const yB = BigInt.asUintN(64, ${toBig64(y)}); if (yB === 0n) throw new Error("runtime error: integer divide by zero"); const hiB = BigInt.asUintN(64, ${toBig64(hi)}); if (hiB >= yB) throw new Error("runtime error: integer overflow"); const loB = BigInt.asUintN(64, ${toBig64(lo)}); const z = (hiB << 64n) | loB; return [Number(BigInt.asUintN(64, z / yB)), Number(BigInt.asUintN(64, z % yB))]; })())`,
|
|
37
|
+
Div: (args) => BITS_MAP.Div64(args),
|
|
38
|
+
|
|
39
|
+
Rem32: ([hi, lo, y]) =>
|
|
40
|
+
`((() => { const yu = (${y}) >>> 0; if (yu === 0) throw new Error("runtime error: integer divide by zero"); const z = (BigInt((${hi}) >>> 0) << 32n) | BigInt((${lo}) >>> 0); return Number(z % BigInt(yu)); })())`,
|
|
41
|
+
Rem64: ([hi, lo, y]) =>
|
|
42
|
+
`((() => { const yB = BigInt.asUintN(64, ${toBig64(y)}); if (yB === 0n) throw new Error("runtime error: integer divide by zero"); const z = ((BigInt.asUintN(64, ${toBig64(hi)}) % yB) << 64n) | BigInt.asUintN(64, ${toBig64(lo)}); return Number(BigInt.asUintN(64, z % yB)); })())`,
|
|
43
|
+
Rem: (args) => BITS_MAP.Rem64(args),
|
|
44
|
+
|
|
45
|
+
LeadingZeros8: ([x]) =>
|
|
46
|
+
`((() => { const v = (${x}) & 0xff; return v === 0 ? 8 : Math.clz32(v) - 24; })())`,
|
|
47
|
+
LeadingZeros16: ([x]) =>
|
|
48
|
+
`((() => { const v = (${x}) & 0xffff; return v === 0 ? 16 : Math.clz32(v) - 16; })())`,
|
|
7
49
|
LeadingZeros32: ([x]) => `Math.clz32((${x}) >>> 0)`,
|
|
50
|
+
LeadingZeros64: ([x]) =>
|
|
51
|
+
`((() => { const v = BigInt.asUintN(64, ${toBig64(x)}); if (v === 0n) return 64; const hi = Number(v >> 32n); return hi !== 0 ? Math.clz32(hi) : 32 + Math.clz32(Number(v & 0xffffffffn)); })())`,
|
|
52
|
+
LeadingZeros: (args) => BITS_MAP.LeadingZeros64(args),
|
|
53
|
+
|
|
54
|
+
TrailingZeros8: ([x]) =>
|
|
55
|
+
`((() => { const v = (${x}) & 0xff; return v === 0 ? 8 : 31 - Math.clz32(v & -v); })())`,
|
|
56
|
+
TrailingZeros16: ([x]) =>
|
|
57
|
+
`((() => { const v = (${x}) & 0xffff; return v === 0 ? 16 : 31 - Math.clz32(v & -v); })())`,
|
|
8
58
|
TrailingZeros32: ([x]) =>
|
|
9
59
|
`((() => { const v = (${x}) >>> 0; return v === 0 ? 32 : 31 - Math.clz32(v & -v); })())`,
|
|
60
|
+
TrailingZeros64: ([x]) =>
|
|
61
|
+
`((() => { const v = BigInt.asUintN(64, ${toBig64(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)); })())`,
|
|
62
|
+
TrailingZeros: (args) => BITS_MAP.TrailingZeros64(args),
|
|
63
|
+
|
|
64
|
+
OnesCount8: ([x]) =>
|
|
65
|
+
`((() => { let v = (${x}) & 0xff; v = v - ((v >>> 1) & 0x55); v = (v & 0x33) + ((v >>> 2) & 0x33); return (v + (v >>> 4)) & 0x0f; })())`,
|
|
66
|
+
OnesCount16: ([x]) =>
|
|
67
|
+
`((() => { let v = (${x}) & 0xffff; v = v - ((v >>> 1) & 0x5555); v = (v & 0x3333) + ((v >>> 2) & 0x3333); return ((Math.imul((v + (v >>> 4)) & 0x0f0f, 0x0101)) >>> 8) & 0xff; })())`,
|
|
10
68
|
OnesCount32: ([x]) =>
|
|
11
69
|
`((() => { let v = (${x}) >>> 0; v = v - ((v >>> 1) & 0x55555555); v = (v & 0x33333333) + ((v >>> 2) & 0x33333333); return (Math.imul((v + (v >>> 4)) & 0x0f0f0f0f, 0x01010101)) >>> 24; })())`,
|
|
70
|
+
OnesCount64: ([x]) =>
|
|
71
|
+
`((() => { let v = BigInt.asUintN(64, ${toBig64(x)}); let c = 0; while (v > 0n) { if (v & 1n) c++; v >>= 1n; } return c; })())`,
|
|
72
|
+
OnesCount: (args) => BITS_MAP.OnesCount64(args),
|
|
73
|
+
|
|
74
|
+
RotateLeft8: ([x, k]) =>
|
|
75
|
+
`((() => { const s = (${k}) & 7; const v = (${x}) & 0xff; return ((v << s) | (v >>> ((8 - s) & 7))) & 0xff; })())`,
|
|
76
|
+
RotateLeft16: ([x, k]) =>
|
|
77
|
+
`((() => { const s = (${k}) & 15; const v = (${x}) & 0xffff; return ((v << s) | (v >>> ((16 - s) & 15))) & 0xffff; })())`,
|
|
12
78
|
RotateLeft32: ([x, k]) =>
|
|
13
79
|
`((() => { 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
80
|
RotateLeft64: ([x, k]) =>
|
|
22
|
-
`((() => { const s =
|
|
81
|
+
`((() => { const s = ${toBig64(k)} & 63n; const v = BigInt.asUintN(64, ${toBig64(x)}); return Number(BigInt.asUintN(64, (v << s) | (v >> ((64n - s) & 63n)))); })())`,
|
|
82
|
+
RotateLeft: (args) => BITS_MAP.RotateLeft64(args),
|
|
23
83
|
|
|
84
|
+
Len8: ([x]) =>
|
|
85
|
+
`((() => { const v = (${x}) & 0xff; return v === 0 ? 0 : 32 - Math.clz32(v); })())`,
|
|
86
|
+
Len16: ([x]) =>
|
|
87
|
+
`((() => { const v = (${x}) & 0xffff; return v === 0 ? 0 : 32 - Math.clz32(v); })())`,
|
|
24
88
|
Len32: ([x]) => `((v => 32 - Math.clz32(v >>> 0))(${x}))`,
|
|
25
89
|
Len64: ([x]) =>
|
|
26
|
-
`((() => { const v = BigInt.asUintN(64,
|
|
90
|
+
`((() => { const v = BigInt.asUintN(64, ${toBig64(x)}); if (v === 0n) return 0; const hi = Number(v >> 32n); return hi !== 0 ? 64 - Math.clz32(hi) : 32 - Math.clz32(Number(v & 0xffffffffn)); })())`,
|
|
91
|
+
Len: (args) => BITS_MAP.Len64(args),
|
|
92
|
+
|
|
93
|
+
Reverse8: ([x]) =>
|
|
94
|
+
`((() => { let v = (${x}) & 0xff; v = ((v >>> 1) & 0x55) | ((v & 0x55) << 1); v = ((v >>> 2) & 0x33) | ((v & 0x33) << 2); return (((v >>> 4) & 0x0f) | ((v & 0x0f) << 4)) & 0xff; })())`,
|
|
95
|
+
Reverse16: ([x]) =>
|
|
96
|
+
`((() => { let v = (${x}) & 0xffff; v = ((v >>> 1) & 0x5555) | ((v & 0x5555) << 1); v = ((v >>> 2) & 0x3333) | ((v & 0x3333) << 2); v = ((v >>> 4) & 0x0f0f) | ((v & 0x0f0f) << 4); return (((v >>> 8) & 0x00ff) | ((v & 0x00ff) << 8)) & 0xffff; })())`,
|
|
97
|
+
Reverse32: ([x]) =>
|
|
98
|
+
`((() => { 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; })())`,
|
|
99
|
+
Reverse64: ([x]) =>
|
|
100
|
+
`((() => { 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, ${toBig64(x)}); const lo = Number(v & 0xffffffffn); const hi = Number((v >> 32n) & 0xffffffffn); return Number((BigInt(rev32(lo)) << 32n) | BigInt(rev32(hi))); })())`,
|
|
101
|
+
Reverse: (args) => BITS_MAP.Reverse64(args),
|
|
102
|
+
|
|
27
103
|
ReverseBytes16: ([x]) =>
|
|
28
104
|
`((v => ((v & 0xff) << 8) | ((v >>> 8) & 0xff))((${x}) & 0xffff))`,
|
|
29
105
|
ReverseBytes32: ([x]) =>
|
|
30
106
|
`((v => (((v & 0xff) << 24) | ((v & 0xff00) << 8) | ((v >>> 8) & 0xff00) | ((v >>> 24) & 0xff)) >>> 0)((${x}) >>> 0))`,
|
|
31
107
|
ReverseBytes64: ([x]) =>
|
|
32
|
-
`((() => { const v = BigInt.asUintN(64,
|
|
33
|
-
|
|
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))); })())`,
|
|
108
|
+
`((() => { const v = BigInt.asUintN(64, ${toBig64(x)}); let r = 0n; for (let i = 0n; i < 8n; i++) r = (r << 8n) | ((v >> (i * 8n)) & 0xffn); return Number(r); })())`,
|
|
109
|
+
ReverseBytes: (args) => BITS_MAP.ReverseBytes64(args),
|
|
37
110
|
};
|
|
38
111
|
|
|
39
112
|
/** @type {ThisType<CodeGen>} */
|
|
@@ -20,16 +20,41 @@ const BUILDER_STR = {
|
|
|
20
20
|
};
|
|
21
21
|
const BUILDER_BYTES = {
|
|
22
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) =>
|
|
23
|
+
`((buf, s) => { buf._lastOp = 0; 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) =>
|
|
25
|
+
`((buf, c) => { buf._lastOp = 0; buf._buf.push(c); return null; })(${b}, ${a[0]})`,
|
|
25
26
|
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
|
+
`((buf, cp) => { buf._lastOp = 0; 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
28
|
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
|
+
`((buf, d) => { buf._lastOp = 0; for (let i = 0; i < d.length; i++) buf._buf.push(d[i]); return [d.length, null]; })(${b}, ${a[0]})`,
|
|
29
30
|
String: (b) => `new TextDecoder().decode(new Uint8Array(${b}._buf))`,
|
|
30
31
|
Reset: (b) => `(${b}._buf = [])`,
|
|
31
32
|
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
|
+
`((buf, p) => { if (!buf._buf || 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(); if (n > 0) { buf._lastOp = 1; buf._lastByte = p[n - 1]; } else { buf._lastOp = 0; } return [n, null]; })(${b}, ${a[0]})`,
|
|
34
|
+
ReadByte: (b) =>
|
|
35
|
+
`((buf) => { if (!buf._buf || buf._buf.length === 0) return [0, __io_eof]; const c = buf._buf.shift(); buf._lastOp = 1; buf._lastByte = c; return [c, null]; })(${b})`,
|
|
36
|
+
UnreadByte: (b) =>
|
|
37
|
+
`((buf) => { if (buf._lastOp !== 1) return __error("bytes.Buffer: UnreadByte: previous operation was not a successful read"); buf._buf.unshift(buf._lastByte); buf._lastOp = 0; return null; })(${b})`,
|
|
38
|
+
ReadRune: (b) =>
|
|
39
|
+
`((buf) => { if (!buf._buf || buf._buf.length === 0) return [0, 0, __io_eof]; const u8 = new Uint8Array(buf._buf); const s = new TextDecoder().decode(u8); const cp = s.codePointAt(0); const runeStr = s.slice(0, cp > 0xffff ? 2 : 1); const sz = new TextEncoder().encode(runeStr).length; for (let i = 0; i < sz; i++) buf._buf.shift(); buf._lastOp = 2; buf._lastRune = runeStr; return [cp, sz, null]; })(${b})`,
|
|
40
|
+
UnreadRune: (b) =>
|
|
41
|
+
`((buf) => { if (buf._lastOp !== 2) return __error("bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune"); const bts = new TextEncoder().encode(buf._lastRune); for (let i = bts.length - 1; i >= 0; i--) buf._buf.unshift(bts[i]); buf._lastOp = 0; return null; })(${b})`,
|
|
42
|
+
ReadBytes: (b, a) =>
|
|
43
|
+
`((buf, delim) => { const idx = buf._buf.indexOf(delim); if (idx < 0) { const rem = Uint8Array.from(buf._buf); buf._buf = []; return [rem, __io_eof]; } const line = Uint8Array.from(buf._buf.splice(0, idx + 1)); return [line, null]; })(${b}, ${a[0]})`,
|
|
44
|
+
ReadString: (b, a) =>
|
|
45
|
+
`((buf, delim) => { const idx = buf._buf.indexOf(delim); if (idx < 0) { const rem = new TextDecoder().decode(Uint8Array.from(buf._buf)); buf._buf = []; return [rem, __io_eof]; } const line = new TextDecoder().decode(Uint8Array.from(buf._buf.splice(0, idx + 1))); return [line, null]; })(${b}, ${a[0]})`,
|
|
46
|
+
ReadFrom: (b, a) =>
|
|
47
|
+
`((buf, r) => { let total = 0n; const tmp = new Uint8Array(4096); while (true) { const [n, err] = r.Read(tmp); if (n > 0) { for (let i = 0; i < n; i++) buf._buf.push(tmp[i]); total += BigInt(n); } if (err) { return [total, (err === __io_eof || err?.Error?.() === "EOF") ? null : err]; } } })(${b}, ${a[0]})`,
|
|
48
|
+
WriteTo: (b, a) =>
|
|
49
|
+
`((buf, w) => { if (!buf._buf || buf._buf.length === 0) return [0n, null]; const bytes = Uint8Array.from(buf._buf); const [n, err] = w.Write(bytes); if (n > 0) buf._buf.splice(0, n); return [BigInt(n), err]; })(${b}, ${a[0]})`,
|
|
50
|
+
Next: (b, a) =>
|
|
51
|
+
`((buf, n) => { const cnt = Math.min(Math.max(0, n), buf._buf.length); return Uint8Array.from(buf._buf.splice(0, cnt)); })(${b}, ${a[0]})`,
|
|
52
|
+
Truncate: (b, a) =>
|
|
53
|
+
`((buf, n) => { if (n < 0 || n > buf._buf.length) throw new Error("bytes.Buffer: truncation out of range"); buf._buf.length = n; })(${b}, ${a[0]})`,
|
|
54
|
+
Available: (b) => `Math.max(0, (${b}._cap ?? 0) - ${b}._buf.length)`,
|
|
55
|
+
AvailableBuffer: () => `new Uint8Array(0)`,
|
|
56
|
+
Peek: (b, a) =>
|
|
57
|
+
`((buf, n) => { if (n < 0) throw new Error("runtime error: slice bounds out of range"); if (n > buf._buf.length) return [Uint8Array.from(buf._buf), __io_eof]; return [Uint8Array.from(buf._buf.slice(0, n)), null]; })(${b}, ${a[0]})`,
|
|
33
58
|
};
|
|
34
59
|
const BUILDER_COMMON = {
|
|
35
60
|
Bytes: (b) => `new Uint8Array(${b}._buf)`,
|
|
@@ -45,7 +70,17 @@ export const builderMethods = {
|
|
|
45
70
|
const recv = expr.func.expr;
|
|
46
71
|
const base = this._unboxWriter(this.genExpr(recv));
|
|
47
72
|
const args = expr.args.map((a) => this.genExpr(a));
|
|
48
|
-
if (
|
|
73
|
+
if (
|
|
74
|
+
method === "Read" ||
|
|
75
|
+
method === "ReadByte" ||
|
|
76
|
+
method === "ReadRune" ||
|
|
77
|
+
method === "ReadBytes" ||
|
|
78
|
+
method === "ReadString" ||
|
|
79
|
+
method === "ReadFrom" ||
|
|
80
|
+
method === "UnreadByte" ||
|
|
81
|
+
method === "UnreadRune" ||
|
|
82
|
+
method === "Peek"
|
|
83
|
+
) {
|
|
49
84
|
this.useHelper("ioEOF");
|
|
50
85
|
this.useHelper("error");
|
|
51
86
|
}
|
|
@@ -6,14 +6,100 @@ const __bs = `(b => typeof TextDecoder !== "undefined" ? new TextDecoder().decod
|
|
|
6
6
|
const __sb = `(s => typeof TextEncoder !== "undefined" ? new TextEncoder().encode(s) : new Uint8Array([...s].map(c => c.charCodeAt(0))))`;
|
|
7
7
|
|
|
8
8
|
const BYTES_DISPATCH = {
|
|
9
|
-
Contains: (a) =>
|
|
9
|
+
Contains: (a) =>
|
|
10
|
+
`((b, sep) => {
|
|
11
|
+
b = b || new Uint8Array(0);
|
|
12
|
+
sep = sep || new Uint8Array(0);
|
|
13
|
+
if (sep.length === 0) return true;
|
|
14
|
+
if (sep.length === 1) return (b.indexOf ? b.indexOf(sep[0]) : Array.prototype.indexOf.call(b, sep[0])) >= 0;
|
|
15
|
+
if (sep.length > b.length) return false;
|
|
16
|
+
const first = sep[0];
|
|
17
|
+
const last = sep[sep.length - 1];
|
|
18
|
+
let i = 0;
|
|
19
|
+
while (i <= b.length - sep.length) {
|
|
20
|
+
const idx = b.indexOf ? b.indexOf(first, i) : Array.prototype.indexOf.call(b, first, i);
|
|
21
|
+
if (idx < 0 || idx > b.length - sep.length) return false;
|
|
22
|
+
if (b[idx + sep.length - 1] === last) {
|
|
23
|
+
let match = true;
|
|
24
|
+
for (let j = 1; j < sep.length - 1; j++) {
|
|
25
|
+
if (b[idx + j] !== sep[j]) { match = false; break; }
|
|
26
|
+
}
|
|
27
|
+
if (match) return true;
|
|
28
|
+
}
|
|
29
|
+
i = idx + 1;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
})(${a[0]}, ${a[1]})`,
|
|
10
33
|
HasPrefix: (a) =>
|
|
11
34
|
`((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
35
|
HasSuffix: (a) =>
|
|
13
36
|
`((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) =>
|
|
37
|
+
Index: (a) =>
|
|
38
|
+
`((b, sep) => {
|
|
39
|
+
b = b || new Uint8Array(0);
|
|
40
|
+
sep = sep || new Uint8Array(0);
|
|
41
|
+
const n = b.length;
|
|
42
|
+
const m = sep.length;
|
|
43
|
+
if (m === 0) return 0;
|
|
44
|
+
if (m === 1) return b.indexOf ? b.indexOf(sep[0]) : Array.prototype.indexOf.call(b, sep[0]);
|
|
45
|
+
if (m > n) return -1;
|
|
46
|
+
if (m === n) {
|
|
47
|
+
for (let k = 0; k < m; k++) if (b[k] !== sep[k]) return -1;
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
const first = sep[0];
|
|
51
|
+
const last = sep[m - 1];
|
|
52
|
+
let i = 0;
|
|
53
|
+
while (i <= n - m) {
|
|
54
|
+
const idx = b.indexOf ? b.indexOf(first, i) : Array.prototype.indexOf.call(b, first, i);
|
|
55
|
+
if (idx < 0 || idx > n - m) return -1;
|
|
56
|
+
if (b[idx + m - 1] === last) {
|
|
57
|
+
let match = true;
|
|
58
|
+
for (let j = 1; j < m - 1; j++) {
|
|
59
|
+
if (b[idx + j] !== sep[j]) { match = false; break; }
|
|
60
|
+
}
|
|
61
|
+
if (match) return idx;
|
|
62
|
+
}
|
|
63
|
+
i = idx + 1;
|
|
64
|
+
}
|
|
65
|
+
return -1;
|
|
66
|
+
})(${a[0]}, ${a[1]})`,
|
|
15
67
|
Count: (a) =>
|
|
16
|
-
`((b, sep) =>
|
|
68
|
+
`((b, sep) => {
|
|
69
|
+
b = b || new Uint8Array(0);
|
|
70
|
+
sep = sep || new Uint8Array(0);
|
|
71
|
+
if (sep.length === 0) {
|
|
72
|
+
let runes = 0;
|
|
73
|
+
for (let i = 0; i < b.length; i++) if ((b[i] & 0xc0) !== 0x80) runes++;
|
|
74
|
+
return runes + 1;
|
|
75
|
+
}
|
|
76
|
+
let cnt = 0;
|
|
77
|
+
if (sep.length === 1) {
|
|
78
|
+
const c = sep[0];
|
|
79
|
+
for (let i = 0; i < b.length; i++) if (b[i] === c) cnt++;
|
|
80
|
+
return cnt;
|
|
81
|
+
}
|
|
82
|
+
let i = 0;
|
|
83
|
+
const first = sep[0];
|
|
84
|
+
const last = sep[sep.length - 1];
|
|
85
|
+
while (i <= b.length - sep.length) {
|
|
86
|
+
const idx = b.indexOf ? b.indexOf(first, i) : Array.prototype.indexOf.call(b, first, i);
|
|
87
|
+
if (idx < 0 || idx > b.length - sep.length) break;
|
|
88
|
+
if (b[idx + sep.length - 1] === last) {
|
|
89
|
+
let match = true;
|
|
90
|
+
for (let j = 1; j < sep.length - 1; j++) {
|
|
91
|
+
if (b[idx + j] !== sep[j]) { match = false; break; }
|
|
92
|
+
}
|
|
93
|
+
if (match) {
|
|
94
|
+
cnt++;
|
|
95
|
+
i = idx + sep.length;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
i = idx + 1;
|
|
100
|
+
}
|
|
101
|
+
return cnt;
|
|
102
|
+
})(${a[0]}, ${a[1]})`,
|
|
17
103
|
Repeat: (a) => `${__sb}(${__bs}(${a[0]}).repeat(${a[1]}))`,
|
|
18
104
|
Replace: (a) =>
|
|
19
105
|
`((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]})`,
|
|
@@ -45,10 +131,38 @@ const BYTES_DISPATCH = {
|
|
|
45
131
|
`((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
132
|
IndexByte: (a) => `(${a[0]}).indexOf(${a[1]})`,
|
|
47
133
|
LastIndex: (a) =>
|
|
48
|
-
`((b,
|
|
134
|
+
`((b, sep) => {
|
|
135
|
+
b = b || new Uint8Array(0);
|
|
136
|
+
sep = sep || new Uint8Array(0);
|
|
137
|
+
const n = b.length;
|
|
138
|
+
const m = sep.length;
|
|
139
|
+
if (m === 0) return n;
|
|
140
|
+
if (m === 1) return b.lastIndexOf ? b.lastIndexOf(sep[0]) : Array.prototype.lastIndexOf.call(b, sep[0]);
|
|
141
|
+
if (m > n) return -1;
|
|
142
|
+
if (m === n) {
|
|
143
|
+
for (let k = 0; k < m; k++) if (b[k] !== sep[k]) return -1;
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
const first = sep[0];
|
|
147
|
+
const last = sep[m - 1];
|
|
148
|
+
let i = n - m;
|
|
149
|
+
while (i >= 0) {
|
|
150
|
+
const idx = b.lastIndexOf ? b.lastIndexOf(first, i) : Array.prototype.lastIndexOf.call(b, first, i);
|
|
151
|
+
if (idx < 0) return -1;
|
|
152
|
+
if (b[idx + m - 1] === last) {
|
|
153
|
+
let match = true;
|
|
154
|
+
for (let j = 1; j < m - 1; j++) {
|
|
155
|
+
if (b[idx + j] !== sep[j]) { match = false; break; }
|
|
156
|
+
}
|
|
157
|
+
if (match) return idx;
|
|
158
|
+
}
|
|
159
|
+
i = idx - 1;
|
|
160
|
+
}
|
|
161
|
+
return -1;
|
|
162
|
+
})(${a[0]}, ${a[1]})`,
|
|
49
163
|
LastIndexByte: (a) => `(${a[0]}).lastIndexOf(${a[1]})`,
|
|
50
164
|
Fields: (a) =>
|
|
51
|
-
`((b) => { const s = new TextDecoder().decode(new Uint8Array(b ?? []))
|
|
165
|
+
`((b) => { const s = new TextDecoder().decode(new Uint8Array(b ?? [])); return s.split(/[ \\t\\n\\v\\f\\r\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000]+/).filter(p => p !== "").map(w => new TextEncoder().encode(w)); })(${a[0]})`,
|
|
52
166
|
FieldsFunc: (a) =>
|
|
53
167
|
`((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
168
|
Clone: (a) =>
|
|
@@ -108,14 +222,146 @@ const BYTES_DISPATCH = {
|
|
|
108
222
|
r.push(b.slice(i));
|
|
109
223
|
return r;
|
|
110
224
|
})(${a[0]}, ${a[1]}, ${a[2]})`,
|
|
225
|
+
NewBuffer: (a) => `({ _buf: Array.from(${a[0]} ?? []) })`,
|
|
226
|
+
NewBufferString: (a) =>
|
|
227
|
+
`({ _buf: Array.from(new TextEncoder().encode(${a[0]} ?? "")) })`,
|
|
228
|
+
ToValidUTF8: (a) =>
|
|
229
|
+
`((b, repl) => {
|
|
230
|
+
if (!b) return new Uint8Array(0);
|
|
231
|
+
repl = repl || new Uint8Array(0);
|
|
232
|
+
const res = [];
|
|
233
|
+
let i = 0;
|
|
234
|
+
let inInvalid = false;
|
|
235
|
+
while (i < b.length) {
|
|
236
|
+
const b0 = b[i];
|
|
237
|
+
let sz = 0;
|
|
238
|
+
let valid = false;
|
|
239
|
+
if (b0 < 0x80) {
|
|
240
|
+
sz = 1;
|
|
241
|
+
valid = true;
|
|
242
|
+
} else if (b0 >= 0xC2 && b0 <= 0xDF) {
|
|
243
|
+
if (i + 1 < b.length && (b[i+1] & 0xC0) === 0x80) {
|
|
244
|
+
sz = 2;
|
|
245
|
+
valid = true;
|
|
246
|
+
}
|
|
247
|
+
} else if (b0 >= 0xE0 && b0 <= 0xEF) {
|
|
248
|
+
if (i + 2 < b.length && (b[i+1] & 0xC0) === 0x80 && (b[i+2] & 0xC0) === 0x80) {
|
|
249
|
+
const r = ((b0 & 0x0F) << 12) | ((b[i+1] & 0x3F) << 6) | (b[i+2] & 0x3F);
|
|
250
|
+
if (r >= 0x800 && (r < 0xD800 || r > 0xDFFF)) {
|
|
251
|
+
sz = 3;
|
|
252
|
+
valid = true;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} else if (b0 >= 0xF0 && b0 <= 0xF4) {
|
|
256
|
+
if (i + 3 < b.length && (b[i+1] & 0xC0) === 0x80 && (b[i+2] & 0xC0) === 0x80 && (b[i+3] & 0xC0) === 0x80) {
|
|
257
|
+
const r = ((b0 & 0x07) << 18) | ((b[i+1] & 0x3F) << 12) | ((b[i+2] & 0x3F) << 6) | (b[i+3] & 0x3F);
|
|
258
|
+
if (r >= 0x10000 && r <= 0x10FFFF) {
|
|
259
|
+
sz = 4;
|
|
260
|
+
valid = true;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (valid) {
|
|
265
|
+
if (inInvalid) {
|
|
266
|
+
for (let k = 0; k < repl.length; k++) res.push(repl[k]);
|
|
267
|
+
inInvalid = false;
|
|
268
|
+
}
|
|
269
|
+
for (let k = 0; k < sz; k++) res.push(b[i + k]);
|
|
270
|
+
i += sz;
|
|
271
|
+
} else {
|
|
272
|
+
inInvalid = true;
|
|
273
|
+
i += 1;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (inInvalid) {
|
|
277
|
+
for (let k = 0; k < repl.length; k++) res.push(repl[k]);
|
|
278
|
+
}
|
|
279
|
+
return new Uint8Array(res);
|
|
280
|
+
})(${a[0]}, ${a[1]})`,
|
|
111
281
|
NewReader: (a) =>
|
|
112
|
-
`((b) => ({
|
|
282
|
+
`((b) => ({
|
|
283
|
+
_src: b,
|
|
284
|
+
_pos: 0,
|
|
285
|
+
_prevRune: -1,
|
|
286
|
+
Read(p) {
|
|
287
|
+
if (this._pos >= this._src.length) return [0, __io_eof];
|
|
288
|
+
const n = Math.min(p.length, this._src.length - this._pos);
|
|
289
|
+
for (let i = 0; i < n; i++) p[i] = this._src[this._pos + i];
|
|
290
|
+
this._pos += n;
|
|
291
|
+
this._prevRune = -1;
|
|
292
|
+
return [n, null];
|
|
293
|
+
},
|
|
294
|
+
ReadAt(p, off) {
|
|
295
|
+
const o = Number(off);
|
|
296
|
+
if (o < 0) return [0, __error("bytes.Reader.ReadAt: negative offset")];
|
|
297
|
+
if (o >= this._src.length) return [0, __io_eof];
|
|
298
|
+
const n = Math.min(p.length, this._src.length - o);
|
|
299
|
+
for (let i = 0; i < n; i++) p[i] = this._src[o + i];
|
|
300
|
+
return [n, n < p.length ? __io_eof : null];
|
|
301
|
+
},
|
|
302
|
+
ReadByte() {
|
|
303
|
+
if (this._pos >= this._src.length) return [0, __io_eof];
|
|
304
|
+
this._prevRune = -1;
|
|
305
|
+
return [this._src[this._pos++], null];
|
|
306
|
+
},
|
|
307
|
+
UnreadByte() {
|
|
308
|
+
if (this._pos <= 0) return __error("bytes.Reader.UnreadByte: at beginning of slice");
|
|
309
|
+
this._prevRune = -1;
|
|
310
|
+
this._pos--;
|
|
311
|
+
return null;
|
|
312
|
+
},
|
|
313
|
+
ReadRune() {
|
|
314
|
+
if (this._pos >= this._src.length) return [0, 0, __io_eof];
|
|
315
|
+
const rem = this._src.subarray ? this._src.subarray(this._pos) : new Uint8Array(this._src.slice(this._pos));
|
|
316
|
+
const s = new TextDecoder().decode(rem);
|
|
317
|
+
const cp = s.codePointAt(0);
|
|
318
|
+
const runeStr = s.slice(0, cp > 0xffff ? 2 : 1);
|
|
319
|
+
const sz = new TextEncoder().encode(runeStr).length;
|
|
320
|
+
this._prevRune = this._pos;
|
|
321
|
+
this._pos += sz;
|
|
322
|
+
return [cp, sz, null];
|
|
323
|
+
},
|
|
324
|
+
UnreadRune() {
|
|
325
|
+
if (this._prevRune === undefined || this._prevRune < 0 || this._prevRune >= this._pos) {
|
|
326
|
+
return __error("bytes.Reader.UnreadRune: previous operation was not ReadRune");
|
|
327
|
+
}
|
|
328
|
+
this._pos = this._prevRune;
|
|
329
|
+
this._prevRune = -1;
|
|
330
|
+
return null;
|
|
331
|
+
},
|
|
332
|
+
Seek(offset, whence) {
|
|
333
|
+
const off = BigInt(offset);
|
|
334
|
+
const w = Number(whence);
|
|
335
|
+
let newPos;
|
|
336
|
+
if (w === 0) newPos = off;
|
|
337
|
+
else if (w === 1) newPos = BigInt(this._pos) + off;
|
|
338
|
+
else if (w === 2) newPos = BigInt(this._src.length) + off;
|
|
339
|
+
else return [0n, __error("bytes.Reader.Seek: invalid whence")];
|
|
340
|
+
if (newPos < 0n) return [0n, __error("bytes.Reader.Seek: negative position")];
|
|
341
|
+
this._pos = Number(newPos);
|
|
342
|
+
this._prevRune = -1;
|
|
343
|
+
return [newPos, null];
|
|
344
|
+
},
|
|
345
|
+
Size() { return BigInt(this._src.length); },
|
|
346
|
+
WriteTo(w) {
|
|
347
|
+
if (this._pos >= this._src.length) return [0, null];
|
|
348
|
+
const rem = this._src.subarray ? this._src.subarray(this._pos) : new Uint8Array(this._src.slice(this._pos));
|
|
349
|
+
const [n, err] = w.Write(rem);
|
|
350
|
+
this._pos += n;
|
|
351
|
+
return [n, err];
|
|
352
|
+
},
|
|
353
|
+
Len() { return Math.max(0, this._src.length - this._pos); },
|
|
354
|
+
Reset(b2) { this._src = b2; this._pos = 0; this._prevRune = -1; }
|
|
355
|
+
}))(${a[0]})`,
|
|
113
356
|
};
|
|
114
357
|
|
|
115
358
|
/** @type {ThisType<CodeGen>} */
|
|
116
359
|
export const bytesMethods = {
|
|
117
360
|
_genBytes(fn, a) {
|
|
118
|
-
if (fn === "NewReader")
|
|
361
|
+
if (fn === "NewReader") {
|
|
362
|
+
this.useHelper("ioEOF");
|
|
363
|
+
this.useHelper("error");
|
|
364
|
+
}
|
|
119
365
|
const gen = BYTES_DISPATCH[fn];
|
|
120
366
|
return gen ? gen(a()) : undefined;
|
|
121
367
|
},
|
|
@@ -14,7 +14,8 @@ export const errorsMethods = {
|
|
|
14
14
|
this.useHelper("errorIs");
|
|
15
15
|
return `__errorIs(${args[0]}, ${args[1]})`;
|
|
16
16
|
}
|
|
17
|
-
if (fn === "Unwrap")
|
|
17
|
+
if (fn === "Unwrap")
|
|
18
|
+
return `((e) => typeof e?.Unwrap === "function" ? e.Unwrap() : (e?._cause ?? null))(${args[0]})`;
|
|
18
19
|
if (fn === "As") {
|
|
19
20
|
this.useHelper("errorAs");
|
|
20
21
|
const targetGoType = expr?.args?.[1]?._type;
|
|
@@ -24,6 +25,11 @@ export const errorsMethods = {
|
|
|
24
25
|
if (concreteGoType?.kind === "interface" || typeName === "error") {
|
|
25
26
|
return `__errorAs(${args[0]}, ${args[1]}, (x) => x !== null && (typeof x === "object" ? typeof x.Error === "function" : true))`;
|
|
26
27
|
}
|
|
28
|
+
// Named non-struct error types sit in interfaces as boxes; store the raw value.
|
|
29
|
+
const namedBox = this._namedBoxInfo(concreteGoType);
|
|
30
|
+
if (namedBox) {
|
|
31
|
+
return `__errorAs(${args[0]}, ${args[1]}, (x) => x instanceof ${namedBox.cls}, (x) => x.__gfUnbox())`;
|
|
32
|
+
}
|
|
27
33
|
if (typeName) {
|
|
28
34
|
return `__errorAs(${args[0]}, ${args[1]}, (x) => (typeof ${typeName} === "function" && x instanceof ${typeName}) || x?.constructor?.name === "${typeName}" || x?.__struct === "${typeName}")`;
|
|
29
35
|
}
|