gofront 1.8.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.
- package/README.md +3 -3
- package/package.json +5 -4
- package/src/backend/js/expressions.js +849 -371
- package/src/backend/js/index.js +241 -147
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +512 -2547
- package/src/backend/js/statements.js +506 -103
- package/src/backend/js/stdlib/index.js +45 -93
- package/src/backend/js/templ.js +32 -45
- package/src/backend/js/type-info.js +177 -13
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +63 -171
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +490 -965
- package/src/backend/wasm/emit-builtins.js +643 -256
- package/src/backend/wasm/emit-exprs.js +124 -57
- package/src/backend/wasm/emit-maps.js +17 -367
- package/src/backend/wasm/emit-stmts.js +325 -75
- package/src/backend/wasm/emit.js +104 -13
- package/src/backend/wasm/globals.js +47 -8
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +36 -530
- package/src/backend/wasm/method-expr.js +12 -1
- package/src/backend/wasm/module-emitter.js +92 -717
- package/src/backend/wasm/monomorph.js +103 -6
- package/src/backend/wasm/natives.js +596 -0
- package/src/backend/wasm/prescan.js +5 -153
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -32
- package/src/backend/wasm/types.js +68 -20
- package/src/backend/wasm/variadic.js +3 -3
- package/src/cli/cli-core.js +5 -1
- package/src/cli/test-runner.js +115 -342
- package/src/compiler.js +108 -130
- package/src/lexer/lexer.js +105 -11
- package/src/lexer/templ-lexer.js +61 -18
- package/src/lexer/tokens.js +1 -0
- package/src/link/stdlib.js +354 -132
- package/src/link/type-names.js +148 -0
- package/src/link/wasm.js +30 -6
- package/src/lower/bounds.js +153 -0
- package/src/lower/captures.js +92 -33
- package/src/lower/embedding.js +32 -3
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +905 -0
- package/src/lower/functions.js +2 -0
- package/src/lower/gen-types.js +274 -0
- package/src/lower/index.js +7 -1
- package/src/lower/json-codecs.js +228 -247
- package/src/lower/ownership.js +25 -7
- package/src/lower/reachability.js +69 -51
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +28 -5
- package/src/parser/expressions.js +86 -16
- package/src/parser/statements.js +1 -0
- package/src/parser/templ.js +44 -5
- package/src/parser/types.js +1 -0
- package/src/resolver.js +1 -2
- package/src/typechecker/assignability.js +124 -11
- package/src/typechecker/const-fold.js +70 -27
- package/src/typechecker/constants.js +32 -6
- package/src/typechecker/expressions.js +326 -98
- package/src/typechecker/index.js +208 -33
- package/src/typechecker/init-order.js +136 -40
- package/src/typechecker/operand-text.js +40 -0
- package/src/typechecker/resolve.js +192 -36
- package/src/typechecker/statements.js +122 -11
- package/src/typechecker/stdlib/excluded.js +9 -5
- package/src/typechecker/stdlib/index.js +25 -9
- package/src/typechecker/termination.js +10 -1
- package/src/typechecker/types.js +203 -573
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -0
- package/stdlib/context/context.go +115 -0
- package/stdlib/crypto/rand/rand.go +34 -0
- package/stdlib/crypto/sha256/sha256.go +249 -0
- package/stdlib/encoding/base64/base64.go +331 -0
- package/stdlib/encoding/binary/binary.go +332 -0
- package/stdlib/encoding/hex/hex.go +140 -0
- package/stdlib/encoding/json/json.go +62 -0
- package/stdlib/errors/errors.go +174 -0
- package/stdlib/fmt/errors.go +110 -0
- package/stdlib/fmt/format.go +732 -0
- package/stdlib/fmt/print.go +1232 -0
- package/stdlib/gom/gom.go +293 -0
- package/stdlib/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +171 -38
- package/stdlib/internal/jsonrt/enc.go +186 -36
- package/stdlib/internal/jsonrt/scanner.go +17 -8
- package/stdlib/io/io.go +157 -1
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +16 -14
- package/stdlib/math/math.go +439 -0
- package/stdlib/math/rand/rand.go +297 -0
- package/stdlib/os/os.go +93 -0
- package/stdlib/path/filepath/filepath.go +47 -0
- package/stdlib/path/path.go +394 -0
- package/stdlib/regexp/regexp.go +231 -0
- package/stdlib/slices/slices.go +526 -0
- package/stdlib/slices/sort.go +209 -0
- package/stdlib/slices/zsort_cmp.go +480 -0
- package/stdlib/slices/zsort_ordered.go +482 -0
- package/stdlib/sort/sort.go +391 -452
- package/stdlib/sort/zsort_func.go +480 -0
- package/stdlib/sort/zsort_iface.go +480 -0
- package/stdlib/strconv/float.go +1699 -0
- package/stdlib/strconv/isprint.go +752 -0
- package/stdlib/strconv/quote.go +235 -50
- package/stdlib/strconv/strconv.go +616 -0
- package/stdlib/strings/builder.go +95 -0
- package/stdlib/strings/reader.go +163 -0
- package/stdlib/strings/replacer.go +102 -0
- package/stdlib/strings/strings.go +807 -0
- package/stdlib/sync/sync.go +268 -0
- package/stdlib/testing/async_js.go +61 -0
- package/stdlib/testing/benchmark.go +297 -0
- package/stdlib/testing/testing.go +523 -0
- package/stdlib/time/duration.go +233 -0
- package/stdlib/time/format.go +745 -0
- package/stdlib/time/parse.go +790 -0
- package/stdlib/time/sleep_js.go +63 -0
- package/stdlib/time/time.go +834 -0
- package/stdlib/unicode/unicode.go +141 -3
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/fmt-runtime.js +0 -573
- package/src/backend/js/stdlib/base64.js +0 -12
- package/src/backend/js/stdlib/binary.js +0 -102
- package/src/backend/js/stdlib/bits.js +0 -119
- package/src/backend/js/stdlib/builder.js +0 -98
- package/src/backend/js/stdlib/bytes.js +0 -368
- package/src/backend/js/stdlib/errors.js +0 -45
- package/src/backend/js/stdlib/fmt.js +0 -517
- package/src/backend/js/stdlib/gom.js +0 -155
- package/src/backend/js/stdlib/hex.js +0 -17
- package/src/backend/js/stdlib/html.js +0 -20
- package/src/backend/js/stdlib/io.js +0 -137
- package/src/backend/js/stdlib/json.js +0 -1167
- package/src/backend/js/stdlib/maps.js +0 -37
- package/src/backend/js/stdlib/math.js +0 -85
- package/src/backend/js/stdlib/os.js +0 -13
- package/src/backend/js/stdlib/path.js +0 -48
- package/src/backend/js/stdlib/rand.js +0 -32
- package/src/backend/js/stdlib/regexp.js +0 -54
- package/src/backend/js/stdlib/sha256.js +0 -12
- package/src/backend/js/stdlib/shared.js +0 -17
- package/src/backend/js/stdlib/simd.js +0 -34
- package/src/backend/js/stdlib/slices.js +0 -107
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -79
- package/src/backend/js/stdlib/strings.js +0 -301
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -41
- package/src/backend/js/stdlib/time.js +0 -152
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/stdlib/bytes.js +0 -6716
- package/src/backend/wasm/stdlib/core.js +0 -10278
- package/src/backend/wasm/stdlib/io.js +0 -3578
- package/src/backend/wasm/stdlib/packages.js +0 -2402
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -2229
- package/src/typechecker/stdlib/core.js +0 -1079
- package/src/typechecker/stdlib/extended.js +0 -1210
- package/stdlib/bytes/iter.go +0 -192
- package/stdlib/bytes/search.go +0 -240
- package/stdlib/bytes/split.go +0 -218
- package/stdlib/errors/overlay.go +0 -12
- package/stdlib/maps/iter.go +0 -65
- package/stdlib/slices/extra.go +0 -73
- package/stdlib/slices/iter.go +0 -113
- package/stdlib/strings/extra.go +0 -35
- package/stdlib/strings/iter.go +0 -122
- package/stdlib/sync/extra.go +0 -105
- package/stdlib/unicode/utf8/bytes.go +0 -239
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// CodeGen for Go `maps` package.
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
/** @type {ThisType<CodeGen>} */
|
|
6
|
-
export const mapsMethods = {
|
|
7
|
-
_genMaps(fn, a) {
|
|
8
|
-
if (fn === "Equal") {
|
|
9
|
-
this.useHelper("equal");
|
|
10
|
-
const [a1, b1] = a();
|
|
11
|
-
return `__equal(${a1}, ${b1})`;
|
|
12
|
-
}
|
|
13
|
-
switch (fn) {
|
|
14
|
-
case "Clone": {
|
|
15
|
-
const [m] = a();
|
|
16
|
-
return `({...${m}})`;
|
|
17
|
-
}
|
|
18
|
-
case "Copy": {
|
|
19
|
-
const [dst, src] = a();
|
|
20
|
-
return `Object.assign(${dst}, ${src})`;
|
|
21
|
-
}
|
|
22
|
-
case "EqualFunc": {
|
|
23
|
-
const [m1, m2, eq] = a();
|
|
24
|
-
return `((a, b, f) => { const ka = Object.keys(a); if (ka.length !== Object.keys(b).length) return false; return ka.every(k => k in b && f(a[k], b[k])); })(${m1}, ${m2}, ${eq})`;
|
|
25
|
-
}
|
|
26
|
-
case "Delete": {
|
|
27
|
-
const [m, k] = a();
|
|
28
|
-
return `(delete ${m}[${k}], undefined)`;
|
|
29
|
-
}
|
|
30
|
-
case "DeleteFunc": {
|
|
31
|
-
const [m, fn2] = a();
|
|
32
|
-
return `Object.keys(${m}).forEach(k => { if (${fn2}(k, ${m}[k])) delete ${m}[k]; })`;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return undefined;
|
|
36
|
-
},
|
|
37
|
-
};
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
// CodeGen for Go `math` package.
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
const MATH1 = {
|
|
6
|
-
Abs: "abs",
|
|
7
|
-
Floor: "floor",
|
|
8
|
-
Ceil: "ceil",
|
|
9
|
-
Sqrt: "sqrt",
|
|
10
|
-
Cbrt: "cbrt",
|
|
11
|
-
Log: "log",
|
|
12
|
-
Log1p: "log1p",
|
|
13
|
-
Log2: "log2",
|
|
14
|
-
Log10: "log10",
|
|
15
|
-
Expm1: "expm1",
|
|
16
|
-
Sin: "sin",
|
|
17
|
-
Cos: "cos",
|
|
18
|
-
Tan: "tan",
|
|
19
|
-
Atan: "atan",
|
|
20
|
-
Asin: "asin",
|
|
21
|
-
Acos: "acos",
|
|
22
|
-
Exp: "exp",
|
|
23
|
-
Trunc: "trunc",
|
|
24
|
-
Sinh: "sinh",
|
|
25
|
-
Cosh: "cosh",
|
|
26
|
-
Tanh: "tanh",
|
|
27
|
-
};
|
|
28
|
-
const MATH2 = {
|
|
29
|
-
Pow: "pow",
|
|
30
|
-
Min: "min",
|
|
31
|
-
Max: "max",
|
|
32
|
-
Atan2: "atan2",
|
|
33
|
-
Hypot: "hypot",
|
|
34
|
-
};
|
|
35
|
-
const MATH_EXTRA = {
|
|
36
|
-
// Go rounds half away from zero; Math.round rounds half toward +Infinity.
|
|
37
|
-
Round: ([x]) => `(Math.sign(${x}) * Math.round(Math.abs(${x})))`,
|
|
38
|
-
Mod: ([x, y]) => `${x} % ${y}`,
|
|
39
|
-
Inf: ([x]) => `(${x} >= 0 ? Infinity : -Infinity)`,
|
|
40
|
-
IsNaN: ([x]) => `Number.isNaN(${x})`,
|
|
41
|
-
IsInf: ([x, y]) =>
|
|
42
|
-
`(${y} > 0 ? ${x} === Infinity : ${y} < 0 ? ${x} === -Infinity : Math.abs(${x}) === Infinity)`,
|
|
43
|
-
NaN: () => "NaN",
|
|
44
|
-
Exp2: ([x]) => `Math.pow(2, ${x})`,
|
|
45
|
-
Signbit: ([x]) => `(${x} < 0 || Object.is(${x}, -0))`,
|
|
46
|
-
Copysign: ([x, y]) =>
|
|
47
|
-
`(Math.abs(${x}) * (${y} < 0 || Object.is(${y}, -0) ? -1 : 1))`,
|
|
48
|
-
Dim: ([x, y]) => `Math.max(${x} - ${y}, 0)`,
|
|
49
|
-
Remainder: ([x, y]) =>
|
|
50
|
-
`((x, y) => { if (isNaN(x) || isNaN(y) || y === 0 || !isFinite(x)) return NaN; if (!isFinite(y)) return x; const q = x / y; const r = Math.round(q); const diff = Math.abs(q - r); const n = (diff === 0.5 && (r % 2 !== 0)) ? (r < q ? r + 1 : r - 1) : r; return x - n * y; })(${x}, ${y})`,
|
|
51
|
-
Frexp: ([x]) =>
|
|
52
|
-
`((f) => { if (f === 0 || !Number.isFinite(f)) return [f, 0]; const buf = new ArrayBuffer(8); const f64 = new Float64Array(buf); const u32 = new Uint32Array(buf); f64[0] = f; let hi = u32[1]; let exp = (hi >>> 20) & 0x7ff; if (exp === 0) { f64[0] = f * Math.pow(2, 54); hi = u32[1]; exp = ((hi >>> 20) & 0x7ff) - 54; } exp -= 1022; u32[1] = (hi & 0x800fffff) | 0x3fe00000; return [f64[0], exp]; })(${x})`,
|
|
53
|
-
Ldexp: ([frac, exp]) =>
|
|
54
|
-
`((frac, exp) => { if (frac === 0 || !Number.isFinite(frac)) return frac; if (exp > 1023) return frac < 0 ? -Infinity : Infinity; if (exp < -1074) return frac < 0 ? -0 : 0; if (exp >= -1022) return frac * Math.pow(2, exp); return frac * Math.pow(2, exp + 54) * Math.pow(2, -54); })(${frac}, ${exp})`,
|
|
55
|
-
Modf: ([f]) =>
|
|
56
|
-
`((x) => { if (Number.isNaN(x)) return [NaN, NaN]; if (!Number.isFinite(x)) return [x, NaN]; const i = Math.trunc(x); const frac = x === i ? (x < 0 || Object.is(x, -0) ? -0 : 0) : x - i; return [i, frac]; })(${f})`,
|
|
57
|
-
FMA: ([x, y, z]) =>
|
|
58
|
-
`((x, y, z) => { if (Number.isNaN(x) || Number.isNaN(y) || Number.isNaN(z)) return NaN; if ((x === 0 && !Number.isFinite(y)) || (y === 0 && !Number.isFinite(x))) return NaN; const p = x * y; if (!Number.isFinite(p) && !Number.isFinite(z) && ((p > 0 && z < 0) || (p < 0 && z > 0))) return NaN; return p + z; })(${x}, ${y}, ${z})`,
|
|
59
|
-
RoundToEven: ([x]) =>
|
|
60
|
-
`((x) => { if (x === 0 || !Number.isFinite(x)) return x; const t = Math.trunc(x); const f = Math.abs(x - t); if (f < 0.5) return Object.is(t, 0) && (x < 0 || Object.is(x, -0)) ? -0 : t; if (f > 0.5) return x > 0 ? t + 1 : t - 1; const res = t % 2 === 0 ? t : (x > 0 ? t + 1 : t - 1); return Object.is(res, 0) && (x < 0 || Object.is(x, -0)) ? -0 : res; })(${x})`,
|
|
61
|
-
Nextafter: ([x, y]) =>
|
|
62
|
-
`((x, y) => { if (Number.isNaN(x) || Number.isNaN(y)) return NaN; if (x === y) return x; if (x === 0) { const s = Number.MIN_VALUE; return y > 0 ? s : -s; } const buf = new ArrayBuffer(8); const f64 = new Float64Array(buf); const i64 = new BigInt64Array(buf); f64[0] = x; let b = i64[0]; if ((x > 0 && y > x) || (x < 0 && y > x)) b = b + (x > 0 ? 1n : -1n); else b = b + (x > 0 ? -1n : 1n); i64[0] = b; return f64[0]; })(${x}, ${y})`,
|
|
63
|
-
Nextafter32: ([x, y]) =>
|
|
64
|
-
`((x, y) => { if (Number.isNaN(x) || Number.isNaN(y)) return NaN; if (x === y) return x; if (x === 0) { const s = 1.401298464324817e-45; return y > 0 ? s : -s; } const buf = new ArrayBuffer(4); const f32 = new Float32Array(buf); const i32 = new Int32Array(buf); f32[0] = x; let b = i32[0]; if ((x > 0 && y > x) || (x < 0 && y > x)) b = b + (x > 0 ? 1 : -1); else b = b + (x > 0 ? -1 : 1); i32[0] = b; return f32[0]; })(${x}, ${y})`,
|
|
65
|
-
Float64bits: ([x]) =>
|
|
66
|
-
`((f) => { const b = new ArrayBuffer(8); new Float64Array(b)[0] = f; return Number(new BigUint64Array(b)[0]); })(${x})`,
|
|
67
|
-
Float64frombits: ([b]) =>
|
|
68
|
-
`((u) => { const buf = new ArrayBuffer(8); new BigUint64Array(buf)[0] = BigInt(u); return new Float64Array(buf)[0]; })(${b})`,
|
|
69
|
-
Float32bits: ([x]) =>
|
|
70
|
-
`((f) => { const b = new ArrayBuffer(4); new Float32Array(b)[0] = f; return new Uint32Array(b)[0]; })(${x})`,
|
|
71
|
-
Float32frombits: ([b]) =>
|
|
72
|
-
`((u) => { const buf = new ArrayBuffer(4); new Uint32Array(buf)[0] = Number(u) >>> 0; return new Float32Array(buf)[0]; })(${b})`,
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/** @type {ThisType<CodeGen>} */
|
|
76
|
-
export const mathMethods = {
|
|
77
|
-
_genMath(fn, a) {
|
|
78
|
-
const args = a();
|
|
79
|
-
const [x, y] = args;
|
|
80
|
-
if (MATH1[fn]) return `Math.${MATH1[fn]}(${x})`;
|
|
81
|
-
if (MATH2[fn]) return `Math.${MATH2[fn]}(${x}, ${y})`;
|
|
82
|
-
const gen = MATH_EXTRA[fn];
|
|
83
|
-
return gen ? gen(args) : undefined;
|
|
84
|
-
},
|
|
85
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// CodeGen for Go `os` package.
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
/** @type {ThisType<CodeGen>} */
|
|
6
|
-
export const osMethods = {
|
|
7
|
-
_genOs(fn, a) {
|
|
8
|
-
const args = a();
|
|
9
|
-
if (fn === "Exit") return `process.exit(${args[0]})`;
|
|
10
|
-
if (fn === "Getenv") return `(process.env[${args[0]}] ?? "")`;
|
|
11
|
-
return undefined;
|
|
12
|
-
},
|
|
13
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
// CodeGen for Go `path` package.
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
const PATH_DISPATCH = {
|
|
6
|
-
Base: (a) =>
|
|
7
|
-
`((p) => { if (!p) return "."; const stripped = p.replace(/\\/+$/, ""); if (!stripped) return "/"; const i = stripped.lastIndexOf("/"); return i < 0 ? stripped : stripped.slice(i + 1) || "/"; })(${a[0]})`,
|
|
8
|
-
Dir: (a) =>
|
|
9
|
-
`((p) => { const i = p.lastIndexOf("/"); if (i < 0) return "."; const res = p.slice(0, i); return res === "" ? "/" : __pathClean(res); })(${a[0]})`,
|
|
10
|
-
Ext: (a) =>
|
|
11
|
-
`((p) => { const b = p.slice(p.lastIndexOf("/") + 1); const i = b.lastIndexOf("."); return i <= 0 ? "" : b.slice(i); })(${a[0]})`,
|
|
12
|
-
IsAbs: (a) => `(${a[0]}).startsWith("/")`,
|
|
13
|
-
Split: (a) =>
|
|
14
|
-
`((p) => { const i = p.lastIndexOf("/"); return i < 0 ? ["", p] : [p.slice(0, i + 1), p.slice(i + 1)]; })(${a[0]})`,
|
|
15
|
-
Match: (a) =>
|
|
16
|
-
`((pat, name) => { const [m, err] = __pathMatch(pat, name); return [m, err ? __path_err_bad_pattern : null]; })(${a[0]}, ${a[1]})`,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/** @type {ThisType<CodeGen>} */
|
|
20
|
-
export const pathMethods = {
|
|
21
|
-
_genPath(fn, a, expr) {
|
|
22
|
-
if (fn === "Match") {
|
|
23
|
-
this.useHelper("error");
|
|
24
|
-
this.useHelper("pathError");
|
|
25
|
-
this.useHelper("pathClean");
|
|
26
|
-
}
|
|
27
|
-
if (fn === "Dir") {
|
|
28
|
-
this.useHelper("pathClean");
|
|
29
|
-
}
|
|
30
|
-
if (fn === "Join") {
|
|
31
|
-
this.useHelper("pathClean");
|
|
32
|
-
const allArgs = expr.args
|
|
33
|
-
.map((e) =>
|
|
34
|
-
e._spread || expr.ellipsis
|
|
35
|
-
? `...(${this.genExpr(e)})`
|
|
36
|
-
: this.genExpr(e),
|
|
37
|
-
)
|
|
38
|
-
.join(", ");
|
|
39
|
-
return `((arr) => arr.length === 0 ? "" : __pathClean(arr.join("/")))([${allArgs}].filter(x => x !== ""))`;
|
|
40
|
-
}
|
|
41
|
-
if (fn === "Clean") {
|
|
42
|
-
this.useHelper("pathClean");
|
|
43
|
-
return `__pathClean(${a()[0]})`;
|
|
44
|
-
}
|
|
45
|
-
const gen = PATH_DISPATCH[fn];
|
|
46
|
-
return gen ? gen(a()) : undefined;
|
|
47
|
-
},
|
|
48
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// CodeGen for Go `math/rand` package.
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
const RAND_DISPATCH = {
|
|
6
|
-
Intn: (a) =>
|
|
7
|
-
`((n) => { if (n <= 0) throw new Error("invalid argument to Intn"); return Math.floor(Math.random() * n); })(${a[0]})`,
|
|
8
|
-
Int63n: (a) =>
|
|
9
|
-
`((n) => { if (n <= 0) throw new Error("invalid argument to Int63n"); return Math.floor(Math.random() * n); })(${a[0]})`,
|
|
10
|
-
Int31n: (a) =>
|
|
11
|
-
`((n) => { if (n <= 0) throw new Error("invalid argument to Int31n"); return Math.floor(Math.random() * n); })(${a[0]})`,
|
|
12
|
-
Float64: () => "Math.random()",
|
|
13
|
-
Float32: () => "Math.random()",
|
|
14
|
-
Int: () => "Math.floor(Math.random() * 2147483647)",
|
|
15
|
-
Int31: () => "Math.floor(Math.random() * 2147483647)",
|
|
16
|
-
Int63: () => "Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)",
|
|
17
|
-
Seed: () => "(void 0)",
|
|
18
|
-
Shuffle: (a) =>
|
|
19
|
-
`((n, f) => { if (n < 0) throw new Error("invalid argument to Shuffle"); for (let i = n - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); f(i, j); } })(${a[0]}, ${a[1]})`,
|
|
20
|
-
Perm: (a) =>
|
|
21
|
-
`((n) => { if (n < 0) throw new Error("invalid argument to Perm"); const a = Array.from({length: n}, (_, i) => i); for (let i = n - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; })(${a[0]})`,
|
|
22
|
-
Read: (a) => `__crypto_rand_read(${a[0]})`,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/** @type {ThisType<CodeGen>} */
|
|
26
|
-
export const randMethods = {
|
|
27
|
-
_genRand(fn, a) {
|
|
28
|
-
if (fn === "Read") this.useHelper("cryptoRand");
|
|
29
|
-
const gen = RAND_DISPATCH[fn];
|
|
30
|
-
return gen ? gen(a()) : undefined;
|
|
31
|
-
},
|
|
32
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// CodeGen for Go `regexp` package and `*Regexp` methods.
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
const REGEXP_METHOD = {
|
|
6
|
-
MatchString: (re, a) => `${re}.test(${a[0]})`,
|
|
7
|
-
FindString: (re, a) => `(${re}.exec(${a[0]})?.[0] ?? "")`,
|
|
8
|
-
FindStringIndex: (re, a) =>
|
|
9
|
-
`((m => m ? [m.index, m.index + m[0].length] : null)(${re}.exec(${a[0]})))`,
|
|
10
|
-
FindAllString: (re, a) =>
|
|
11
|
-
`[...${a[0]}.matchAll(new RegExp(${re}.source, ${re}.flags.includes("g") ? ${re}.flags : ${re}.flags + "g"))].slice(0, ${a[1]} < 0 ? undefined : ${a[1]}).map(m => m[0])`,
|
|
12
|
-
FindStringSubmatch: (re, a) => `[...(${re}.exec(${a[0]}) ?? [])]`,
|
|
13
|
-
FindAllStringSubmatch: (re, a) =>
|
|
14
|
-
`[...${a[0]}.matchAll(new RegExp(${re}.source, ${re}.flags.includes("g") ? ${re}.flags : ${re}.flags + "g"))].slice(0, ${a[1]} < 0 ? undefined : ${a[1]}).map(m => [...m])`,
|
|
15
|
-
ReplaceAllString: (re, a) =>
|
|
16
|
-
`${a[0]}.replaceAll(new RegExp(${re}.source, ${re}.flags.includes("g") ? ${re}.flags : ${re}.flags + "g"), ${a[1]})`,
|
|
17
|
-
ReplaceAllLiteralString: (re, a) =>
|
|
18
|
-
`${a[0]}.replaceAll(new RegExp(${re}.source, ${re}.flags.includes("g") ? ${re}.flags : ${re}.flags + "g"), ${a[1]}.replace(/\\$/g, '$$$$'))`,
|
|
19
|
-
Split: (re, a) =>
|
|
20
|
-
`${a[0]}.split(${re}).slice(0, ${a[1]} < 0 ? undefined : ${a[1]})`,
|
|
21
|
-
String: (re) => `${re}.source`,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/** @type {ThisType<CodeGen>} */
|
|
25
|
-
export const regexpMethods = {
|
|
26
|
-
_genRegexp(fn, a) {
|
|
27
|
-
// Converts a Go regexp pattern string (which may contain inline flags like (?i))
|
|
28
|
-
// into a JS RegExp, extracting the flags into the second constructor argument.
|
|
29
|
-
const makeRegExp = (pat) =>
|
|
30
|
-
`((p) => { const m = /^\\(\\?([gimsuy]+)\\)/.exec(p); return m ? new RegExp(p.slice(m[0].length), m[1]) : new RegExp(p); })(${pat})`;
|
|
31
|
-
switch (fn) {
|
|
32
|
-
case "MustCompile":
|
|
33
|
-
return makeRegExp(a()[0]);
|
|
34
|
-
case "Compile":
|
|
35
|
-
return `[${makeRegExp(a()[0])}, null]`;
|
|
36
|
-
case "MatchString": {
|
|
37
|
-
const [pat, s] = a();
|
|
38
|
-
return `[new RegExp(${pat}).test(${s}), null]`;
|
|
39
|
-
}
|
|
40
|
-
case "QuoteMeta":
|
|
41
|
-
return `${a()[0]}.replace(/[.*+?^\${}()|[\\]\\\\]/g, '\\\\$&')`;
|
|
42
|
-
}
|
|
43
|
-
return undefined;
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
_genRegexpMethodCall(method, expr) {
|
|
47
|
-
const recv = expr.func.expr;
|
|
48
|
-
// *Regexp is a plain JS RegExp — no .value boxing needed
|
|
49
|
-
const re = this.genExpr(recv);
|
|
50
|
-
const args = expr.args.map((a) => this.genExpr(a));
|
|
51
|
-
const gen = REGEXP_METHOD[method];
|
|
52
|
-
return gen ? gen(re, args) : undefined;
|
|
53
|
-
},
|
|
54
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// src/backend/js/stdlib/sha256.js
|
|
2
|
-
// CodeGen for Go crypto/sha256 package.
|
|
3
|
-
|
|
4
|
-
export const sha256Methods = {
|
|
5
|
-
_genSha256(fn, a) {
|
|
6
|
-
this.useHelper("sha256");
|
|
7
|
-
const args = a();
|
|
8
|
-
if (fn === "Sum256") return `__sha256.Sum256(${args[0]})`;
|
|
9
|
-
if (fn === "New") return "__sha256.New()";
|
|
10
|
-
return undefined;
|
|
11
|
-
},
|
|
12
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// CodeGen for the `gofront/shared` package: in js packages a shared buffer is
|
|
2
|
-
// just a TypedArray (no linear memory is involved); in wasm packages the facade
|
|
3
|
-
// hands out zero-copy views onto the module memory.
|
|
4
|
-
|
|
5
|
-
import { SHARED_KINDS } from "../../../typechecker/stdlib/shared.js";
|
|
6
|
-
|
|
7
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
8
|
-
|
|
9
|
-
/** @type {ThisType<CodeGen>} */
|
|
10
|
-
export const sharedMethods = {
|
|
11
|
-
_genShared(fn, a) {
|
|
12
|
-
if (!fn.startsWith("New")) return undefined;
|
|
13
|
-
const info = SHARED_KINDS[fn.slice(3)];
|
|
14
|
-
if (!info) return undefined;
|
|
15
|
-
return `new ${info.ctor}(${a()[0]})`;
|
|
16
|
-
},
|
|
17
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// src/backend/js/stdlib/simd.js
|
|
2
|
-
// CodeGen for the `gofront/simd` package in JS packages.
|
|
3
|
-
|
|
4
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
5
|
-
|
|
6
|
-
/** @type {ThisType<CodeGen>} */
|
|
7
|
-
export const simdMethods = {
|
|
8
|
-
_genSimd(fn, a) {
|
|
9
|
-
this.useHelper("simd");
|
|
10
|
-
const args = a();
|
|
11
|
-
switch (fn) {
|
|
12
|
-
case "Splat":
|
|
13
|
-
return `__simd_splat(${args[0]})`;
|
|
14
|
-
case "NewF32x4":
|
|
15
|
-
return `__simd_f32x4(${args[0]}, ${args[1]}, ${args[2]}, ${args[3]})`;
|
|
16
|
-
case "Select":
|
|
17
|
-
return `__simd_select(${args[0]}, ${args[1]}, ${args[2]})`;
|
|
18
|
-
case "Shuffle":
|
|
19
|
-
return `__simd_shuffle(${args.join(", ")})`;
|
|
20
|
-
case "LoadF32x4":
|
|
21
|
-
return `__simd_load(${args[0]}, ${args[1]})`;
|
|
22
|
-
case "StoreF32x4":
|
|
23
|
-
return `__simd_store(${args[0]}, ${args[1]}, ${args[2]})`;
|
|
24
|
-
case "LoadF32x4Slice":
|
|
25
|
-
return `__simd_load_slice(${args[0]}, ${args[1]})`;
|
|
26
|
-
case "StoreF32x4Slice":
|
|
27
|
-
return `__simd_store_slice(${args[0]}, ${args[1]}, ${args[2]})`;
|
|
28
|
-
case "Pad4":
|
|
29
|
-
return `(Math.floor((${args[0]} + 3) / 4) * 4)`;
|
|
30
|
-
default:
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
};
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { isTypedArraySlice } from "../../../typechecker/types.js";
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
const SLICES_DISPATCH = {
|
|
6
|
-
Contains: (a) => `${a[0]}.includes(${a[1]})`,
|
|
7
|
-
ContainsFunc: (a) =>
|
|
8
|
-
`((s, f) => { s = s || []; for (let i = 0; i < s.length; i++) { if (f(s[i])) return true; } return false; })(${a[0]}, ${a[1]})`,
|
|
9
|
-
Index: (a) => `${a[0]}.indexOf(${a[1]})`,
|
|
10
|
-
IndexFunc: (a) =>
|
|
11
|
-
`((s, f) => { s = s || []; for (let i = 0; i < s.length; i++) { if (f(s[i])) return i; } return -1; })(${a[0]}, ${a[1]})`,
|
|
12
|
-
BinarySearch: (a) =>
|
|
13
|
-
`((s, target) => { s = s || []; let i = 0, j = s.length; while (i < j) { const h = (i + j) >>> 1; if (s[h] < target) i = h + 1; else j = h; } return [i, i < s.length && s[i] === target]; })(${a[0]}, ${a[1]})`,
|
|
14
|
-
BinarySearchFunc: (a) =>
|
|
15
|
-
`((s, target, cmp) => { s = s || []; let i = 0, j = s.length; while (i < j) { const h = (i + j) >>> 1; if (cmp(s[h], target) < 0) i = h + 1; else j = h; } return [i, i < s.length && cmp(s[i], target) === 0]; })(${a[0]}, ${a[1]}, ${a[2]})`,
|
|
16
|
-
Compare: (a) =>
|
|
17
|
-
`((a, b) => { a = a || []; b = b || []; for (let i = 0; i < a.length && i < b.length; i++) { const x = a[i], y = b[i]; const xN = typeof x === "number" && isNaN(x), yN = typeof y === "number" && isNaN(y); if (xN && yN) continue; if (xN) return -1; if (yN) return 1; if (x < y) return -1; if (x > y) return 1; } return a.length < b.length ? -1 : a.length > b.length ? 1 : 0; })(${a[0]}, ${a[1]})`,
|
|
18
|
-
Sort: (a) =>
|
|
19
|
-
`((s) => s ? s.sort((a, b) => a < b ? -1 : a > b ? 1 : 0) : null)(${a[0]})`,
|
|
20
|
-
SortFunc: (a) => `((s, f) => s ? s.sort(f) : null)(${a[0]}, ${a[1]})`,
|
|
21
|
-
SortStableFunc: (a) => `((s, f) => s ? s.sort(f) : null)(${a[0]}, ${a[1]})`,
|
|
22
|
-
IsSorted: (a) =>
|
|
23
|
-
`((s) => { s = s || []; for (let i = 0; i < s.length; i++) { if (typeof s[i] === "number" && isNaN(s[i])) return false; if (i > 0 && s[i] < s[i-1]) return false; } return true; })(${a[0]})`,
|
|
24
|
-
IsSortedFunc: (a) =>
|
|
25
|
-
`((s, f) => { s = s || []; for (let i = 1; i < s.length; i++) { if (f(s[i], s[i-1]) < 0) return false; } return true; })(${a[0]}, ${a[1]})`,
|
|
26
|
-
Reverse: (a) => `((s) => s ? s.reverse() : null)(${a[0]})`,
|
|
27
|
-
Max: (a) =>
|
|
28
|
-
`((s) => { if (!s || s.length === 0) throw new Error("slices.Max: empty list"); let m = s[0]; for (let i = 1; i < s.length; i++) { const x = s[i]; if ((typeof x === "number" && isNaN(x)) || x > m || (x === 0 && m === 0 && Object.is(m, -0) && !Object.is(x, -0))) m = x; } return m; })(${a[0]})`,
|
|
29
|
-
Min: (a) =>
|
|
30
|
-
`((s) => { if (!s || s.length === 0) throw new Error("slices.Min: empty list"); let m = s[0]; for (let i = 1; i < s.length; i++) { const x = s[i]; if ((typeof x === "number" && isNaN(x)) || x < m || (x === 0 && m === 0 && Object.is(x, -0))) m = x; } return m; })(${a[0]})`,
|
|
31
|
-
MaxFunc: (a) =>
|
|
32
|
-
`((s, f) => { if (!s || s.length === 0) throw new Error("slices.MaxFunc: empty list"); return s.reduce((m, x) => f(x, m) > 0 ? x : m); })(${a[0]}, ${a[1]})`,
|
|
33
|
-
MinFunc: (a) =>
|
|
34
|
-
`((s, f) => { if (!s || s.length === 0) throw new Error("slices.MinFunc: empty list"); return s.reduce((m, x) => f(x, m) < 0 ? x : m); })(${a[0]}, ${a[1]})`,
|
|
35
|
-
Clone: (a) => `((s) => s ? s.slice() : null)(${a[0]})`,
|
|
36
|
-
Compact: (a) =>
|
|
37
|
-
`((s) => { if (!s || s.length === 0) return s; let k = 1; for (let i = 1; i < s.length; i++) { if (s[i] !== s[k - 1]) s[k++] = s[i]; } return s[__sv] !== undefined ? __slice(s, 0, k) : ArrayBuffer.isView(s) ? s.subarray(0, k) : (s.length = k, s); })(${a[0]})`,
|
|
38
|
-
CompactFunc: (a) =>
|
|
39
|
-
`((s, f) => { if (!s || s.length === 0) return s; let k = 1; for (let i = 1; i < s.length; i++) { if (!f(s[i], s[k - 1])) s[k++] = s[i]; } return s[__sv] !== undefined ? __slice(s, 0, k) : ArrayBuffer.isView(s) ? s.subarray(0, k) : (s.length = k, s); })(${a[0]}, ${a[1]})`,
|
|
40
|
-
Concat: (a) =>
|
|
41
|
-
a.length === 0
|
|
42
|
-
? "null"
|
|
43
|
-
: `((...slices) => { const nonNull = slices.filter(Boolean); if (nonNull.length === 0) return slices[0] === null ? null : []; if (ArrayBuffer.isView(nonNull[0])) { const totalLen = nonNull.reduce((sum, s) => sum + s.length, 0); const out = new nonNull[0].constructor(totalLen); let off = 0; for (const s of nonNull) { out.set(s, off); off += s.length; } return out; } return [].concat(...slices.map(s => s ? (ArrayBuffer.isView(s) ? Array.from(s) : s) : [])); })(${a.map((x) => `(${x})`).join(", ")})`,
|
|
44
|
-
Delete: (a) =>
|
|
45
|
-
`((s, i, j) => { if (!s && i === 0 && j === 0) return s; s = s || []; if (i < 0 || j < i || j > s.length) throw new Error("runtime error: slice bounds out of range"); if (ArrayBuffer.isView(s)) { s.copyWithin(i, j); return s.subarray(0, s.length - (j - i)); } if (s[__sv] !== undefined) { s.copyWithin(i, j); return __slice(s, 0, s.length - (j - i)); } s.splice(i, j - i); return s; })(${a[0]}, ${a[1]}, ${a[2]})`,
|
|
46
|
-
DeleteFunc: (a) =>
|
|
47
|
-
`((s, f) => { if (!s || s.length === 0) return s; let k = 0; for (let i = 0; i < s.length; i++) { if (!f(s[i])) s[k++] = s[i]; } return s[__sv] !== undefined ? __slice(s, 0, k) : ArrayBuffer.isView(s) ? s.subarray(0, k) : (s.length = k, s); })(${a[0]}, ${a[1]})`,
|
|
48
|
-
Insert: (a, isTyped) => {
|
|
49
|
-
const items = a.slice(2);
|
|
50
|
-
const nilInit = isTyped ? "new Uint8Array(0)" : "[]";
|
|
51
|
-
return `((s, i, ...v) => { if (!s && i === 0) s = ${nilInit}; if (!s || i < 0 || i > s.length) throw new Error("runtime error: slice bounds out of range"); if (ArrayBuffer.isView(s)) { const res = new s.constructor(s.length + v.length); res.set(s.subarray(0, i), 0); res.set(v, i); res.set(s.subarray(i), i + v.length); return res; } if (s[__sv] !== undefined) s = Array.from(s); s.splice(i, 0, ...v); return s; })(${a[0]}, ${a[1]}${items.length ? `, ${items.join(", ")}` : ""})`;
|
|
52
|
-
},
|
|
53
|
-
Replace: (a, isTyped) => {
|
|
54
|
-
const items = a.slice(3);
|
|
55
|
-
const nilInit = isTyped ? "new Uint8Array(0)" : "[]";
|
|
56
|
-
return `((s, i, j, ...v) => { if (!s && i === 0 && j === 0) s = ${nilInit}; if (!s || i < 0 || j < i || j > s.length) throw new Error("runtime error: slice bounds out of range"); if (ArrayBuffer.isView(s)) { const res = new s.constructor(s.length - (j - i) + v.length); res.set(s.subarray(0, i), 0); res.set(v, i); res.set(s.subarray(j), i + v.length); return res; } if (s[__sv] !== undefined) s = Array.from(s); s.splice(i, j - i, ...v); return s; })(${a[0]}, ${a[1]}, ${a[2]}${items.length ? `, ${items.join(", ")}` : ""})`;
|
|
57
|
-
},
|
|
58
|
-
Grow: (a, isTyped) => {
|
|
59
|
-
const nilInit = isTyped ? "new Uint8Array(0)" : "[]";
|
|
60
|
-
return `((s, n) => { if (n < 0) throw new Error("runtime error: makeslice: len out of range"); if (!s) return ${nilInit}; return s.slice(); })(${a[0]}, ${a[1]})`;
|
|
61
|
-
},
|
|
62
|
-
Clip: (a) => `((s) => s ? s.slice() : null)(${a[0]})`,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const VIEW_AWARE = new Set([
|
|
66
|
-
"Compact",
|
|
67
|
-
"CompactFunc",
|
|
68
|
-
"Delete",
|
|
69
|
-
"DeleteFunc",
|
|
70
|
-
"Insert",
|
|
71
|
-
"Replace",
|
|
72
|
-
]);
|
|
73
|
-
|
|
74
|
-
/** @type {ThisType<CodeGen>} */
|
|
75
|
-
export const slicesMethods = {
|
|
76
|
-
_genSlices(fn, a, expr) {
|
|
77
|
-
if (fn === "Equal") {
|
|
78
|
-
this.useHelper("equal");
|
|
79
|
-
const [a1, b1] = a();
|
|
80
|
-
return `__equal(${a1}, ${b1})`;
|
|
81
|
-
}
|
|
82
|
-
// Struct and array elements are values: compare them field by field
|
|
83
|
-
// (`.includes` and `.indexOf` compare object identity).
|
|
84
|
-
if (
|
|
85
|
-
(fn === "Contains" || fn === "Index") &&
|
|
86
|
-
this._sliceElemIsAggregate(expr)
|
|
87
|
-
) {
|
|
88
|
-
this.useHelper("equal");
|
|
89
|
-
const [s1, v1] = a();
|
|
90
|
-
const found = fn === "Contains" ? "true" : "i";
|
|
91
|
-
const missing = fn === "Contains" ? "false" : "-1";
|
|
92
|
-
return `((s, v) => { s = s || []; for (let i = 0; i < s.length; i++) { if (__equal(s[i], v)) return ${found}; } return ${missing}; })(${s1}, ${v1})`;
|
|
93
|
-
}
|
|
94
|
-
const isTyped = isTypedArraySlice(expr?.args?.[0]?._type);
|
|
95
|
-
const gen = SLICES_DISPATCH[fn];
|
|
96
|
-
// These shrink or grow the slice in place; a slice view (`__sv`) has a
|
|
97
|
-
// fixed length, so they reslice it or copy it to a plain array.
|
|
98
|
-
if (VIEW_AWARE.has(fn)) this.useHelper("slice");
|
|
99
|
-
return gen ? gen(a(), isTyped) : undefined;
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
_sliceElemIsAggregate(expr) {
|
|
103
|
-
let t = expr?.args?.[0]?._type;
|
|
104
|
-
while (t?.kind === "named") t = t.underlying;
|
|
105
|
-
return t?.kind === "slice" && Boolean(this._aggregateBase(t.elem));
|
|
106
|
-
},
|
|
107
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// CodeGen for Go `sort` package.
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
const SORT_DISPATCH = {
|
|
6
|
-
Ints: (a) => `${a[0]}.sort((a, b) => a - b)`,
|
|
7
|
-
Float64s: (a) => `${a[0]}.sort((a, b) => a - b)`,
|
|
8
|
-
Strings: (a) => `${a[0]}.sort()`,
|
|
9
|
-
Slice: (a) => `__sortSlice(${a[0]}, ${a[1]})`,
|
|
10
|
-
SliceStable: (a) => `__sortSlice(${a[0]}, ${a[1]})`,
|
|
11
|
-
SliceIsSorted: (a) =>
|
|
12
|
-
`((s, less) => { for (let i = (s?.length ?? 0) - 1; i > 0; i--) if (less(i, i - 1)) return false; return true; })(${a[0]}, ${a[1]})`,
|
|
13
|
-
Search: (a) =>
|
|
14
|
-
`((n, f) => { let lo = 0, hi = n; while (lo < hi) { const mid = (lo + hi) >>> 1; if (f(mid)) hi = mid; else lo = mid + 1; } return lo; })(${a[0]}, ${a[1]})`,
|
|
15
|
-
IntsAreSorted: (a) =>
|
|
16
|
-
`(${a[0]}).every((v, i, a) => i === 0 || a[i - 1] <= v)`,
|
|
17
|
-
Float64sAreSorted: (a) =>
|
|
18
|
-
`(${a[0]}).every((v, i, a) => i === 0 || a[i - 1] <= v)`,
|
|
19
|
-
StringsAreSorted: (a) =>
|
|
20
|
-
`(${a[0]}).every((v, i, a) => i === 0 || a[i - 1] <= v)`,
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/** @type {ThisType<CodeGen>} */
|
|
24
|
-
export const sortMethods = {
|
|
25
|
-
_genSort(fn, a) {
|
|
26
|
-
if (fn === "Slice" || fn === "SliceStable") this.useHelper("sortSlice");
|
|
27
|
-
const gen = SORT_DISPATCH[fn];
|
|
28
|
-
return gen ? gen(a()) : undefined;
|
|
29
|
-
},
|
|
30
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
// CodeGen for Go `strconv` package.
|
|
2
|
-
|
|
3
|
-
/** @typedef {import('../index.js').CodeGen} CodeGen */
|
|
4
|
-
|
|
5
|
-
// Parsers return [value, msg|null] from the shared __strconv_* helpers
|
|
6
|
-
// (runtime.js); the message becomes a Go error value.
|
|
7
|
-
const parsed = (fnName, numArg, call, toValue = "r[0]") =>
|
|
8
|
-
`((r, s) => [${toValue}, r[1] === null ? null : (typeof NumError$$strconv !== "undefined" ? ((o) => { o.__p = true; return o; })(new NumError$$strconv("${fnName}", String(s), r[1].includes("value out of range") ? __strconv_err_range : __strconv_err_syntax)) : __error(r[1], r[1].includes("invalid syntax") ? __strconv_err_syntax : r[1].includes("value out of range") ? __strconv_err_range : null))])(${call}, ${numArg})`;
|
|
9
|
-
|
|
10
|
-
const STRCONV_DISPATCH = {
|
|
11
|
-
Itoa: (a) => `String(${a[0]})`,
|
|
12
|
-
Atoi: (a) => parsed("Atoi", a[0], `__strconv_atoi(${a[0]})`, "Number(r[0])"),
|
|
13
|
-
FormatBool: (a) => `String(${a[0]})`,
|
|
14
|
-
FormatInt: (a) => `(${a[0]}).toString(${a[1]})`,
|
|
15
|
-
FormatFloat: (a) =>
|
|
16
|
-
a.length < 3
|
|
17
|
-
? `String(${a[0]})`
|
|
18
|
-
: `__strconv_format_float(${a[0]}, ${a[1]}, ${a[2]})`,
|
|
19
|
-
ParseFloat: (a) =>
|
|
20
|
-
parsed("ParseFloat", a[0], `__strconv_parse_float(${a[0]})`),
|
|
21
|
-
ParseInt: (a) =>
|
|
22
|
-
parsed(
|
|
23
|
-
"ParseInt",
|
|
24
|
-
a[0],
|
|
25
|
-
`__strconv_parse_int(${a[0]}, ${a[1]}, ${a[2] ?? 64})`,
|
|
26
|
-
"Number(r[0])",
|
|
27
|
-
),
|
|
28
|
-
ParseBool: (a) => parsed("ParseBool", a[0], `__strconv_parse_bool(${a[0]})`),
|
|
29
|
-
Quote: (a) => `JSON.stringify(${a[0]})`,
|
|
30
|
-
Unquote: (a) =>
|
|
31
|
-
`((s) => { if (typeof s === "string" && s.startsWith("\`") && s.endsWith("\`") && s.length >= 2) { if (s.slice(1, -1).includes("\`")) return ["", __strconv_err_syntax]; return [s.slice(1, -1), null]; } try { const v = JSON.parse(s); if (typeof v !== "string") throw 0; return [v, null]; } catch(e) { return ["", __strconv_err_syntax]; } })(${a[0]})`,
|
|
32
|
-
AppendInt: (a) =>
|
|
33
|
-
`((d, s) => { const e = new TextEncoder().encode(s); const dl = d ? d.length : 0; const r = new Uint8Array(dl + e.length); if (dl > 0) r.set(d, 0); r.set(e, dl); return r; })(${a[0]}, (${a[1]}).toString(${a[2]}))`,
|
|
34
|
-
AppendUint: (a) =>
|
|
35
|
-
`((d, s) => { const e = new TextEncoder().encode(s); const dl = d ? d.length : 0; const r = new Uint8Array(dl + e.length); if (dl > 0) r.set(d, 0); r.set(e, dl); return r; })(${a[0]}, (BigInt.asUintN(64, BigInt(${a[1]}))).toString(${a[2]}))`,
|
|
36
|
-
AppendBool: (a) =>
|
|
37
|
-
`((d, s) => { const e = new TextEncoder().encode(s); const dl = d ? d.length : 0; const r = new Uint8Array(dl + e.length); if (dl > 0) r.set(d, 0); r.set(e, dl); return r; })(${a[0]}, String(${a[1]}))`,
|
|
38
|
-
AppendFloat: (a) =>
|
|
39
|
-
`((d, s) => { const e = new TextEncoder().encode(s); const dl = d ? d.length : 0; const r = new Uint8Array(dl + e.length); if (dl > 0) r.set(d, 0); r.set(e, dl); return r; })(${a[0]}, __strconv_format_float(${a[1]}, typeof (${a[2]}) === "string" ? (${a[2]}).charCodeAt(0) : (${a[2]}), ${a[3]}))`,
|
|
40
|
-
FormatUint: (a) => `(BigInt.asUintN(64, BigInt(${a[0]}))).toString(${a[1]})`,
|
|
41
|
-
ParseUint: (a) =>
|
|
42
|
-
parsed(
|
|
43
|
-
"ParseUint",
|
|
44
|
-
a[0],
|
|
45
|
-
`__strconv_parse_uint(${a[0]}, ${a[1]}, ${a[2] ?? 64})`,
|
|
46
|
-
"Number(r[0])",
|
|
47
|
-
),
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const USES_ERROR = new Set([
|
|
51
|
-
"Atoi",
|
|
52
|
-
"ParseFloat",
|
|
53
|
-
"ParseInt",
|
|
54
|
-
"ParseUint",
|
|
55
|
-
"ParseBool",
|
|
56
|
-
"Unquote",
|
|
57
|
-
]);
|
|
58
|
-
const USES_STRCONV = new Set([
|
|
59
|
-
"Atoi",
|
|
60
|
-
"ParseFloat",
|
|
61
|
-
"ParseInt",
|
|
62
|
-
"ParseUint",
|
|
63
|
-
"ParseBool",
|
|
64
|
-
"FormatFloat",
|
|
65
|
-
"AppendFloat",
|
|
66
|
-
]);
|
|
67
|
-
|
|
68
|
-
/** @type {ThisType<CodeGen>} */
|
|
69
|
-
export const strconvMethods = {
|
|
70
|
-
_genStrconv(fn, a) {
|
|
71
|
-
const gen = STRCONV_DISPATCH[fn];
|
|
72
|
-
if (gen && USES_ERROR.has(fn)) {
|
|
73
|
-
this.useHelper("error");
|
|
74
|
-
this.useHelper("strconvError");
|
|
75
|
-
}
|
|
76
|
-
if (gen && USES_STRCONV.has(fn)) this.useHelper("strconv");
|
|
77
|
-
return gen ? gen(a()) : undefined;
|
|
78
|
-
},
|
|
79
|
-
};
|