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
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
//go:build gofront
|
|
2
|
+
|
|
3
|
+
//gofront:target both
|
|
4
|
+
|
|
5
|
+
package utf8
|
|
6
|
+
|
|
7
|
+
// RuneSelf characters below RuneSelf are represented as themselves in a single byte.
|
|
8
|
+
const RuneSelf = 0x80
|
|
9
|
+
|
|
10
|
+
const (
|
|
11
|
+
t2 = 0b11000000
|
|
12
|
+
t3 = 0b11100000
|
|
13
|
+
t4 = 0b11110000
|
|
14
|
+
|
|
15
|
+
maskx = 0b00111111
|
|
16
|
+
mask2 = 0b00011111
|
|
17
|
+
mask3 = 0b00001111
|
|
18
|
+
mask4 = 0b00000111
|
|
19
|
+
|
|
20
|
+
locb = 0b10000000
|
|
21
|
+
hicb = 0b10111111
|
|
22
|
+
|
|
23
|
+
xx = 0xF1 // invalid: size 1
|
|
24
|
+
as = 0xF0 // ASCII: size 1
|
|
25
|
+
s1 = 0x02 // accept 0, size 2
|
|
26
|
+
s2 = 0x13 // accept 1, size 3
|
|
27
|
+
s3 = 0x03 // accept 0, size 3
|
|
28
|
+
s4 = 0x23 // accept 2, size 3
|
|
29
|
+
s5 = 0x34 // accept 3, size 4
|
|
30
|
+
s6 = 0x04 // accept 0, size 4
|
|
31
|
+
s7 = 0x44 // accept 4, size 4
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
var first = [256]uint8{
|
|
35
|
+
as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as,
|
|
36
|
+
as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as,
|
|
37
|
+
as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as,
|
|
38
|
+
as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as,
|
|
39
|
+
as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as,
|
|
40
|
+
as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as,
|
|
41
|
+
as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as,
|
|
42
|
+
as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as,
|
|
43
|
+
xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
|
|
44
|
+
xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
|
|
45
|
+
xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
|
|
46
|
+
xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
|
|
47
|
+
xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1,
|
|
48
|
+
s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1,
|
|
49
|
+
s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3,
|
|
50
|
+
s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type acceptRange struct {
|
|
54
|
+
lo uint8
|
|
55
|
+
hi uint8
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
var acceptRanges = [16]acceptRange{
|
|
59
|
+
0: {locb, hicb},
|
|
60
|
+
1: {0xA0, hicb},
|
|
61
|
+
2: {locb, 0x9F},
|
|
62
|
+
3: {0x90, hicb},
|
|
63
|
+
4: {locb, 0x8F},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// RuneStart reports whether the byte could be the first byte of an encoded rune.
|
|
67
|
+
func RuneStart(b byte) bool {
|
|
68
|
+
return b&0xC0 != 0x80
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// FullRune reports whether the bytes in p begin with a full UTF-8 encoding of a rune.
|
|
72
|
+
func FullRune(p []byte) bool {
|
|
73
|
+
n := len(p)
|
|
74
|
+
if n == 0 {
|
|
75
|
+
return false
|
|
76
|
+
}
|
|
77
|
+
x := first[p[0]]
|
|
78
|
+
if n >= int(x&7) {
|
|
79
|
+
return true
|
|
80
|
+
}
|
|
81
|
+
accept := acceptRanges[x>>4]
|
|
82
|
+
if n > 1 && (p[1] < accept.lo || p[1] > accept.hi) {
|
|
83
|
+
return true
|
|
84
|
+
} else if n > 2 && (p[2] < locb || p[2] > hicb) {
|
|
85
|
+
return true
|
|
86
|
+
}
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
func decodeMulti(p []byte, p0 byte) (rune, int) {
|
|
91
|
+
x := first[p0]
|
|
92
|
+
if x >= as {
|
|
93
|
+
return RuneError, 1
|
|
94
|
+
}
|
|
95
|
+
sz := int(x & 7)
|
|
96
|
+
accept := acceptRanges[x>>4]
|
|
97
|
+
if len(p) < sz {
|
|
98
|
+
return RuneError, 1
|
|
99
|
+
}
|
|
100
|
+
b1 := p[1]
|
|
101
|
+
if b1 < accept.lo || b1 > accept.hi {
|
|
102
|
+
return RuneError, 1
|
|
103
|
+
}
|
|
104
|
+
if sz <= 2 {
|
|
105
|
+
return rune(p0&mask2)<<6 | rune(b1&maskx), 2
|
|
106
|
+
}
|
|
107
|
+
b2 := p[2]
|
|
108
|
+
if b2 < locb || b2 > hicb {
|
|
109
|
+
return RuneError, 1
|
|
110
|
+
}
|
|
111
|
+
if sz <= 3 {
|
|
112
|
+
return rune(p0&mask3)<<12 | rune(b1&maskx)<<6 | rune(b2&maskx), 3
|
|
113
|
+
}
|
|
114
|
+
b3 := p[3]
|
|
115
|
+
if b3 < locb || b3 > hicb {
|
|
116
|
+
return RuneError, 1
|
|
117
|
+
}
|
|
118
|
+
return rune(p0&mask4)<<18 | rune(b1&maskx)<<12 | rune(b2&maskx)<<6 | rune(b3&maskx), 4
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and its width in bytes.
|
|
122
|
+
func DecodeRune(p []byte) (r rune, size int) {
|
|
123
|
+
if len(p) < 1 {
|
|
124
|
+
return RuneError, 0
|
|
125
|
+
}
|
|
126
|
+
p0 := p[0]
|
|
127
|
+
if p0 < RuneSelf {
|
|
128
|
+
return rune(p0), 1
|
|
129
|
+
}
|
|
130
|
+
r, size = decodeMulti(p, p0)
|
|
131
|
+
return r, size
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// DecodeLastRune unpacks the last UTF-8 encoding in p and returns the rune and its width in bytes.
|
|
135
|
+
func DecodeLastRune(p []byte) (r rune, size int) {
|
|
136
|
+
end := len(p)
|
|
137
|
+
if end == 0 {
|
|
138
|
+
return RuneError, 0
|
|
139
|
+
}
|
|
140
|
+
start := end - 1
|
|
141
|
+
if p[start] < RuneSelf {
|
|
142
|
+
return rune(p[start]), 1
|
|
143
|
+
}
|
|
144
|
+
lim := end - UTFMax
|
|
145
|
+
if lim < 0 {
|
|
146
|
+
lim = 0
|
|
147
|
+
}
|
|
148
|
+
for start--; start >= lim; start-- {
|
|
149
|
+
if RuneStart(p[start]) {
|
|
150
|
+
break
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if start < 0 {
|
|
154
|
+
start = 0
|
|
155
|
+
}
|
|
156
|
+
r, size = DecodeRune(p[start:end])
|
|
157
|
+
if start+size != end {
|
|
158
|
+
return RuneError, 1
|
|
159
|
+
}
|
|
160
|
+
return r, size
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// EncodeRune writes into p (which must be large enough) the UTF-8 encoding of the rune.
|
|
164
|
+
func EncodeRune(p []byte, r rune) int {
|
|
165
|
+
switch i := uint32(r); {
|
|
166
|
+
case i <= 0x7F:
|
|
167
|
+
p[0] = byte(r)
|
|
168
|
+
return 1
|
|
169
|
+
case i <= 0x7FF:
|
|
170
|
+
p[0] = t2 | byte(r>>6)
|
|
171
|
+
p[1] = locb | byte(r)&maskx
|
|
172
|
+
return 2
|
|
173
|
+
case i < 0xD800, i > 0xDFFF && i <= 0xFFFF:
|
|
174
|
+
p[0] = t3 | byte(r>>12)
|
|
175
|
+
p[1] = locb | byte(r>>6)&maskx
|
|
176
|
+
p[2] = locb | byte(r)&maskx
|
|
177
|
+
return 3
|
|
178
|
+
case i > 0xFFFF && i <= MaxRune:
|
|
179
|
+
p[0] = t4 | byte(r>>18)
|
|
180
|
+
p[1] = locb | byte(r>>12)&maskx
|
|
181
|
+
p[2] = locb | byte(r>>6)&maskx
|
|
182
|
+
p[3] = locb | byte(r)&maskx
|
|
183
|
+
return 4
|
|
184
|
+
default:
|
|
185
|
+
p[0] = 0xEF
|
|
186
|
+
p[1] = 0xBF
|
|
187
|
+
p[2] = 0xBD
|
|
188
|
+
return 3
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// AppendRune appends the UTF-8 encoding of r to the end of p.
|
|
193
|
+
func AppendRune(p []byte, r rune) []byte {
|
|
194
|
+
switch i := uint32(r); {
|
|
195
|
+
case i <= 0x7F:
|
|
196
|
+
return append(p, byte(r))
|
|
197
|
+
case i <= 0x7FF:
|
|
198
|
+
return append(p, t2|byte(r>>6), locb|byte(r)&maskx)
|
|
199
|
+
case i < 0xD800, i > 0xDFFF && i <= 0xFFFF:
|
|
200
|
+
return append(p, t3|byte(r>>12), locb|byte(r>>6)&maskx, locb|byte(r)&maskx)
|
|
201
|
+
case i > 0xFFFF && i <= MaxRune:
|
|
202
|
+
return append(p, t4|byte(r>>18), locb|byte(r>>12)&maskx, locb|byte(r>>6)&maskx, locb|byte(r)&maskx)
|
|
203
|
+
default:
|
|
204
|
+
return append(p, 0xEF, 0xBF, 0xBD)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// RuneCount returns the number of runes in p.
|
|
209
|
+
func RuneCount(p []byte) int {
|
|
210
|
+
np := len(p)
|
|
211
|
+
var n int
|
|
212
|
+
for i := 0; i < np; {
|
|
213
|
+
if p[i] < RuneSelf {
|
|
214
|
+
i++
|
|
215
|
+
n++
|
|
216
|
+
continue
|
|
217
|
+
}
|
|
218
|
+
_, sz := DecodeRune(p[i:])
|
|
219
|
+
i += sz
|
|
220
|
+
n++
|
|
221
|
+
}
|
|
222
|
+
return n
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Valid reports whether p consists entirely of valid UTF-8-encoded runes.
|
|
226
|
+
func Valid(p []byte) bool {
|
|
227
|
+
for len(p) > 0 {
|
|
228
|
+
if p[0] < RuneSelf {
|
|
229
|
+
p = p[1:]
|
|
230
|
+
continue
|
|
231
|
+
}
|
|
232
|
+
_, sz := DecodeRune(p)
|
|
233
|
+
if sz == 1 {
|
|
234
|
+
return false
|
|
235
|
+
}
|
|
236
|
+
p = p[sz:]
|
|
237
|
+
}
|
|
238
|
+
return true
|
|
239
|
+
}
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
// Compile-time folding of package-level constant expressions for the wasm
|
|
2
|
-
// backend. Folds literals, other already-folded constants, unary/binary
|
|
3
|
-
// operators and `len("literal")` into a single BasicLit. Anything it cannot
|
|
4
|
-
// reduce returns null and the caller falls back to a runtime-initialised
|
|
5
|
-
// global (see `_collectPackageConsts`).
|
|
6
|
-
|
|
7
|
-
const INT = "INT";
|
|
8
|
-
const FLOAT = "FLOAT";
|
|
9
|
-
const STRING = "STRING";
|
|
10
|
-
const BOOL = "BOOL";
|
|
11
|
-
|
|
12
|
-
function fromLit(lit) {
|
|
13
|
-
switch (lit.litKind) {
|
|
14
|
-
case INT: {
|
|
15
|
-
const s = String(lit.value);
|
|
16
|
-
const clean = /^0[0-7]+$/.test(s) ? `0o${s.slice(1)}` : s;
|
|
17
|
-
return { k: INT, v: BigInt(clean) };
|
|
18
|
-
}
|
|
19
|
-
case FLOAT: {
|
|
20
|
-
const n = Number(lit.value);
|
|
21
|
-
return Number.isFinite(n) ? { k: FLOAT, v: n } : null;
|
|
22
|
-
}
|
|
23
|
-
case STRING:
|
|
24
|
-
return { k: STRING, v: String(lit.value ?? "") };
|
|
25
|
-
case BOOL:
|
|
26
|
-
return { k: BOOL, v: lit.value === "true" };
|
|
27
|
-
default:
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function toLit(val) {
|
|
33
|
-
switch (val.k) {
|
|
34
|
-
case INT:
|
|
35
|
-
return { kind: "BasicLit", litKind: INT, value: val.v.toString() };
|
|
36
|
-
case FLOAT:
|
|
37
|
-
return {
|
|
38
|
-
kind: "BasicLit",
|
|
39
|
-
litKind: FLOAT,
|
|
40
|
-
value: Object.is(val.v, -0) ? "-0" : String(val.v),
|
|
41
|
-
};
|
|
42
|
-
case STRING:
|
|
43
|
-
return { kind: "BasicLit", litKind: STRING, value: val.v };
|
|
44
|
-
default:
|
|
45
|
-
return {
|
|
46
|
-
kind: "BasicLit",
|
|
47
|
-
litKind: BOOL,
|
|
48
|
-
value: val.v ? "true" : "false",
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function asFloat(val) {
|
|
54
|
-
return val.k === INT ? Number(val.v) : val.v;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function foldUnary(op, x) {
|
|
58
|
-
if (op === "-" && x.k === INT) return { k: INT, v: -x.v };
|
|
59
|
-
if (op === "-" && x.k === FLOAT) return { k: FLOAT, v: -x.v };
|
|
60
|
-
if (op === "+" && (x.k === INT || x.k === FLOAT)) return x;
|
|
61
|
-
if (op === "!" && x.k === BOOL) return { k: BOOL, v: !x.v };
|
|
62
|
-
if (op === "^" && x.k === INT) return { k: INT, v: ~x.v };
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function compare(op, a, b) {
|
|
67
|
-
switch (op) {
|
|
68
|
-
case "==":
|
|
69
|
-
return a === b;
|
|
70
|
-
case "!=":
|
|
71
|
-
return a !== b;
|
|
72
|
-
case "<":
|
|
73
|
-
return a < b;
|
|
74
|
-
case "<=":
|
|
75
|
-
return a <= b;
|
|
76
|
-
case ">":
|
|
77
|
-
return a > b;
|
|
78
|
-
case ">=":
|
|
79
|
-
return a >= b;
|
|
80
|
-
default:
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function foldInts(op, a, b) {
|
|
86
|
-
switch (op) {
|
|
87
|
-
case "+":
|
|
88
|
-
return { k: INT, v: a + b };
|
|
89
|
-
case "-":
|
|
90
|
-
return { k: INT, v: a - b };
|
|
91
|
-
case "*":
|
|
92
|
-
return { k: INT, v: a * b };
|
|
93
|
-
case "/":
|
|
94
|
-
if (b === 0n) throw new Error("division by zero");
|
|
95
|
-
return { k: INT, v: a / b };
|
|
96
|
-
case "%":
|
|
97
|
-
if (b === 0n) throw new Error("division by zero");
|
|
98
|
-
return { k: INT, v: a % b };
|
|
99
|
-
case "&":
|
|
100
|
-
return { k: INT, v: a & b };
|
|
101
|
-
case "|":
|
|
102
|
-
return { k: INT, v: a | b };
|
|
103
|
-
case "^":
|
|
104
|
-
return { k: INT, v: a ^ b };
|
|
105
|
-
case "&^":
|
|
106
|
-
return { k: INT, v: a & ~b };
|
|
107
|
-
case "<<":
|
|
108
|
-
if (b < 0n) throw new Error("negative shift count");
|
|
109
|
-
return b > 1024n ? null : { k: INT, v: a << b };
|
|
110
|
-
case ">>":
|
|
111
|
-
if (b < 0n) throw new Error("negative shift count");
|
|
112
|
-
return b > 1024n ? null : { k: INT, v: a >> b };
|
|
113
|
-
default: {
|
|
114
|
-
const r = compare(op, a, b);
|
|
115
|
-
return r === null ? null : { k: BOOL, v: r };
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function foldFloats(op, a, b) {
|
|
121
|
-
let v;
|
|
122
|
-
switch (op) {
|
|
123
|
-
case "+":
|
|
124
|
-
v = a + b;
|
|
125
|
-
break;
|
|
126
|
-
case "-":
|
|
127
|
-
v = a - b;
|
|
128
|
-
break;
|
|
129
|
-
case "*":
|
|
130
|
-
v = a * b;
|
|
131
|
-
break;
|
|
132
|
-
case "/":
|
|
133
|
-
if (b === 0) throw new Error("division by zero");
|
|
134
|
-
v = a / b;
|
|
135
|
-
break;
|
|
136
|
-
default: {
|
|
137
|
-
const r = compare(op, a, b);
|
|
138
|
-
return r === null ? null : { k: BOOL, v: r };
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return Number.isFinite(v) ? { k: FLOAT, v } : null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function foldBinary(op, a, b) {
|
|
145
|
-
if (a.k === BOOL && b.k === BOOL) {
|
|
146
|
-
if (op === "&&") return { k: BOOL, v: a.v && b.v };
|
|
147
|
-
if (op === "||") return { k: BOOL, v: a.v || b.v };
|
|
148
|
-
const r = op === "==" || op === "!=" ? compare(op, a.v, b.v) : null;
|
|
149
|
-
return r === null ? null : { k: BOOL, v: r };
|
|
150
|
-
}
|
|
151
|
-
if (a.k === STRING && b.k === STRING) {
|
|
152
|
-
if (op === "+") return { k: STRING, v: a.v + b.v };
|
|
153
|
-
const r = compare(op, a.v, b.v);
|
|
154
|
-
return r === null ? null : { k: BOOL, v: r };
|
|
155
|
-
}
|
|
156
|
-
if (a.k === INT && b.k === INT) return foldInts(op, a.v, b.v);
|
|
157
|
-
if (
|
|
158
|
-
(a.k === INT || a.k === FLOAT) &&
|
|
159
|
-
(b.k === INT || b.k === FLOAT) &&
|
|
160
|
-
op !== "<<" &&
|
|
161
|
-
op !== ">>"
|
|
162
|
-
) {
|
|
163
|
-
return foldFloats(op, asFloat(a), asFloat(b));
|
|
164
|
-
}
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function foldExpr(expr, resolve) {
|
|
169
|
-
switch (expr?.kind) {
|
|
170
|
-
case "BasicLit":
|
|
171
|
-
return fromLit(expr);
|
|
172
|
-
case "Ident": {
|
|
173
|
-
if (expr.name === "true" || expr.name === "false")
|
|
174
|
-
return { k: BOOL, v: expr.name === "true" };
|
|
175
|
-
const lit = resolve(expr.name);
|
|
176
|
-
return lit ? fromLit(lit) : null;
|
|
177
|
-
}
|
|
178
|
-
case "UnaryExpr": {
|
|
179
|
-
const x = foldExpr(expr.operand, resolve);
|
|
180
|
-
return x ? foldUnary(expr.op, x) : null;
|
|
181
|
-
}
|
|
182
|
-
case "BinaryExpr": {
|
|
183
|
-
const a = foldExpr(expr.left, resolve);
|
|
184
|
-
const b = a ? foldExpr(expr.right, resolve) : null;
|
|
185
|
-
return a && b ? foldBinary(expr.op, a, b) : null;
|
|
186
|
-
}
|
|
187
|
-
case "CallExpr": {
|
|
188
|
-
if (expr.func?.kind !== "Ident" || expr.func.name !== "len") return null;
|
|
189
|
-
if (expr.args?.length !== 1) return null;
|
|
190
|
-
const s = foldExpr(expr.args[0], resolve);
|
|
191
|
-
if (s?.k !== STRING) return null;
|
|
192
|
-
// Gofront strings across JS and WASM runtime use UTF-16 code units (s.length).
|
|
193
|
-
return { k: INT, v: BigInt(s.v.length) };
|
|
194
|
-
}
|
|
195
|
-
default:
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Folds `expr` into a BasicLit, or returns null when it needs the runtime.
|
|
201
|
-
// `resolve(name)` yields the BasicLit of an already-folded constant, if any.
|
|
202
|
-
export function foldConstExpr(expr, resolve) {
|
|
203
|
-
const val = foldExpr(expr, resolve);
|
|
204
|
-
return val ? toLit(val) : null;
|
|
205
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// src/backend/wasm/emit-stdlib.js
|
|
2
|
-
// Backwards compatibility re-export.
|
|
3
|
-
// WASM stdlib implementations have moved to src/backend/wasm/stdlib/.
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
BINARY_MATH_IMPORTS,
|
|
7
|
-
BytesEmitter,
|
|
8
|
-
IoEmitter,
|
|
9
|
-
PurePackagesEmitter,
|
|
10
|
-
StdlibCoreEmitter,
|
|
11
|
-
StdlibCoreEmitter as StdlibEmitter,
|
|
12
|
-
TimeEmitter,
|
|
13
|
-
} from "./stdlib/index.js";
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|