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
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// (e.g. Identity$int, Box$int, Stack$int.Push) and re-typechecks the monomorphised AST.
|
|
8
8
|
|
|
9
9
|
import { TypeChecker } from "../../typechecker/index.js";
|
|
10
|
+
import { goTypeName } from "../shared/fmt-types.js";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Returns true if the AST contains any generic declarations.
|
|
@@ -118,7 +119,11 @@ export function typeToTypeNode(t) {
|
|
|
118
119
|
if (t.kind === "array") {
|
|
119
120
|
return {
|
|
120
121
|
kind: "ArrayType",
|
|
121
|
-
|
|
122
|
+
size: {
|
|
123
|
+
kind: "BasicLit",
|
|
124
|
+
litKind: "INT",
|
|
125
|
+
value: String(t.len ?? t.size ?? 0),
|
|
126
|
+
},
|
|
122
127
|
elem: typeToTypeNode(t.elem),
|
|
123
128
|
};
|
|
124
129
|
}
|
|
@@ -133,13 +138,51 @@ export function typeToTypeNode(t) {
|
|
|
133
138
|
return { kind: "TypeName", name: t.name ?? "any" };
|
|
134
139
|
}
|
|
135
140
|
|
|
141
|
+
// Replaces the type parameters inside a checker type (`[]E`, `map[K]V`,
|
|
142
|
+
// `Box[E]`) by their type arguments; the result mixes checker types and the
|
|
143
|
+
// AST type nodes of the substitution, which `typeKey` and `typeToTypeNode`
|
|
144
|
+
// both accept.
|
|
145
|
+
function substituteInType(t, map) {
|
|
146
|
+
if (!t || typeof t !== "object") return t;
|
|
147
|
+
const sub = (x) => substituteInType(x, map);
|
|
148
|
+
switch (t.kind) {
|
|
149
|
+
case "typeParam":
|
|
150
|
+
return map.has(t.name) ? map.get(t.name) : t;
|
|
151
|
+
case "slice":
|
|
152
|
+
case "array":
|
|
153
|
+
return { ...t, elem: sub(t.elem) };
|
|
154
|
+
case "pointer":
|
|
155
|
+
return { ...t, base: sub(t.base) };
|
|
156
|
+
case "map":
|
|
157
|
+
return { ...t, key: sub(t.key), value: sub(t.value) };
|
|
158
|
+
case "func":
|
|
159
|
+
return {
|
|
160
|
+
...t,
|
|
161
|
+
params: (t.params ?? []).map(sub),
|
|
162
|
+
returns: (t.returns ?? []).map(sub),
|
|
163
|
+
};
|
|
164
|
+
case "named":
|
|
165
|
+
return t.typeArgs?.length ? { ...t, typeArgs: t.typeArgs.map(sub) } : t;
|
|
166
|
+
default:
|
|
167
|
+
return t;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// A partial instantiation (`Grow[S](nil, n)`) lists only the explicit type
|
|
172
|
+
// arguments; the checker recorded the complete list, which replaces it.
|
|
173
|
+
function completeTypeArgs(node, typeSubstMap) {
|
|
174
|
+
if (node._typeArgs?.length > (node.typeArgs?.length ?? 0))
|
|
175
|
+
return node._typeArgs.map((t) => substituteInType(t, typeSubstMap));
|
|
176
|
+
return node.typeArgs;
|
|
177
|
+
}
|
|
178
|
+
|
|
136
179
|
function getSpecializedName(baseName, typeArgs) {
|
|
137
180
|
if (!typeArgs || typeArgs.length === 0) return baseName;
|
|
138
181
|
const keys = typeArgs.map(typeKey).join("$");
|
|
139
182
|
return `${baseName}$${keys}`;
|
|
140
183
|
}
|
|
141
184
|
|
|
142
|
-
const KEPT_CLONE_KEYS = new Set(["_typeArgs", "_line", "_col"]);
|
|
185
|
+
const KEPT_CLONE_KEYS = new Set(["_typeArgs", "_line", "_col", "_spread"]);
|
|
143
186
|
|
|
144
187
|
function cloneAst(node) {
|
|
145
188
|
if (!node || typeof node !== "object") return node;
|
|
@@ -252,6 +295,7 @@ function substituteTypesInAst(
|
|
|
252
295
|
}
|
|
253
296
|
const baseName = node.expr?.name;
|
|
254
297
|
if (baseName) {
|
|
298
|
+
node.typeArgs = completeTypeArgs(node, typeSubstMap);
|
|
255
299
|
const sName = getSpecializedName(baseName, node.typeArgs);
|
|
256
300
|
const isType = genericTypes ? genericTypes.has(baseName) : false;
|
|
257
301
|
if (onGenericUsage) {
|
|
@@ -271,6 +315,13 @@ function substituteTypesInAst(
|
|
|
271
315
|
// 3b. CompositeLit
|
|
272
316
|
if (node.kind === "CompositeLit") {
|
|
273
317
|
const targetProp = node.typeExpr ? "typeExpr" : node.type ? "type" : null;
|
|
318
|
+
// `S{a, b}` with S a type parameter: the type is a bare identifier.
|
|
319
|
+
if (
|
|
320
|
+
targetProp &&
|
|
321
|
+
node[targetProp]?.kind === "Ident" &&
|
|
322
|
+
typeSubstMap.has(node[targetProp].name)
|
|
323
|
+
)
|
|
324
|
+
node[targetProp] = cloneAst(typeSubstMap.get(node[targetProp].name));
|
|
274
325
|
if (targetProp && node[targetProp]) {
|
|
275
326
|
node[targetProp] = substituteTypesInAst(
|
|
276
327
|
node[targetProp],
|
|
@@ -301,6 +352,18 @@ function substituteTypesInAst(
|
|
|
301
352
|
_line: node._line,
|
|
302
353
|
};
|
|
303
354
|
}
|
|
355
|
+
// `make(S, n)` / `new(S)`: the type argument is a bare identifier.
|
|
356
|
+
if (
|
|
357
|
+
node.func?.kind === "Ident" &&
|
|
358
|
+
(node.func.name === "make" || node.func.name === "new") &&
|
|
359
|
+
node.args?.[0]?.kind === "Ident" &&
|
|
360
|
+
typeSubstMap.has(node.args[0].name)
|
|
361
|
+
) {
|
|
362
|
+
node.args[0] = {
|
|
363
|
+
kind: "TypeExpr",
|
|
364
|
+
type: cloneAst(typeSubstMap.get(node.args[0].name)),
|
|
365
|
+
};
|
|
366
|
+
}
|
|
304
367
|
if (node.func?.kind === "Ident") {
|
|
305
368
|
let typeArgs = node._typeArgs ?? node.func._typeArgs;
|
|
306
369
|
if (typeArgs) {
|
|
@@ -309,7 +372,7 @@ function substituteTypesInAst(
|
|
|
309
372
|
if (name && typeSubstMap.has(name)) {
|
|
310
373
|
return typeSubstMap.get(name);
|
|
311
374
|
}
|
|
312
|
-
return t;
|
|
375
|
+
return substituteInType(t, typeSubstMap);
|
|
313
376
|
});
|
|
314
377
|
const baseName = node.func.name;
|
|
315
378
|
const sName = getSpecializedName(baseName, typeArgs);
|
|
@@ -559,9 +622,14 @@ export function monomorphise(programs, checker) {
|
|
|
559
622
|
const genericFuncs = new Map();
|
|
560
623
|
const genericTypes = new Map();
|
|
561
624
|
const genericMethods = new Map(); // recvBaseName -> Array<MethodDecl>
|
|
625
|
+
// Template declaration -> its program; a specialization joins the program
|
|
626
|
+
// of its template, so a wasm package's instances stay wasm-package
|
|
627
|
+
// declarations even when a Go-source stdlib package is linked first.
|
|
628
|
+
const homeOf = new Map();
|
|
562
629
|
|
|
563
630
|
for (const p of progs) {
|
|
564
631
|
for (const d of p?.decls ?? []) {
|
|
632
|
+
homeOf.set(d, p);
|
|
565
633
|
if (d.kind === "FuncDecl" && d.typeParams && d.typeParams.length > 0) {
|
|
566
634
|
genericFuncs.set(d.name, d);
|
|
567
635
|
} else if (
|
|
@@ -611,6 +679,7 @@ export function monomorphise(programs, checker) {
|
|
|
611
679
|
}
|
|
612
680
|
}
|
|
613
681
|
|
|
682
|
+
const typeInstances = new Map();
|
|
614
683
|
const specializedFuncs = new Map();
|
|
615
684
|
const specializedTypes = new Map();
|
|
616
685
|
const specializedMethods = new Map();
|
|
@@ -638,6 +707,7 @@ export function monomorphise(programs, checker) {
|
|
|
638
707
|
typeSubstMap.set(tp.name, typeToTypeNode(concrete));
|
|
639
708
|
}
|
|
640
709
|
|
|
710
|
+
typeInstances.set(item.specializedName, item);
|
|
641
711
|
const monoTypeDecl = cloneAst(genDecl);
|
|
642
712
|
monoTypeDecl.name = item.specializedName;
|
|
643
713
|
monoTypeDecl.typeParams = null;
|
|
@@ -650,6 +720,7 @@ export function monomorphise(programs, checker) {
|
|
|
650
720
|
);
|
|
651
721
|
rebindNamedResults(monoTypeDecl);
|
|
652
722
|
specializedTypes.set(item.specializedName, monoTypeDecl);
|
|
723
|
+
homeOf.set(monoTypeDecl, homeOf.get(genDecl));
|
|
653
724
|
|
|
654
725
|
// Specialize all methods declared on this generic type
|
|
655
726
|
const methods = genericMethods.get(item.genericName) ?? [];
|
|
@@ -669,6 +740,7 @@ export function monomorphise(programs, checker) {
|
|
|
669
740
|
rebindNamedResults(monoMethod);
|
|
670
741
|
const mKey = `${item.specializedName}.${monoMethod.name}`;
|
|
671
742
|
specializedMethods.set(mKey, monoMethod);
|
|
743
|
+
homeOf.set(monoMethod, homeOf.get(m));
|
|
672
744
|
}
|
|
673
745
|
} else if (item.kind === "func") {
|
|
674
746
|
const genDecl = genericFuncs.get(item.genericName);
|
|
@@ -693,6 +765,7 @@ export function monomorphise(programs, checker) {
|
|
|
693
765
|
);
|
|
694
766
|
rebindNamedResults(monoFuncDecl);
|
|
695
767
|
specializedFuncs.set(item.specializedName, monoFuncDecl);
|
|
768
|
+
homeOf.set(monoFuncDecl, homeOf.get(genDecl));
|
|
696
769
|
}
|
|
697
770
|
}
|
|
698
771
|
|
|
@@ -744,15 +817,22 @@ export function monomorphise(programs, checker) {
|
|
|
744
817
|
|
|
745
818
|
const targetProg = progs[0];
|
|
746
819
|
if (targetProg) {
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
820
|
+
for (const group of [
|
|
821
|
+
specializedTypes,
|
|
822
|
+
specializedMethods,
|
|
823
|
+
specializedFuncs,
|
|
824
|
+
])
|
|
825
|
+
for (const d of group.values())
|
|
826
|
+
(homeOf.get(d) ?? targetProg).decls.push(d);
|
|
750
827
|
}
|
|
751
828
|
|
|
752
829
|
// 6. Typecheck the monomorphised program to annotate all concrete types
|
|
753
830
|
const monoChecker = new TypeChecker();
|
|
754
831
|
monoChecker.target = "wasm";
|
|
755
832
|
monoChecker.pkgName = targetProg?.pkg?.name ?? "main";
|
|
833
|
+
// The programs were checked once already, where `//gofront:native` is
|
|
834
|
+
// limited to the standard library; this pass only re-annotates them.
|
|
835
|
+
monoChecker.nativesChecked = true;
|
|
756
836
|
if (checker?.types) {
|
|
757
837
|
for (const [name, type] of checker.types.entries()) {
|
|
758
838
|
if (!monoChecker.types.has(name)) {
|
|
@@ -764,6 +844,23 @@ export function monomorphise(programs, checker) {
|
|
|
764
844
|
// One pass over all programs: declarations of every linked package are
|
|
765
845
|
// visible to the others (cross-package references are dequalified).
|
|
766
846
|
monoChecker.checkAll(progs);
|
|
847
|
+
nameInstances(monoChecker, typeInstances);
|
|
767
848
|
|
|
768
849
|
return { programs: progs, checker: monoChecker };
|
|
769
850
|
}
|
|
851
|
+
|
|
852
|
+
// Records Go's spelling of each generic instance (`Box[int]`) on its
|
|
853
|
+
// monomorphised type, which is named `Box$int`; `%T` prints the spelling.
|
|
854
|
+
function nameInstances(checker, instances) {
|
|
855
|
+
const spelling = {
|
|
856
|
+
has: (name) => instances.has(name),
|
|
857
|
+
get: (name) => {
|
|
858
|
+
const { genericName, typeArgs } = instances.get(name);
|
|
859
|
+
return `${genericName}[${typeArgs.map((a) => goTypeName(a, spelling)).join(",")}]`;
|
|
860
|
+
},
|
|
861
|
+
};
|
|
862
|
+
for (const name of instances.keys()) {
|
|
863
|
+
const type = checker.types.get(name);
|
|
864
|
+
if (type) type._goName = spelling.get(name);
|
|
865
|
+
}
|
|
866
|
+
}
|