gofront 1.8.0 → 1.9.1
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 +6 -5
- package/src/backend/js/expressions.js +1157 -408
- package/src/backend/js/index.js +327 -153
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +559 -2552
- package/src/backend/js/statements.js +670 -158
- package/src/backend/js/stdlib/index.js +45 -93
- package/src/backend/js/templ.js +32 -45
- package/src/backend/js/type-info.js +298 -19
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +91 -170
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +490 -965
- package/src/backend/wasm/emit-builtins.js +884 -256
- package/src/backend/wasm/emit-exprs.js +185 -77
- package/src/backend/wasm/emit-maps.js +17 -367
- package/src/backend/wasm/emit-shared.js +4 -1
- package/src/backend/wasm/emit-stmts.js +524 -240
- package/src/backend/wasm/emit.js +176 -38
- package/src/backend/wasm/globals.js +48 -8
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +44 -530
- package/src/backend/wasm/method-expr.js +12 -1
- package/src/backend/wasm/module-emitter.js +299 -770
- package/src/backend/wasm/monomorph.js +139 -8
- package/src/backend/wasm/natives.js +600 -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 +97 -20
- package/src/backend/wasm/variadic.js +9 -4
- package/src/cli/cli-core.js +5 -1
- package/src/cli/test-runner.js +115 -342
- package/src/compiler.js +113 -130
- package/src/lexer/lexer.js +106 -11
- package/src/lexer/templ-lexer.js +61 -18
- package/src/lexer/tokens.js +1 -0
- package/src/link/stdlib.js +355 -132
- package/src/link/type-names.js +204 -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 +62 -5
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +929 -0
- package/src/lower/functions.js +225 -7
- package/src/lower/gen-types.js +293 -0
- package/src/lower/index.js +14 -2
- package/src/lower/json-codecs.js +334 -245
- 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 +30 -5
- package/src/parser/expressions.js +111 -57
- package/src/parser/statements.js +108 -0
- package/src/parser/templ.js +44 -5
- package/src/parser/types.js +12 -0
- package/src/resolver.js +1 -2
- package/src/typechecker/assignability.js +214 -19
- package/src/typechecker/const-fold.js +70 -27
- package/src/typechecker/constants.js +156 -8
- package/src/typechecker/expressions.js +490 -108
- package/src/typechecker/index.js +346 -42
- package/src/typechecker/init-order.js +136 -40
- package/src/typechecker/operand-text.js +41 -0
- package/src/typechecker/resolve.js +490 -65
- package/src/typechecker/statements.js +288 -27
- 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 +287 -575
- 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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// The host half of strconv's fixed-point float formatting: a JS function,
|
|
2
|
+
// as source text, that both backends embed (src/backend/js/natives.js and the
|
|
3
|
+
// WASM host imports in src/backend/wasm/boundary.js).
|
|
4
|
+
//
|
|
5
|
+
// `toFixed` is exact except that it rounds a tie (a value whose decimal
|
|
6
|
+
// expansion ends in a 5 right after the digits kept) up, where Go rounds it
|
|
7
|
+
// to even; the extra digits of a second call tell the two apart. A tie is a
|
|
8
|
+
// multiple of 2^-(p+1), so any other value needs no second call. "" declines.
|
|
9
|
+
export const FIXED_FLOAT_JS = `(x, p) => {
|
|
10
|
+
if (!(x < 1e21)) return "";
|
|
11
|
+
const s = x.toFixed(p);
|
|
12
|
+
if (x % 1 === 0 || (x * 2 ** (p + 1)) % 1 !== 0) return s;
|
|
13
|
+
const t = x.toFixed(p + 30);
|
|
14
|
+
const dot = t.indexOf(".");
|
|
15
|
+
if (/^50*$/.test(t.slice(dot + 1 + p))) {
|
|
16
|
+
const down = t.slice(0, p === 0 ? dot : dot + 1 + p);
|
|
17
|
+
return (down.charCodeAt(down.length - 1) - 48) % 2 === 0 ? down : s;
|
|
18
|
+
}
|
|
19
|
+
return s;
|
|
20
|
+
}`;
|
|
@@ -1,188 +1,109 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// 3, a `Color` is a raw number inside a slice). Where a format string is a
|
|
5
|
-
// literal that needs them (`fmtWantsTypes`), codegen passes the operand's
|
|
6
|
-
// static type next to its value as a plain JSON-compatible tree, which
|
|
7
|
-
// `__sprintf` reads (`__ft` on JS, `fmt_arg_type` on WASM).
|
|
8
|
-
//
|
|
9
|
-
// Descriptor shapes (`k`): `b` basic `{ n }`, `named` `{ n, u }` (a named
|
|
10
|
-
// non-struct type, `u` its underlying type), `struct` `{ n, f: [[name, T]] }`
|
|
11
|
-
// (`n` is "" for an anonymous struct), `ptr` `{ e }`, `slice` `{ e }`,
|
|
12
|
-
// `array` `{ e, len }`, `map` `{ key, val }`, `i` an interface `{ n }`,
|
|
13
|
-
// `func` `{ p, r }`, `chan` `{ e }`. A type that is too deep or unknown is
|
|
14
|
-
// `null`; the runtime then derives a best-effort type from the value.
|
|
1
|
+
// Go's `reflect` spelling of a type used as a type argument (the monomorphiser
|
|
2
|
+
// records it for `%T` of a type-parameter operand), shared by the JS and WASM
|
|
3
|
+
// backends.
|
|
15
4
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const VERBS = "vTtcdoObxXUeEfFgGsqp";
|
|
5
|
+
const qualify = (name) =>
|
|
6
|
+
name.split("[")[0].includes(".") ? name : `main.${name}`;
|
|
19
7
|
|
|
20
|
-
const
|
|
8
|
+
const PREDECLARED = new Set([
|
|
9
|
+
"bool",
|
|
10
|
+
"string",
|
|
11
|
+
"int",
|
|
12
|
+
"int8",
|
|
13
|
+
"int16",
|
|
14
|
+
"int32",
|
|
15
|
+
"int64",
|
|
16
|
+
"uint",
|
|
17
|
+
"uint8",
|
|
18
|
+
"uint16",
|
|
19
|
+
"uint32",
|
|
20
|
+
"uint64",
|
|
21
|
+
"uintptr",
|
|
22
|
+
"float32",
|
|
23
|
+
"float64",
|
|
24
|
+
"complex64",
|
|
25
|
+
"complex128",
|
|
26
|
+
"byte",
|
|
27
|
+
"rune",
|
|
28
|
+
"error",
|
|
29
|
+
]);
|
|
21
30
|
|
|
22
31
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* @
|
|
32
|
+
* Go's `reflect` spelling of a type used as a type argument: `int`,
|
|
33
|
+
* `main.Foo`, `[]main.Foo`. Takes checker types and parsed type nodes;
|
|
34
|
+
* `specialized` maps the names of monomorphised instances to their spelling.
|
|
35
|
+
* @param {any} t
|
|
36
|
+
* @param {Map<string, string>} [specialized]
|
|
37
|
+
* @returns {string}
|
|
27
38
|
*/
|
|
28
|
-
export function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const sub = (x) => fmtTypeDesc(x, resolve, depth + 1);
|
|
32
|
-
switch (t.kind) {
|
|
39
|
+
export function goTypeName(t, specialized = null) {
|
|
40
|
+
const go = (x) => goTypeName(x, specialized);
|
|
41
|
+
switch (t?.kind) {
|
|
33
42
|
case "basic":
|
|
34
|
-
|
|
35
|
-
if (t.name === "nil" || t.name === "void") return null;
|
|
36
|
-
return { k: "b", n: t.name };
|
|
43
|
+
return t.name === "any" ? "interface {}" : t.name;
|
|
37
44
|
case "untyped":
|
|
38
|
-
return
|
|
39
|
-
case "
|
|
40
|
-
|
|
45
|
+
return t.base;
|
|
46
|
+
case "TypeName":
|
|
47
|
+
case "Ident":
|
|
48
|
+
if (specialized?.has(t.name)) return qualify(specialized.get(t.name));
|
|
49
|
+
if (t.name === "any") return "interface {}";
|
|
50
|
+
return PREDECLARED.has(t.name) ? t.name : qualify(t.name);
|
|
51
|
+
case "GenericTypeName":
|
|
52
|
+
return qualify(`${t.name}[${t.typeArgs.map(go).join(",")}]`);
|
|
41
53
|
case "named":
|
|
42
|
-
return
|
|
43
|
-
case "
|
|
44
|
-
return
|
|
54
|
+
return qualify(instanceName(t, specialized));
|
|
55
|
+
case "interface":
|
|
56
|
+
return t.name ? qualify(t.name) : "interface {}";
|
|
45
57
|
case "pointer":
|
|
46
|
-
|
|
58
|
+
case "PointerType":
|
|
59
|
+
return `*${go(t.base)}`;
|
|
47
60
|
case "slice":
|
|
48
|
-
|
|
61
|
+
case "SliceType":
|
|
62
|
+
return `[]${go(t.elem)}`;
|
|
49
63
|
case "array":
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
case "ArrayType":
|
|
65
|
+
// A parsed array type carries its length as a literal node.
|
|
66
|
+
return `[${typeof t.size === "object" ? (t.size?.value ?? 0) : (t.size ?? 0)}]${go(t.elem)}`;
|
|
53
67
|
case "map":
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
for (const n of sf.names) own.push([n, st.fields.get(n)]);
|
|
84
|
-
continue;
|
|
68
|
+
case "MapType":
|
|
69
|
+
return `map[${go(t.key)}]${go(t.value)}`;
|
|
70
|
+
case "func": {
|
|
71
|
+
// A func without results is `func()`, not `func() void`.
|
|
72
|
+
const rets = (t.returns ?? [])
|
|
73
|
+
.filter((r) => !(r?.kind === "basic" && r.name === "void"))
|
|
74
|
+
.map(go);
|
|
75
|
+
const ret =
|
|
76
|
+
rets.length === 0
|
|
77
|
+
? ""
|
|
78
|
+
: rets.length === 1
|
|
79
|
+
? ` ${rets[0]}`
|
|
80
|
+
: ` (${rets.join(", ")})`;
|
|
81
|
+
return `func(${(t.params ?? []).map(go).join(", ")})${ret}`;
|
|
82
|
+
}
|
|
83
|
+
case "FuncType": {
|
|
84
|
+
// A parsed func type: parameters and the result as written.
|
|
85
|
+
const rt = t.returnType;
|
|
86
|
+
const rets = !rt ? [] : rt.kind === "TupleType" ? rt.types : [rt];
|
|
87
|
+
const ret =
|
|
88
|
+
rets.length === 0
|
|
89
|
+
? ""
|
|
90
|
+
: rets.length === 1
|
|
91
|
+
? ` ${go(rets[0])}`
|
|
92
|
+
: ` (${rets.map(go).join(", ")})`;
|
|
93
|
+
const params = (t.params ?? []).map((p) =>
|
|
94
|
+
p.variadic ? `...${go(p.type)}` : go(p.type),
|
|
95
|
+
);
|
|
96
|
+
return `func(${params.join(", ")})${ret}`;
|
|
85
97
|
}
|
|
86
|
-
const inner = sf.type?.kind === "pointer" ? sf.type.base : sf.type;
|
|
87
|
-
const name = (
|
|
88
|
-
sf.embeddedName ??
|
|
89
|
-
sf.astType?.name ??
|
|
90
|
-
sf.type?.name ??
|
|
91
|
-
sf.type?.base?.name ??
|
|
92
|
-
(inner?.kind === "named" ? inner.name : "")
|
|
93
|
-
)
|
|
94
|
-
.split(".")
|
|
95
|
-
.pop();
|
|
96
|
-
if (name) own.push([name, st.fields.get(name) ?? sf.type]);
|
|
97
|
-
}
|
|
98
|
-
return own;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function structDesc(n, st, sub) {
|
|
102
|
-
const f = [];
|
|
103
|
-
for (const [name, ft] of structOwnFields(st)) f.push([name, sub(ft)]);
|
|
104
|
-
return { k: "struct", n, f };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function namedDesc(t, resolve, depth, sub) {
|
|
108
|
-
const n = qualify(t.name ?? "");
|
|
109
|
-
const u = resolve(t.underlying) ?? t.underlying;
|
|
110
|
-
if (!u) return { k: "named", n, u: null };
|
|
111
|
-
if (u.kind === "struct")
|
|
112
|
-
return depth > MAX_DEPTH
|
|
113
|
-
? { k: "struct", n, f: null }
|
|
114
|
-
: structDesc(n, u, sub);
|
|
115
|
-
if (u.kind === "interface") return { k: "i", n };
|
|
116
|
-
return { k: "named", n, u: depth > MAX_DEPTH ? null : sub(u) };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Whether a type descriptor mentions a float32 or float64. Such operands
|
|
121
|
-
* travel with their static type: a number alone cannot tell `float64(1e6)`
|
|
122
|
-
* (Go prints 1e+06) from an `int`, or a float32 from the float64 holding the
|
|
123
|
-
* same bits.
|
|
124
|
-
* @param {any} desc result of fmtTypeDesc
|
|
125
|
-
* @returns {boolean}
|
|
126
|
-
*/
|
|
127
|
-
export function fmtDescHasFloat(desc) {
|
|
128
|
-
if (!desc || typeof desc !== "object") return false;
|
|
129
|
-
switch (desc.k) {
|
|
130
|
-
case "b":
|
|
131
|
-
return desc.n === "float32" || desc.n === "float64";
|
|
132
|
-
case "named":
|
|
133
|
-
return fmtDescHasFloat(desc.u);
|
|
134
|
-
case "struct":
|
|
135
|
-
return (desc.f ?? []).some(([, ft]) => fmtDescHasFloat(ft));
|
|
136
|
-
case "ptr":
|
|
137
|
-
case "slice":
|
|
138
|
-
case "array":
|
|
139
|
-
return fmtDescHasFloat(desc.e);
|
|
140
|
-
case "map":
|
|
141
|
-
return fmtDescHasFloat(desc.key) || fmtDescHasFloat(desc.val);
|
|
142
98
|
default:
|
|
143
|
-
return
|
|
99
|
+
return "interface {}";
|
|
144
100
|
}
|
|
145
101
|
}
|
|
146
102
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
*/
|
|
154
|
-
export function fmtDescIsSeq(desc) {
|
|
155
|
-
let d = desc;
|
|
156
|
-
while (d?.k === "named") d = d.u;
|
|
157
|
-
return d?.k === "slice" || d?.k === "array";
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Whether a call with this literal format string needs operand types: `%T`,
|
|
162
|
-
* `%#v`, an unknown verb (`%!z(int=5)`), or more operands than verbs
|
|
163
|
-
* (`%!(EXTRA int=1)`).
|
|
164
|
-
* @param {unknown} format
|
|
165
|
-
* @param {number} nargs operand count, -1 when not known statically
|
|
166
|
-
* @param {boolean} [seqArgs] some operand is a slice or array, whose element
|
|
167
|
-
* type decides how `%s`, `%q`, `%x` and `%X` read it
|
|
168
|
-
*/
|
|
169
|
-
export function fmtWantsTypes(format, nargs, seqArgs = false) {
|
|
170
|
-
if (typeof format !== "string") return false;
|
|
171
|
-
const re = new RegExp(
|
|
172
|
-
`%([${FLAGS}]*)((?:\\[\\d+\\])?(?:\\*|\\d+)?(?:\\.(?:\\[\\d+\\])?(?:\\*|\\d*))?(?:\\[\\d+\\])?)([^]?)`,
|
|
173
|
-
"g",
|
|
174
|
-
);
|
|
175
|
-
let count = 0;
|
|
176
|
-
let indexed = false;
|
|
177
|
-
for (const m of format.matchAll(re)) {
|
|
178
|
-
const verb = m[3];
|
|
179
|
-
if (verb === "%") continue;
|
|
180
|
-
if (verb === "T" || verb === "p") return true;
|
|
181
|
-
if (verb === "v" && m[1].includes("#")) return true;
|
|
182
|
-
if (seqArgs && "sqxX".includes(verb)) return true;
|
|
183
|
-
if (verb !== "" && !VERBS.includes(verb) && verb !== "w") return true;
|
|
184
|
-
if (/[[*]/.test(m[2])) indexed = true;
|
|
185
|
-
count++;
|
|
186
|
-
}
|
|
187
|
-
return nargs >= 0 && !indexed && nargs > count;
|
|
103
|
+
// `Box[int]` for a generic instance: the checker's type arguments on JS, the
|
|
104
|
+
// spelling the monomorphiser recorded on WASM.
|
|
105
|
+
function instanceName(t, specialized = null) {
|
|
106
|
+
if (t._goName) return t._goName;
|
|
107
|
+
if (!t.typeArgs?.length) return t.name ?? "";
|
|
108
|
+
return `${t.name}[${t.typeArgs.map((a) => goTypeName(a, specialized)).join(",")}]`;
|
|
188
109
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// JS bodies of the host side of the unicode intrinsics (unicode_is,
|
|
2
|
+
// unicode_to_upper, unicode_to_lower). The JS backend inlines them as the
|
|
3
|
+
// intrinsic bodies and the WASM boundary ships them as `env` imports, so
|
|
4
|
+
// both targets answer from the same tables. Each takes the names of the
|
|
5
|
+
// parameters it reads and returns statements ending in a `return`.
|
|
6
|
+
|
|
7
|
+
// Classes, in the order of the constants in stdlib/unicode/unicode.go: the
|
|
8
|
+
// test of the one-code-point string `c`.
|
|
9
|
+
const CLASS_TESTS = [
|
|
10
|
+
"/\\p{L}/u.test(c)", // Letter
|
|
11
|
+
"/\\p{Nd}/u.test(c)", // Digit
|
|
12
|
+
"/[ \\t\\n\\v\\f\\r\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000]/.test(c)", // Space
|
|
13
|
+
"/\\p{Lu}/u.test(c)", // Upper
|
|
14
|
+
"/\\p{Ll}/u.test(c)", // Lower
|
|
15
|
+
"/\\p{P}/u.test(c)", // Punct
|
|
16
|
+
"/\\p{Cc}/u.test(c)", // Control
|
|
17
|
+
"!/\\p{Cc}/u.test(c)", // Print
|
|
18
|
+
"!/\\p{Cc}/u.test(c)", // Graphic
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export function unicodeIsJs(r, cls) {
|
|
22
|
+
const cases = CLASS_TESTS.map((test, i) => `case ${i}: return ${test};`).join(
|
|
23
|
+
" ",
|
|
24
|
+
);
|
|
25
|
+
return `const c = String.fromCodePoint(${r}); switch (${cls}) { ${cases} } return false;`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// A letter whose upper case spans several code points (the German sharp s)
|
|
29
|
+
// stays as it is.
|
|
30
|
+
export function unicodeToUpperJs(r) {
|
|
31
|
+
return `const m = String.fromCodePoint(${r}).toUpperCase(); const u = m.codePointAt(0); return m.length > (u > 0xffff ? 2 : 1) ? ${r} : u;`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function unicodeToLowerJs(r) {
|
|
35
|
+
return `return String.fromCodePoint(${r}).toLowerCase().codePointAt(0);`;
|
|
36
|
+
}
|